mannydmorales/101domain-api

PHP SDK for the 101domain Client API v1

Maintainers

Package info

github.com/mannydmorales/101domain-api-php

pkg:composer/mannydmorales/101domain-api

Statistics

Installs: 20

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-06-07 13:56 UTC

This package is auto-updated.

Last update: 2026-06-07 14:09:13 UTC


README

A PHP 8.1+ SDK for the 101domain Client API v1.

Requirements

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.