https://github.com/rdapapi/rdapapi-php
Official PHP SDK for the RDAP API
https://github.com/rdapapi/rdapapi-php
Last synced: about 2 months ago
JSON representation
Official PHP SDK for the RDAP API
- Host: GitHub
- URL: https://github.com/rdapapi/rdapapi-php
- Owner: rdapapi
- License: mit
- Created: 2026-02-25T19:08:53.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-17T13:05:11.000Z (3 months ago)
- Last Synced: 2026-03-18T02:57:13.036Z (3 months ago)
- Language: PHP
- Size: 40 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# rdapapi-php
Official PHP SDK for the [RDAP API](https://rdapapi.io) — look up domains, IP addresses, ASNs, nameservers, and entities via the RDAP protocol.
[](https://packagist.org/packages/rdapapi/rdapapi-php)
[](https://packagist.org/packages/rdapapi/rdapapi-php)
[](https://github.com/rdapapi/rdapapi-php/actions/workflows/ci.yml)
## Installation
```bash
composer require rdapapi/rdapapi-php
```
Requires PHP 8.2 or later.
## Quick Start
```php
domain('google.com');
echo $domain->registrar->name; // "MarkMonitor Inc."
echo $domain->dates->registered; // "1997-09-15T04:00:00Z"
echo $domain->dates->expires; // "2028-09-14T04:00:00Z"
print_r($domain->nameservers); // ["ns1.google.com", ...]
```
## Usage
### Configuration
```php
use RdapApi\RdapApi;
// Default configuration
$api = new RdapApi('your-api-key');
// Custom timeout (in seconds)
$api = new RdapApi('your-api-key', ['timeout' => 10]);
// Custom base URL
$api = new RdapApi('your-api-key', ['base_url' => 'https://custom.api.com/v1']);
```
### Domain Lookup
```php
$domain = $api->domain('example.com');
echo $domain->domain; // "example.com"
echo $domain->registrar->name; // Registrar name
echo $domain->registrar->iana_id; // IANA registrar ID
echo $domain->dnssec; // true/false
// With registrar follow-through (for thin registries)
$domain = $api->domain('example.com', ['follow' => true]);
echo $domain->meta->followed; // true
```
### IP Address Lookup
```php
$ip = $api->ip('8.8.8.8');
echo $ip->name; // "LVLT-GOGL-8-8-8"
echo $ip->country; // "US"
print_r($ip->cidr); // ["8.8.8.0/24"]
echo $ip->start_address; // "8.8.8.0"
echo $ip->end_address; // "8.8.8.255"
```
### ASN Lookup
```php
$asn = $api->asn(15169); // integer
$asn = $api->asn('AS15169'); // string with prefix (stripped automatically)
echo $asn->name; // "GOOGLE"
echo $asn->start_autnum; // 15169
```
### Nameserver Lookup
```php
$ns = $api->nameserver('ns1.google.com');
echo $ns->ldh_name; // "ns1.google.com"
print_r($ns->ip_addresses->v4); // ["216.239.32.10"]
print_r($ns->ip_addresses->v6); // ["2001:4860:4802:32::a"]
```
### Entity Lookup
```php
$entity = $api->entity('GOGL');
echo $entity->name; // "Google LLC"
echo $entity->organization; // "Google LLC"
echo $entity->autnums[0]->handle; // "AS15169"
echo $entity->networks[0]->cidr[0]; // "8.8.8.0/24"
```
### Bulk Domain Lookup
Requires a Pro or Business plan. Up to 10 domains per call.
```php
$resp = $api->bulkDomains(
['google.com', 'github.com', 'example.com'],
['follow' => true],
);
echo $resp->summary->total; // 3
echo $resp->summary->successful; // 3
foreach ($resp->results as $result) {
if ($result->status === 'success') {
echo "{$result->domain} — {$result->data->registrar->name}\n";
} else {
echo "{$result->domain} — error: {$result->message}\n";
}
}
```
## Supported TLDs Catalog
List every TLD the API can resolve, with the date support was added and a qualitative summary of which fields the registry's RDAP server populates. Does not count against your monthly quota.
```php
$tlds = $api->tlds();
if ($tlds !== null) {
echo "{$tlds->meta->count} TLDs, coverage ".round($tlds->meta->coverage * 100)."%\n";
foreach ($tlds->data as $tld) {
$availability = $tld->field_availability;
if ($availability !== null) {
echo "{$tld->tld}: expires_at={$availability->expires_at}\n";
}
}
}
```
Filter to recent additions or to a single registry:
```php
$recent = $api->tlds(['since' => '2026-04-01T00:00:00Z']);
$verisign = $api->tlds(['server' => 'rdap.verisign.com']);
```
Pass back the previous `etag` to skip the transfer when nothing has changed:
```php
$first = $api->tlds();
$later = $api->tlds(['if_none_match' => $first?->etag ?? '']);
if ($later === null) {
echo "No change since last poll\n";
}
```
Look up a single TLD:
```php
$com = $api->tld('com');
echo $com->data->rdap_server_host; // "rdap.verisign.com"
```
## Error Handling
All API errors are thrown as typed exceptions that extend `RdapApiException`:
```php
use RdapApi\Exceptions\AuthenticationException;
use RdapApi\Exceptions\NotFoundException;
use RdapApi\Exceptions\NotSupportedException;
use RdapApi\Exceptions\RateLimitException;
use RdapApi\Exceptions\SubscriptionRequiredException;
try {
$domain = $api->domain('example.nope');
} catch (NotSupportedException $e) {
// Catch before NotFoundException: it's a subclass.
echo 'The TLD is not covered by RDAP.';
} catch (NotFoundException $e) {
echo 'The domain is not registered.';
} catch (RateLimitException $e) {
echo "Rate limited, retry after {$e->retryAfter} seconds";
} catch (AuthenticationException $e) {
echo 'Invalid API key';
} catch (SubscriptionRequiredException $e) {
echo 'Subscription required';
}
```
`NotSupportedException` extends `NotFoundException`, so catching `NotFoundException` still handles both cases.
| Exception | HTTP Status | Description |
|---|---|---|
| `ValidationException` | 400 | Invalid input |
| `AuthenticationException` | 401 | Invalid or missing API key |
| `SubscriptionRequiredException` | 403 | No active subscription |
| `NotFoundException` | 404 | Namespace is covered but no record exists |
| `NotSupportedException` | 404 | Namespace (TLD, IP range, ASN range) is not covered by RDAP |
| `RateLimitException` | 429 | Rate limit or quota exceeded |
| `UpstreamException` | 502 | Upstream RDAP server failure |
| `TemporarilyUnavailableException` | 503 | Domain data temporarily unavailable |
All exceptions expose `statusCode`, `errorCode`, and `getMessage()`. `RateLimitException` and `TemporarilyUnavailableException` also have `retryAfter` (int or null).
## Nullable Fields
Fields that may be absent in API responses use nullable types (`?string`, `?int`). Check for null before using:
```php
if ($domain->dates->expires !== null) {
echo "Expires: {$domain->dates->expires}";
}
// Or use PHP 8's nullsafe operator
echo $domain->entities->registrant?->name;
```
## Development
Set up pre-commit hooks (runs lint + tests before each commit):
```bash
git config core.hooksPath .githooks
```
## License
MIT — see [LICENSE](LICENSE).