mannydmorales / 101domain-api
PHP SDK for the 101domain Client API v1
v1.0.0
2026-06-07 13:56 UTC
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.0
- guzzlehttp/promises: ^2.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpunit/phpunit: ^10.0
README
A PHP 8.1+ SDK for the 101domain Client API v1.
Requirements
- PHP 8.1 or higher
- Composer
Installation
composer require mannydmorales/101domain-api
Quick Start
use mannydmorales\the101domain\api\Client; $client = new Client('your-bearer-token'); // Check account balance $balance = $client->account()->balance(); echo "Credit: {$balance->creditBalance} {$balance->currency}"; // List your domains $page = $client->domains()->list(page: 1, perPage: 25); foreach ($page->items as $domain) { echo "{$domain->domainName} — {$domain->status}\n"; } // Check domain availability $result = $client->domains()->search('my-new-domain.com'); if ($result->available) { echo "Available! Register for {$result->firstPrice()->register} {$result->firstPrice()->currency}"; }
Authentication
All API requests require a Bearer token issued by 101domain. Pass it to the constructor:
$client = new Client('your-bearer-token');
Different endpoints require different scopes:
| Scope | Used by |
|---|---|
account_read |
account()->balance() |
domains_read |
domains()->list(), get() |
domains_write |
domains()->addForwarding(), … |
dns_read |
dns()->nameservers(), records() |
Resources
Account
$balance = $client->account()->balance(); // $balance->creditBalance (string) // $balance->amountDue (string) // $balance->currency (string)
Domains
// List with optional filters $page = $client->domains()->list( page: 1, perPage: 50, search: 'example', status: ['ACTIVE', 'EXPIRED'], expiresFrom: '2026-01-01', expiresTo: '2027-01-01', ); echo $page->total; // total number of matching domains echo $page->totalPages; echo $page->hasMorePages() ? 'more' : 'done'; // Single domain $domain = $client->domains()->get('example.com'); $domain->isActive(); // bool $domain->isExpired(); // bool $domain->isTransferring(); // bool // Domain search / availability $avail = $client->domains()->search('example.com', pricingTerms: '1,2,5'); $avail->available; // bool $avail->firstPrice()->register; // cheapest available term register price // Bulk search (up to 50 domains) ['results' => $results, 'invalid' => $invalid] = $client->domains()->bulkSearch( ['example.com', 'another.net'], pricingTerm: 1 );
Web Forwarding
// Get current config $fwd = $client->domains()->getForwarding('example.com'); // Add forwarding (type: "301" or "cloak") $fwd = $client->domains()->addForwarding('example.com', 'https://target.com', '301'); // Update $fwd = $client->domains()->updateForwarding('example.com', destination: 'https://new-target.com'); // Remove $client->domains()->removeForwarding('example.com');
DNS
// Nameservers for a domain $ns = $client->dns()->nameservers('example.com'); // ['NS1.101DOMAIN.COM', 'NS2.101DOMAIN.COM', ...] // All DNS records (domain must use 101domain nameservers) $records = $client->dns()->records('example.com'); // Filter by type and/or host $aRecords = $client->dns()->records('example.com', type: 'A'); $wwwRecords = $client->dns()->records('example.com', type: 'A', name: 'www'); foreach ($records as $r) { echo "{$r->name} {$r->type} {$r->value} (TTL: {$r->ttl})\n"; }
TLDs
// Single TLD $tld = $client->tlds()->get('.com', pricingTerms: 'all'); $tld->tldName; // ".COM" $tld->type; // "gTLD" $tld->hasRequirements; // bool $tld->availableTerms; // [1, 2, 3, 4, 5, ...] $price = $tld->priceForTerm(1); echo "{$price->register} {$price->currency}"; // Bulk lookup (up to 50 TLDs) ['results' => $tlds, 'invalid' => $invalid] = $client->tlds()->bulkLookup( ['.com', '.net', '.ai'], pricingTerm: 1 );
Products
$product = $client->products()->get(101); // $product->productId (int) // $product->productName (string) // $product->pricing (ProductPrice[]) $price = $product->priceForTerm(12); // 12 months echo "{$price->new} / {$price->renew} {$price->currency}";
Error Handling
All exceptions extend mannydmorales\the101domain\api\Exceptions\ApiException.
use mannydmorales\the101domain\api\Exceptions\ApiException; use mannydmorales\the101domain\api\Exceptions\AuthenticationException; use mannydmorales\the101domain\api\Exceptions\ForbiddenException; use mannydmorales\the101domain\api\Exceptions\NotFoundException; use mannydmorales\the101domain\api\Exceptions\RateLimitException; use mannydmorales\the101domain\api\Exceptions\ValidationException; try { $domain = $client->domains()->get('example.com'); } catch (AuthenticationException $e) { // 401 — token is invalid or expired } catch (ForbiddenException $e) { // 403 — token lacks the required scope } catch (NotFoundException $e) { // 404 — domain not found in your account } catch (RateLimitException $e) { // 429 — slow down! } catch (ValidationException $e) { // 422 — check $e->getErrors() for field-level messages foreach ($e->getErrors() ?? [] as $field => $messages) { echo "{$field}: " . implode(', ', $messages) . "\n"; } } catch (ApiException $e) { // Everything else echo $e->getStatusCode() . ' ' . $e->getApiCode() . ': ' . $e->getMessage(); }
Custom Guzzle Options
Pass any Guzzle request options as a second argument:
$client = new Client('your-token', [ 'timeout' => 60, 'proxy' => 'tcp://localhost:8125', 'verify' => false, // disable SSL verification (dev only) ]);
Running Tests
composer install ./vendor/bin/phpunit
Contributing
Contributions are welcome! Please fork the repository and create a pull request with your changes.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Contact
For any questions or suggestions, please contact mannydmorales@gmail.com.