PHPackages                             uaregistry/sdk - 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. uaregistry/sdk

ActiveLibrary[API Development](/categories/api)

uaregistry/sdk
==============

Standalone PHP client for the UARegistry EPP service — RFC 5730-5734 over TLS (port 700). No framework, no project code.

v0.1.0(3w ago)01MITPHPPHP &gt;=7.4

Since Jul 4Pushed 3w agoCompare

[ Source](https://github.com/uaregistry/php-sdk)[ Packagist](https://packagist.org/packages/uaregistry/sdk)[ Docs](https://github.com/uaregistry/php-sdk)[ RSS](/packages/uaregistry-sdk/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

UARegistry EPP SDK (PHP)
========================

[](#uaregistry-epp-sdk-php)

A small, dependency-free PHP client for the **UARegistry** EPP service — standard **RFC 5730–5734** EPP over **TLS on port 700**. It speaks the wire protocol directly (no framework, no server-side code), so you can drop it into any PHP 7.4+ project (works through 8.x).

- TLS transport with correct RFC 5734 framing (4-byte length prefix).
- Session: `hello` / `login` / `logout`, with the login services taken from the server greeting automatically (never rejected for an unsupported service).
- Full object commands: **domain**, **contact**, **host** (check / info / create / update / delete / transfer / renew), plus **poll** and **balance**.
- Extensions: **secDNS** (RFC 5910), **RGP restore** (RFC 3915), and the UARegistry native **.ua trademark licence**.
- Clean `Response` objects (result code, message, availability map, value getters) and typed exceptions.

Install
-------

[](#install)

```
composer require uaregistry/sdk
```

No Composer? Clone the repo and `require __DIR__ . '/sdk/autoload.php';` — it registers a minimal PSR-4 autoloader for `UARegistry\Sdk\`.

Requires PHP ≥ 7.4 with the `dom`, `libxml` and `openssl` extensions (and `psr/log` for optional logging — pulled in by Composer).

Quick start
-----------

[](#quick-start)

```
use UARegistry\Sdk\Client;
use UARegistry\Sdk\Config;
use UARegistry\Sdk\Exception\EppException;

$client = new Client(Config::fromArray([
    'host'     => 'uaregistry.com',
    'clid'     => 'UAR0001',
    'password' => 'your-secret',
    'port'     => 700,                       // default; override only if the endpoint moves
    // 'caFile' => '/path/to/ca.cert.pem',   // for a private-CA / self-signed endpoint
    // 'clientCert' / 'clientKey' / 'clientKeyPassphrase' — only if mutual TLS is required
]));

try {
    $client->connect();   // TLS + read
    $client->login();

    $avail = $client->domain()->check(['example.com.ua'])->availability();
    // => ['example.com.ua' => true]

    $info = $client->domain()->info('example.com.ua');
    echo $info->value('exDate');

    $client->logout();
} catch (EppException $e) {
    echo 'EPP error: ' . $e->getMessage();
} finally {
    $client->disconnect();
}
```

TLS notes
---------

[](#tls-notes)

ScenarioConfigPublic, browser-trusted certdefaults (`verifyPeer: true`, `verifyPeerName: true`)Private-CA / self-signed endpointset `caFile` to the CA `.pem`Hostname mismatch (dev)`verifyPeerName: false`Mutual-TLS endpoint (client cert required)`clientCert` + `clientKey` (+ `clientKeyPassphrase` if the key is encrypted)The public endpoint on `uaregistry.com:700` is strict RFC EPP and needs **no client certificate** — auth is clID + password (over TLS) with an IP allowlist. Your own certificate/key are only needed if your endpoint requires mutual TLS. Every TLS field is optional and independent; the port defaults to 700 but is fully configurable.

Commands
--------

[](#commands)

```
// Session
$client->connect(); $client->login(); $client->logout(); $client->disconnect();
$client->login('new-password');                // rotate the EPP password during login
$client->hello();                              // re-read the greeting / keep-alive

// Domain
$client->domain()->check(['a.com.ua', 'b.com.ua']);
$client->domain()->info('a.com.ua', 'pw');
$client->domain()->create('a.com.ua', [
    'years'       => 1,
    'registrant'  => 'C1',
    'contacts'    => ['admin' => 'C1', 'tech' => 'C2'],
    'nameservers' => ['ns1.x.ua', 'ns2.x.ua'],
    'authInfo'    => 'pw',
    'license'     => 'TM-123',                 // second-level .ua only
    'secDNS'      => ['dsData' => [[
        'keyTag' => 12345, 'alg' => 8, 'digestType' => 2, 'digest' => 'ABCD...'
    ]]],
]);
$client->domain()->update('a.com.ua', [
    'add' => ['ns' => ['ns3.x.ua'], 'statuses' => ['clientHold']],
    'rem' => ['statuses' => ['clientHold']],
    'chg' => ['registrant' => 'C9', 'authInfo' => 'newpw'],
    // DNSSEC (RFC 5910) on an existing domain:
    // 'secDNS' => ['add' => ['dsData' => [[...]]], 'remAll' => true, 'maxSigLife' => 1209600],
]);
$client->domain()->renew('a.com.ua', '2027-01-15', 1);
$client->domain()->restore('a.com.ua');        // RGP restore (op="request")
$client->domain()->delete('a.com.ua');
$client->domain()->transfer('request', 'a.com.ua', 'pw', 1);

// Contact
$client->contact()->check(['c1']);
$client->contact()->info('c1', 'pw');
$client->contact()->create('c1', ['name' => 'ACME', 'city' => 'Kyiv', 'cc' => 'UA',
    'email' => 'a@b.ua', 'authInfo' => 'pw',
    // 'postalInfos' => [['type'=>'int', ...], ['type'=>'loc', ...]],   // int + localized
    // 'disclose'    => ['flag'=>false, 'addr'=>['int'], 'voice'=>true], // RFC 5733 privacy
]);
$client->contact()->update('c1', ['chg' => ['email' => 'new@b.ua',
    // 'postalInfo' => ['name'=>'New Name', 'city'=>'Lviv', 'cc'=>'UA'], // change the address
    // 'disclose'   => ['flag'=>true],
]]);
$client->contact()->delete('c1');
$client->contact()->transfer('request', 'c1', 'pw');

// Host
$client->host()->check(['ns1.x.ua']);
$client->host()->info('ns1.x.ua');
$client->host()->create('ns1.x.ua', ['203.0.113.10', '2001:db8::1']);  // v4/v6 auto-detected
$client->host()->update('ns1.x.ua', ['addAddresses' => ['203.0.113.11']]);
$client->host()->delete('ns1.x.ua');

// Poll & balance
$msg = $client->poll()->request();             // 1301 with a message, 1300 when empty
if ($msg->messageId() !== null) {              // messageCount() = how many remain
    // ... process $msg ...
    $client->poll()->ack($msg->messageId());
}
$b = $client->balance()->balance();            // ['creditLimit'=>…, 'balance'=>…, 'availableCredit'=>…]
```

Responses
---------

[](#responses)

Every command returns a `Response`:

```
$r->code();           // int EPP result code (1000, 1001, 2303, ...)
$r->isSuccess();      // true for 1xxx
$r->isPending();      // true for 1001 (registry will resolve via a poll message)
$r->message();        // human-readable
$r->messageLang();    // its language: "en" | "uk" | "ua" | "ru"
$r->availability();   // array for *:check
$r->statuses();       // ['ok'] or ['clientHold', ...] — from the status `s` attribute
$r->value('exDate');  // first element with that local name
$r->values('ns');     // all elements with that local name
$r->balance();        // ['creditLimit'=>…,'balance'=>…,'availableCredit'=>…] or null (balance:info)
$r->prices();         // domain:info hint: ['renewal'=>['value'=>…,'currency'=>'UAH'], ...]
$r->license();        // domain:info: the .ua trademark/licence number, or null
$r->rgpStatus();      // domain:info: ['redemptionPeriod'] etc.
$r->transferStatus(); // transfer/poll trnData: "pending" | "serverApproved" | ... or null
$r->dsRecords();      // domain:info DNSSEC: [['keyTag'=>…,'alg'=>…,'digestType'=>…,'digest'=>…], ...]
$r->keyRecords();     // domain:info DNSSEC keyData: [['flags'=>…,'protocol'=>…,'alg'=>…,'pubKey'=>…], ...]
$r->isSigned();       // bool: does the domain carry any DNSSEC data
$r->messageId();      // poll: id to pass to pollAck();  $r->messageCount() = queue size
$r->errorReasons();   // extra  text on a failed command
$r->svTRID();         // server transaction id
$r->raw();            // the raw XML
$r->xpath();          // DOMXPath for anything bespoke (prefixes e/domain/contact/host/secDNS/rgp/uareg/balance)
```

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

[](#error-handling)

By default any EPP error code (≥ 2000) throws `CommandException` (carrying `->eppCode`and `->response`). Login failures throw `AuthenticationException`; transport problems throw `ConnectionException`. All extend `EppException`.

```
use UARegistry\Sdk\Exception\CommandException;
use UARegistry\Sdk\ResultCode;

try {
    $client->domain()->create('taken.com.ua', [...]);
} catch (CommandException $e) {
    if ($e->eppCode === ResultCode::OBJECT_EXISTS) { /* 2302 */ }
    // $e->response->errorReasons() may carry extra detail
}
```

`ResultCode` has named constants for every code (`SUCCESS`, `SUCCESS_PENDING`, `OBJECT_EXISTS`, `OBJECT_DOES_NOT_EXIST`, `AUTHENTICATION_ERROR`, `BILLING_FAILURE`, …).

Prefer to branch on codes yourself? Turn throwing off:

```
$client->throwOnFailure(false);
$resp = $client->domain()->info('maybe.com.ua');
if ($resp->code() === ResultCode::OBJECT_DOES_NOT_EXIST) { /* not found */ }
```

Logging (PSR-3)
---------------

[](#logging-psr-3)

Pass any [PSR-3](https://www.php-fig.org/psr/psr-3/) logger (Monolog, Laravel, etc.). Every request/response frame is logged at `debug` and each result at `info` / `warning`, with **passwords and authInfo masked** so secrets never reach your logs.

```
$log = new Monolog\Logger('epp');
$log->pushHandler(new Monolog\Handler\StreamHandler('php://stderr', Monolog\Level::Debug));

$client = new Client($config, null, $log);
// or later: $client->setLogger($log);
```

Custom frames
-------------

[](#custom-frames)

Anything the high-level API doesn't cover can be built with `Frame` and sent raw:

```
use UARegistry\Sdk\Frame;
use UARegistry\Sdk\Namespaces;

$frame = Frame::command('my-trid-1');
$check = $frame->ns($frame->verb('check'), Namespaces::DOMAIN, 'domain:check');
$frame->ns($check, Namespaces::DOMAIN, 'domain:name', 'x.com.ua');
$resp = $client->request($frame);   // or $client->request($rawXmlString);
```

Testing
-------

[](#testing)

A no-dependency offline self-test (frame building + response parsing, no server):

```
php tests/offline_test.php      # or: composer test
```

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance94

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity23

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

26d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2345abc1b2414a9ee44b71dd2059199152313a077738b308304556c157592fe2?d=identicon)[uaregistry](/maintainers/uaregistry)

---

Top Contributors

[![uaregistry](https://avatars.githubusercontent.com/u/293228516?v=4)](https://github.com/uaregistry "uaregistry (1 commits)")

---

Tags

clientsdkregistryuadomainseppuaregistryrfc5730rfc5731

### Embed Badge

![Health badge](/badges/uaregistry-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/uaregistry-sdk/health.svg)](https://phpackages.com/packages/uaregistry-sdk)
```

###  Alternatives

[algolia/algoliasearch-client-php

API powering the features of Algolia.

69635.1M165](/packages/algolia-algoliasearch-client-php)[temporal/sdk

Temporal SDK

4072.9M25](/packages/temporal-sdk)[struzik-vladislav/epp-client

PHP library for communicating with EPP(Extensible Provisioning Protocol) servers

1915.5k12](/packages/struzik-vladislav-epp-client)[africc/php-epp2

A High Level EPP (Extensible Provisioning Protocol) TCP/SSL Client for PHP

5489.7k3](/packages/africc-php-epp2)[webit/w-firma-api

wFirma.pl API

1822.1k](/packages/webit-w-firma-api)

PHPackages © 2026

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