domainreseller / php-dna
DomainNameAPI PHP Library for Domain Management
Requires
- php: >=7.4
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^9.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- V4.0.3
- V4.0.2
- V4.0.1
- V4.0.0
- V3.0.17
- V3.0.16
- V3.0.15
- V3.0.14
- V3.0.13
- V3.0.12
- V3.0.11
- V3.0.10
- V3.0.9
- V3.0.8
- V3.0.7
- V3.0.6
- V3.0.5
- V3.0.4
- V3.0.3
- V3.0.2
- V3.0.1
- V3.0.0
- V2.1.22
- V2.1.21
- V2.1.20
- V2.1.19
- V2.1.18
- V2.1.17
- V2.1.15
- v2.1.13
- v2.1.12
- v2.1.11
- v2.1.10
- v2.1.9
- v2.1.8
- v2.1.7
- V2.1.6
- v2.1.5
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.0.24
- V2.0.24-b
- V2.0.20
- V2.0.12
- V2.0.10
- V2.0.9
- V2.0.7
This package is auto-updated.
Last update: 2026-10-22 10:24:28 UTC
README
TR📦 Download — always use Releases!
⬇️ Get the latest tested version here: https://github.com/domainreseller/php-dna/releases/latest
⚠️ Do not use the green Code → Download ZIP button — that downloads the raw development branch. Release packages are versioned, tested and production-ready.
Installation and Integration Guide
Minimum Requirements
- PHP7.4 or higher (Recommended 8.1)
- PHP JSON and cURL extensions must be active.
🔑 API Credentials — Reseller ID & API Key
The library talks to the DomainNameAPI REST API and needs exactly two credentials, passed to the constructor:
| Parameter | Value |
|---|---|
| First | Reseller ID — UUID like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
| Second | API Key |
💡 Find your Reseller ID and API Key in your DomainNameAPI panel under API Settings. ⚠️ These are API credentials — your panel login details will not work here.
$resellerId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'; $apiKey = 'your-api-key'; // Live environment $dna = new \DomainNameApi\DomainNameAPI_PHPLibrary($resellerId, $apiKey); // Test (OTE) environment $dna = new \DomainNameApi\DomainNameAPI_PHPLibrary($resellerId, $apiKey, true);
Error reporting (telemetry)
When an API call fails, the library sends an error report to DomainNameAPI's own error tracker (Sentry, at sentry.atakdomain.com). A small random share of successful calls (4%, plus every call slower than 1 second) is sent as a performance record. This helps DomainNameAPI find and fix problems. Error reporting is on by default.
What is sent:
- error code and message
- called endpoint path and HTTP method
- call duration
- module name, library version and PHP version
- reseller ID and domain name
- the server's public IP address (looked up via
api.ipify.org) - the address (URL) of the panel page that triggered the call
- the hosting account name on the server
- the API request and response, including the domain's contact details; only credentials are masked — EPP/auth codes, API keys, passwords and tokens are replaced with
***
What is never sent: EPP/auth codes, API keys, passwords or tokens in readable form; function call arguments in stack traces.
Why and how long: the data is used only for usage measurement and early diagnosis of problems, and is kept for 30 days on DomainNameAPI's own Sentry server, after which it is deleted automatically.
How to turn it off: call setErrorReportingEnabled(false) after constructing the client:
$dna = new \DomainNameApi\DomainNameAPI_PHPLibrary($resellerId, $apiKey); $dna->setErrorReportingEnabled(false);
🔒 Security: TLS certificate verification is on. On a host with an outdated CA bundle it can be switched off with
$dna->setSslVerification(false);— this is not recommended; updating the CA bundle is the better fix.
A) Manual Usage
Download the files and examine the examples in the examples folder.
require_once __DIR__.'/DomainNameApi/DomainNameAPI_PHPLibrary.php'; $dna = new \DomainNameApi\DomainNameAPI_PHPLibrary($resellerId, $apiKey);
B) Composer Integration
composer require domainreseller/php-dna
require_once __DIR__.'/vendor/autoload.php'; $dna = new \DomainNameApi\DomainNameAPI_PHPLibrary($resellerId, $apiKey);
Usage
Domain Registration
Note: Additional parameters are required for .tr domains. The Additional parameter is used for domain names that require extra information like .tr.
$contact = [ "FirstName" => 'John', "LastName" => 'Doe', "Company" => 'Example Corp', "EMail" => 'john.doe@example.com', "AddressLine1" => '123 Lorem Street', "AddressLine2" => 'Suite 456', "AddressLine3" => '', "City" => 'Springfield', "Country" => 'US', "Fax" => '1234567890', "FaxCountryCode" => '1', "Phone" => '9876543210', "PhoneCountryCode" => 1, "Type" => 'Contact', "ZipCode" => '12345', "State" => 'IL' ]; $dna->RegisterWithContactInfo( 'example.com', 1, [ 'Administrative' => $contact, 'Billing' => $contact, 'Technical' => $contact, 'Registrant' => $contact ], ["ns1.example.com", "ns2.example.com"], true, false, // Additional attributes are only required for .tr domains [ 'TRABISDOMAINCATEGORY' => 1, 'TRABISCITIZIENID' => '12345678901', 'TRABISNAMESURNAME' => 'John Doe', 'TRABISCOUNTRYID' => '840', 'TRABISCITYID' => '17' ]);
Sample Output for Domain Registration
Array ( [result] => OK [data] => Array ( [ID] => 123456 [Status] => clientTransferProhibited [DomainName] => example.com [AuthCode] => Xy9#mK2$pL5@vN8 [LockStatus] => true [PrivacyProtectionStatus] => false [IsChildNameServer] => false [Contacts] => Array ( [Billing] => Array ( [ID] => 987654 ) [Technical] => Array ( [ID] => 987654 ) [Administrative] => Array ( [ID] => 987654 ) [Registrant] => Array ( [ID] => 987654 ) ) [Dates] => Array ( [Start] => 2024-03-15T10:00:00 [Expiration] => 2025-03-15T10:00:00 [RemainingDays] => 365 ) [NameServers] => Array ( [0] => ns1.example.com [1] => ns2.example.com ) [Additional] => Array ( ) [ChildNameServers] => Array ( ) ) )
Domain Renewal
$dna->Renew('example.com', 1);
Sample Output for Domain Renewal
Array ( [result] => OK [data] => Array ( [ExpirationDate] => 2025-03-15T10:00:00 ) )
Domain Transfer
$dna->Transfer('example.com', 'Xy9#mK2$', 3);
Sample Output for Domain Transfer
Array ( [result] => OK )
Domain List
$dna->GetList(['OrderColumn'=>'Id', 'OrderDirection'=>'ASC', 'PageNumber'=>0,'PageSize'=>1000]);
Sample Output for Domain List
Array ( [data] => Array ( [Domains] => Array ( [0] => Array ( [ID] => 564346 [Status] => Active [DomainName] => example.com [AuthCode] => DHQ!K52 [LockStatus] => false [PrivacyProtectionStatus] => false [IsChildNameServer] => false [Contacts] => Array ( [Billing] => Array ( [ID] => 11854114 ) [Technical] => Array ( [ID] => 11854114 ) [Administrative] => Array ( [ID] => 11854114 ) [Registrant] => Array ( [ID] => 11854114 ) ) [Dates] => Array ( [Start] => 2024-03-15T10:00:00 [Expiration] => 2025-03-15T10:00:00 [RemainingDays] => 365 ) [NameServers] => Array ( [0] => ns1.example.com [1] => ns2.example.com ) [Additional] => Array ( ) [ChildNameServers] => Array ( [0] => Array ( [ns] => ns1.example.com [ip] => 1.2.3.4 ) ) ) ) ) [result] => OK [TotalCount] => 1 )
TLD List
$dna->GetTldList(100);
Sample Output for TLD List
Array ( [data] => Array ( [0] => Array ( [id] => 1 [status] => Active [maxchar] => 63 [maxperiod] => 10 [minchar] => 1 [minperiod] => 1 [tld] => com [pricing] => Array ( [registration] => Array ( [1] => 10.8100 ) [renew] => Array ( [1] => 11.0100 ) [transfer] => Array ( [1] => 10.6100 ) [restore] => Array ( [1] => 99.9000 ) ) [currencies] => Array ( [registration] => USD [renew] => USD [transfer] => USD [restore] => USD ) ) ) [result] => OK )
Domain Availability Check
$dna->CheckAvailability(['hello','world123x0'], ['com','net'], 1, 'create');
Sample Output for Domain Availability Check
Array ( [0] => Array ( [TLD] => com [DomainName] => hello [Status] => notavailable [Command] => create [Period] => 1 [IsFee] => [Price] => 10.8100 [Currency] => USD [Reason] => Domain exists ) [1] => Array ( [TLD] => com [DomainName] => world123x0 [Status] => available [Command] => create [Period] => 1 [IsFee] => [Price] => 10.8100 [Currency] => USD [Reason] => ) )
Domain Details
$dna->GetDetails('example.com');
Sample Output for Domain Details
Array ( [data] => Array ( [ID] => 564346 [Status] => Active [DomainName] => example.com [AuthCode] => DHQ!K52 [LockStatus] => true [PrivacyProtectionStatus] => false [IsChildNameServer] => false [Contacts] => Array ( [Billing] => Array ( [ID] => 11854114 ) [Technical] => Array ( [ID] => 11854114 ) [Administrative] => Array ( [ID] => 11854114 ) [Registrant] => Array ( [ID] => 11854114 ) ) [Dates] => Array ( [Start] => 2025-05-26T16:08:37 [Expiration] => 2027-05-26T16:08:37 [RemainingDays] => 449 ) [NameServers] => Array ( [0] => ns1.example.com [1] => ns2.example.com ) [Additional] => Array ( ) [ChildNameServers] => Array ( [0] => Array ( [ns] => ns1.example.com [ip] => 1.2.3.4 ) ) ) [result] => OK )
Nameserver Modification
$dna->ModifyNameServer('example.com', ['ns1.example.com', 'ns2.example.com']);
Sample Output for Nameserver Modification
Array ( [data] => Array ( [NameServers] => Array ( [0] => ns1.example.com [1] => ns2.example.com ) ) [result] => OK )
Enable Domain Lock
$dna->EnableTheftProtectionLock('example.com');
Sample Output for Enable Domain Lock
Array ( [data] => Array ( [LockStatus] => true ) [result] => OK )
Disable Domain Lock
$dna->DisableTheftProtectionLock('example.com');
Sample Output for Disable Domain Lock
Array ( [data] => Array ( [LockStatus] => false ) [result] => OK )
Add Child Nameserver
$dna->AddChildNameServer('example.com', 'ns1.example.com', '1.2.3.4');
Sample Output for Add Child Nameserver
Array ( [data] => Array ( [NameServer] => ns1.example.com [IPAdresses] => Array ( [0] => 1.2.3.4 ) ) [result] => OK )
Delete Child Nameserver
$dna->DeleteChildNameServer('example.com', 'ns1.example.com');
Sample Output for Delete Child Nameserver
Array ( [data] => Array ( [NameServer] => ns1.example.com ) [result] => OK )
Update Child Nameserver
$dna->ModifyChildNameServer('example.com', 'ns1.example.com', '1.2.3.4');
Sample Output for Update Child Nameserver
Array ( [data] => Array ( [NameServer] => ns1.example.com [IPAdresses] => Array ( [0] => 1.2.3.4 ) ) [result] => OK )
Modify Domain Privacy
$dna->ModifyPrivacyProtectionStatus('example.com', true, 'Owner request');
Sample Output for Modify Domain Privacy
Array ( [data] => Array ( [PrivacyProtectionStatus] => true ) [result] => OK )
Save Domain Contacts
$contact = [ "FirstName" => 'John', "LastName" => 'Doe', "Company" => 'Example Corp', "EMail" => 'john@example.com', "AddressLine1" => '123 Main Street', "AddressLine2" => '', "AddressLine3" => '', "City" => 'Springfield', "Country" => 'US', "Fax" => '5559876543', "FaxCountryCode" => '1', "Phone" => '5551234567', "PhoneCountryCode" => 1, "Type" => 'Contact', "ZipCode" => '62701', "State" => 'IL' ]; $dna->SaveContacts('example.com', [ 'Administrative' => $contact, 'Billing' => $contact, 'Technical' => $contact, 'Registrant' => $contact ]);
Sample Output for Save Domain Contacts
Array ( [result] => OK )
Get Reseller Details
$dna->GetResellerDetails();
Sample Output for Get Reseller Details
Array ( [result] => OK [id] => 12345 [active] => 1 [name] => Example Reseller [balance] => 500.0000 [currency] => USD [symbol] => $ [balances] => Array ( [0] => Array ( [balance] => 500.0000 [currency] => USD [symbol] => $ ) [1] => Array ( [balance] => 1500.0000 [currency] => TL [symbol] => TL ) ) )
Testing
The library includes PHPUnit tests that run against the DomainNameAPI REST API.
Setup
- Create a
.env.testfile in the project root:
DNA_RESELLER_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx DNA_API_KEY=your-api-key DNA_DOMAIN=yourdomain.com DNA_DOMAIN_CONTACTS=yourdomain-with-contacts.com
- Run all tests:
env $(cat .env.test | xargs) vendor/bin/phpunit --testdox
- Run specific test suites:
# Read operations only env $(cat .env.test | xargs) vendor/bin/phpunit --testdox --filter RestRead # Write operations only env $(cat .env.test | xargs) vendor/bin/phpunit --testdox --filter RestWrite
Test Structure
| Test File | Description |
|---|---|
tests/RestReadTest.php |
Read operations (GetDetails, GetList, CheckAvailability, etc.) |
tests/RestWriteTest.php |
Write operations (ModifyNameServer, Lock, ChildNS, etc.) |
tests/RestEdgeCaseTest.php |
Edge cases (empty/invalid input handling) |
Return and Error Codes with Descriptions
| Code | Description | Detail |
|---|---|---|
| 1000 | Command completed successfully | Operation successful. |
| 1001 | Command completed successfully; action pending | Operation successful. However, the operation is currently queued for completion. |
| 2003 | Required parameter missing | Parameter missing error. For example, no phone entry in contact information. |
| 2105 | Object is not eligible for renewal | Domain status is not suitable for renewal, locked for update operations. Status should not be "clientupdateprohibited". May be due to other status conditions. |
| 2200 | Authentication error | Authorization error, security code is incorrect or domain is registered with another registrar. |
| 2302 | Object exists | Domain name or nameserver information already exists in database. Cannot be registered. |
| 2303 | Object does not exist | Domain name or nameserver information does not exist in database. New registration required. |
| 2304 | Object status prohibits operation | Domain status is not suitable for updates, locked for update operations. Status should not be "clientupdateprohibited". May be due to other status conditions. |
| CODE | DETAIL |
|---|---|
| 101 | System Error Detailed For ({0})! |
| 102 | Multiple Errors Detailed For ({0})! |
| 103 | Unknown Errors Detailed For ({0})! |
| 200 | API command not found ({0})! |
| 210 | API service not found ({0})! |
| 211 | API service provider not set! |
| 300 | Reseller not found! |
| 301 | Your current IP address is not authorized to access. Please make sure you are connecting from an authorized IP address and try again |
| 310 | TLD is not supported! |
| 320 | API not found! |
| 321 | Currency is not supported! |
| 330 | Required parameter(s) not set ({0}). |
| – | Make sure you send all contact objects full |
| 340 | Price definition not found ({0}[{1}]-{2}{3}). |
| 350 | Insufficient reseller balance. (Reseller Id : {0} - Current Balance : {1} {2}). |
| 350 | Accounting currency does not match or the balance is not sufficient. |
| 360 | Invalid API request for field ({0}). |
| 360 | API quota exceeded! |
| 361 | Throttled error! |
| 362 | Premium domain is not available to register right now. |
| 363 | Operation cancelled because domain in auto-renewal period |
| 364 | This domain is currently unavailable for transaction due to a problem with the registry |
| CODE | DETAIL |
|---|---|
| 400 | Invalid contact ({0}). |
| 401 | Contact info can not sync. |
| 402 | No access to contact information from registry. |
| 403 | THE SYSTEM HAS MISSING INFORMATION. ENTER YOUR DEFAULT INFORMATION OR CONTACT SUPPORT TEAM. |
| 404 | DOMAIN CONTACT CANNOT UPDATE. PERMISSION FROM THE REGISTRY. |
| 410 | Contact not found. |
| 410 | Contact not found ({0}). |
| 420 | Invalid Api command for contact {0}. |
| 430 | Contact api not found. |
| 440 | Contact is not synced. |
| 450 | Too many domain contacts! |
| 451 | Failed to proceed with contact update. |
| CODE | DETAIL |
|---|---|
| 500 | Invalid domain id. |
| 500 | Invalid domain id ({0}). |
| 501 | Domain could not synchronized({0}) |
| 502 | Internal transfer failed |
| 503 | Domain registration is not available. |
| 504 | Domain information does not match. Before :{0} |
| 505 | Enter the Ip Address. |
| 506 | Domain Transfer Has Been Started But Contact Info Not Read. |
| 507 | Authorization error. |
| 510 | Domain not found. |
| 511 | Expired domains cannot be found. |
| 512 | Domain is not renewable. |
| 513 | Domain is not in updateable status. It must be active for to be updated |
| 514 | Redemption Period Expected. |
| 520 | Invalid Api command for domain "{0}". |
| 530 | Invalid domain period. Period must be {0} to {1} years. Requested period is {2} years. |
| 540 | Domain cannot be extended beyond {0} years from current date. |
| 550 | Invalid domain name. Domain must be {0} to {1} characters length. Requested domain name is {2} characters. |
| 560 | Invalid name server count. Domain must have {0} to {1} name servers. Requested name server count is {2}. |
| 561 | No name server information found in the incoming request |
| 570 | Idn not supported for tld "{0}". |
| 571 | Period invalid. |
| 572 | Command invalid. |
| 573 | Domain names not found. |
| 574 | TLD names not found. |
| 575 | Domain is not in updateable status. It must be active for name servers to be updated |
| 576 | Domain can be renewed in the last 1 month before the expire date |
| 580 | Transfer not supported for tld "{0}". |
| 581 | Child name server not found |
| 582 | Transfer started by other reseller. |
| 583 | Transfer not initialized. Please contact the support team. |
| 584 | Object status prohibits operation |
| 590 | Auth code is required for this transfer. |
| 591 | Auth code is not valid. |
| 592 | Transfer lock exists on domain. |
| 593 | Domain cannot be transferred, Status Information and Transfer Lock must comply with the required criteria. (Status Information: #ok) |
| 594 | Domain name server address could not resolved ({0}) |
| 595 | Contact information can not be read (whois.registrar.tld) Please make sure that privacy protection status open |
| 596 | Contact information could not verified |
| 597 | Tld Not Found |
| 598 | Unknown error occurred |
| 599 | Domain Forward Not Found |