A PHP 8.1+ SDK for the 101domain Client API v1.
- PHP 8.1 or higher
- Composer
composer require mannydmorales/101domain-apiuse 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}";
}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() |
$balance = $client->account()->balance();
// $balance->creditBalance (string)
// $balance->amountDue (string)
// $balance->currency (string)// 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
);// 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');// 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";
}// 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
);$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}";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();
}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)
]);composer install
./vendor/bin/phpunitContributions are welcome! Please fork the repository and create a pull request with your changes.
This project is licensed under the MIT License. See the LICENSE file for details.
For any questions or suggestions, please contact mannydmorales@gmail.com.