PHPackages                             luchaninov/nicnames-client - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. luchaninov/nicnames-client

ActiveLibrary[API Development](/categories/api)

luchaninov/nicnames-client
==========================

PHP client for the Nicnames domain registrar REST API v2

1.0.3(1mo ago)01↓100%MITPHPPHP &gt;=8.4CI passing

Since May 1Pushed 1mo agoCompare

[ Source](https://github.com/luchaninov/nicnames-client)[ Packagist](https://packagist.org/packages/luchaninov/nicnames-client)[ RSS](/packages/luchaninov-nicnames-client/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (5)Used By (0)

nicnames-client
===============

[](#nicnames-client)

PHP client for the [Nicnames](https://nicnames.com) domain registrar REST API v2. Full API reference: [api.nicnames.com/docs/2/](https://api.nicnames.com/docs/2/).

> **Disclaimer:** This is an unofficial, personal project and is not affiliated with, endorsed by, or maintained by Nicnames. Use at your own risk.

Requirements
------------

[](#requirements)

- PHP 8.4+
- `symfony/http-client`

Installation
------------

[](#installation)

```
composer require luchaninov/nicnames-client
```

API key
-------

[](#api-key)

Generate an API key at [nicnames.com/en/my/settings](https://nicnames.com/en/my/settings). A paid Nicnames membership is required to access the API.

Usage
-----

[](#usage)

```
use Luchaninov\NicnamesClient\HttpTransport;
use Luchaninov\NicnamesClient\NicnamesClient;
use Symfony\Component\HttpClient\HttpClient;

$transport = new HttpTransport(HttpClient::create(), apiKey: 'YOUR-API-KEY');
$client = new NicnamesClient($transport);

$domains = $client->listDomains();
foreach ($domains->list as $order) {
    echo $order->domain?->name . ' — ' . implode(',', $order->status) . PHP_EOL;
}
```

### Automatic retries

[](#automatic-retries)

`HttpTransport` accepts any `Symfony\Contracts\HttpClient\HttpClientInterface`, so transient failures (5xx, network blips) can be handled by wrapping with Symfony's `RetryableHttpClient`:

```
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\RetryableHttpClient;

$http = new RetryableHttpClient(HttpClient::create(), maxRetries: 3);
$transport = new HttpTransport($http, apiKey: 'YOUR-API-KEY');
```

### Domain info &amp; availability

[](#domain-info--availability)

```
$order = $client->infoDomain('example.com');
echo $order->domain?->name;

$check = $client->checkDomain('example.com');
// $check->availableFor: NONE|CREATE|TRANSFER|RENEW|RESTORE|UPDATE
// $check->tier:         REGULAR|PREMIUM|UNKNOWN
// $check->price:        PriceModel[] — one entry per period
```

### Create a domain

[](#create-a-domain)

Operations that the API may complete inline (200/201) **or** schedule as a background job (202) return a `DomainOperationResult` wrapper:

```
use Luchaninov\NicnamesClient\Dto\CreateDomainRequest;
use Luchaninov\NicnamesClient\Dto\OperationModel;
use Luchaninov\NicnamesClient\Dto\PeriodModel;
use Luchaninov\NicnamesClient\Dto\PeriodUnitModel;
use Luchaninov\NicnamesClient\Dto\PriceModel;

$price = new PriceModel(
    amt: 12.34,
    ccy: 840,
    op: OperationModel::CREATE,
    period: new PeriodModel(PeriodUnitModel::YEARS, 1),
);

$result = $client->createDomain('example.com', new CreateDomainRequest(
    price: $price,
    registrant: 'c987654321',
));

if ($result->isAsync()) {
    echo "Scheduled as job {$result->jobId}\n";
} else {
    echo "Created order {$result->order->oid}\n";
}
```

The same wrapper is returned by `transferDomain()`, `renewDomain()`, `restoreDomain()`, `updateDomainNameServers()`, and `updateDomainWhoisPrivacy()`.

### Contacts

[](#contacts)

```
use Luchaninov\NicnamesClient\Dto\CreateContactRequest;

$contact = $client->createContact(new CreateContactRequest(
    firstName: 'John',
    lastName: 'Doe',
    cc: 'us',
    pc: '62704',
    sp: 'IL',
    city: 'Springfield',
    addr: '123 Main Street',
    email: 'john.doe@example.com',
    phone: '+15551234567',
    phonePolicy: true,
));

$contacts = $client->listContacts();
$one = $client->infoContact('c987654321');
```

### Update nameservers / WHOIS privacy

[](#update-nameservers--whois-privacy)

```
use Luchaninov\NicnamesClient\Dto\UpdateNameServersRequest;
use Luchaninov\NicnamesClient\Dto\UpdateWhoisPrivacyRequest;

$client->updateDomainNameServers(
    'example.com',
    new UpdateNameServersRequest(['ns1.example.com', 'ns2.example.com']),
);
$client->updateDomainWhoisPrivacy('example.com', new UpdateWhoisPrivacyRequest(
    registrant: UpdateWhoisPrivacyRequest::ENABLE,
));
```

### Webhooks

[](#webhooks)

The API delivers asynchronous results and events as `application/x-www-form-urlencoded`POSTs containing `object` (JSON), `timestamp`, and `signature` fields. The simplest integration uses `WebhookHandler`, which verifies the HMAC-SHA256 signature, checks that the timestamp is fresh (default 5 min anti-replay window), and decodes the JSON into a typed event in one call:

```
use Luchaninov\NicnamesClient\Dto\WebhookJobResultEvent;
use Luchaninov\NicnamesClient\Webhook\WebhookException;
use Luchaninov\NicnamesClient\Webhook\WebhookHandler;
use Luchaninov\NicnamesClient\Webhook\WebhookVerifier;

$handler = new WebhookHandler(new WebhookVerifier(secret: 'YOUR-WEBHOOK-SECRET'));

try {
    $event = $handler->handle($_POST);
} catch (WebhookException) {
    http_response_code(401);
    exit;
}

if ($event instanceof WebhookJobResultEvent) {
    // $event->jobId, $event->code (e.g. 441000 SUCCESS, 442xxx error codes)
}
```

In a Symfony controller, pass the request payload as an array:

```
use Luchaninov\NicnamesClient\Dto\WebhookJobResultEvent;
use Luchaninov\NicnamesClient\Webhook\WebhookException;
use Luchaninov\NicnamesClient\Webhook\WebhookHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/webhooks/nicnames', methods: ['POST'])]
public function __invoke(Request $request, WebhookHandler $handler): Response
{
    try {
        $event = $handler->handle($request->request->all());
    } catch (WebhookException) {
        return new Response('', Response::HTTP_UNAUTHORIZED);
    }

    if ($event instanceof WebhookJobResultEvent) {
        // $event->jobId, $event->code
    }

    return new Response('', Response::HTTP_NO_CONTENT);
}
```

If you need finer control, `WebhookVerifier::isValid()` and `WebhookEventFactory::fromJson()`are public and composable.

Error handling
--------------

[](#error-handling)

Every API result code maps to a typed exception:

CodeException`442001``RemoteException``442002``ApiException``442003``ForbiddenException``442006``UnknownStatusException``442007``NotFoundException``442008``StatusProhibitedException``442009``InvalidParamPolicyException``442010``InvalidParamValueException``442011``ParamRequiredException``442012``UnauthorizedException`other`NicnamesException`All exceptions carry the API trace id:

```
use Luchaninov\NicnamesClient\Exception\NicnamesException;

try {
    $client->createDomain('bad', $request);
} catch (NicnamesException $e) {
    $e->getCode();   // 442010
    $e->getMessage(); // 'Invalid domain name.'
    $e->traceId;      // 'c4f9d5b3-...'
}
```

HTTP / network failures throw `TransportException`. A 2xx response that doesn't conform to the spec (e.g. an HTTP 202 without a `jobId`) throws `MalformedResponseException`.

Webhook validation failures (missing fields, bad signature, stale timestamp, malformed JSON) throw `Webhook\WebhookException` — a separate hierarchy from `NicnamesException`, since they originate in your inbound traffic, not from the API.

Development
-----------

[](#development)

```
composer install
vendor/bin/phpunit
vendor/bin/phpstan analyze
```

### Manual smoke test

[](#manual-smoke-test)

Copy `.env.local.example` to `.env.local` (gitignored) and fill in your API key. Then run:

```
php examples/test.php
```

### Bulk scripts

[](#bulk-scripts)

All scripts read from `--input `, support `--resume`, and emit TSV to stdout.

```
php examples/check.php    --input domains.txt > availability.tsv
php examples/register.php --input domains.txt --registrant c987654321 --term 1 > registered.tsv
php examples/renew.php    --input domains.txt --term 1 > renewed.tsv
php examples/transfer.php --input transfers.tsv --registrant c987654321 --term 1 > transferred.tsv
php examples/ns.php       --input ns.tsv > ns-results.tsv
php examples/privacy.php  --input domains.txt --on > privacy-on.tsv
php examples/privacy.php  --input domains.txt --off --apply-to-all > privacy-off.tsv

# Resume any script after interruption (skip already-processed entries)
php examples/register.php --input domains.txt --registrant c987654321 --resume last-done.com >> registered.tsv
```

License
-------

[](#license)

MIT

Help Ukraine
------------

[](#help-ukraine)

If you find this project useful, please consider supporting Ukraine: 🇺🇦 [Donate](https://commission.europa.eu/topics/eu-solidarity-ukraine/donate_en)

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance92

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

4

Last Release

39d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/df3e7060fb5777768e7bb133e98b1e7dfcc788f25fe6dc445acf7036da5c0c3e?d=identicon)[luchaninov](/maintainers/luchaninov)

---

Top Contributors

[![luchaninov](https://avatars.githubusercontent.com/u/3829796?v=4)](https://github.com/luchaninov "luchaninov (5 commits)")

---

Tags

api clientdomainsrest-clientdomain registrarnicnames

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/luchaninov-nicnames-client/health.svg)

```
[![Health](https://phpackages.com/badges/luchaninov-nicnames-client/health.svg)](https://phpackages.com/packages/luchaninov-nicnames-client)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.8M710](/packages/sylius-sylius)[temporal/sdk

Temporal SDK

4082.7M22](/packages/temporal-sdk)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M195](/packages/sulu-sulu)[web-auth/webauthn-framework

FIDO2/Webauthn library for PHP and Symfony Bundle.

51090.8k2](/packages/web-auth-webauthn-framework)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.4M506](/packages/shopware-core)[bitrix24/b24phpsdk

An official PHP library for the Bitrix24 REST API

10139.4k5](/packages/bitrix24-b24phpsdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
