API documentation
One route returns every known subdomain of a domain, as JSON or plain text. Base URL: https://api.assetdiscovery.io
Quickstart
- Create a free account and verify your email.
- Create an API key under API keys. The full key is shown once, so store it right away.
- Export it as
ASSETDISCOVERY_KEYand send your first request:
curl "https://api.assetdiscovery.io/api/domain/example.com" \
-H "Api-Key: $ASSETDISCOVERY_KEY"Authentication
Send your key in the Api-Key header on every request. Keys start with sk_live_. Keep keys on the server; never ship them in browser or mobile code. Revoking a key in the app stops it immediately.
Api-Key: sk_live_8f3c…Endpoints
All formats share one route, GET /api/domain/{domain}, with the same request and response shape as other subdomain APIs that use an Api-Key header. Existing scripts work by changing the base URL. The format query parameter is optional: json (default), txt or full. The total field is always the real number of known subdomains, even when your plan returns fewer.
Subdomains
GET/api/domain/{domain}
Returns hostnames as a JSON array. This is the default and works on every plan, up to your plan's results-per-query limit.
- domainpath
- example.comRegistrable domain or subdomain, without scheme or path.
- Api-Keyheader
- sk_live_…Your API key. Required on every request.
curl "https://api.assetdiscovery.io/api/domain/example.com" \
-H "Api-Key: $ASSETDISCOVERY_KEY"{
"domain": "example.com",
"total": 4521,
"subdomains": [
"api.example.com",
"auth.example.com",
"cdn.example.com",
"dev.api.example.com",
"mail.example.com"
]
}Plain text
GET/api/domain/{domain}?format=txt
Returns one hostname per line, ready to pipe into other tools. Needs a plan that includes export; other plans get plan_required.
- domainpath
- example.comRegistrable domain or subdomain, without scheme or path.
- formatquery
- txtOptional. Return text/plain instead of JSON.
- Api-Keyheader
- sk_live_…Your API key. Required on every request.
curl "https://api.assetdiscovery.io/api/domain/example.com?format=txt" \
-H "Api-Key: $ASSETDISCOVERY_KEY" \
-o example.com.txtapi.example.com
auth.example.com
cdn.example.com
dev.api.example.com
mail.example.comFull records
GET/api/domain/{domain}?format=full
Returns each host with first_seen and last_seen, a pagination cursor and a meta block with your plan and quota.
- domainpath
- example.comRegistrable domain or subdomain, without scheme or path.
- formatquery
- fullOptional. Return records with timestamps and meta.
- cursorquery
- c_3uoOptional. The
next_cursorfrom the previous page. - Api-Keyheader
- sk_live_…Your API key. Required on every request.
curl "https://api.assetdiscovery.io/api/domain/example.com?format=full" \
-H "Api-Key: $ASSETDISCOVERY_KEY"{
"domain": "example.com",
"total": 4521,
"returned": 100,
"truncated": true,
"next_cursor": null,
"subdomains": [
{ "host": "api.example.com", "first_seen": "2023-11-04T00:00:00Z", "last_seen": "2026-10-17T00:00:00Z" }
],
"meta": {
"query_ms": 38,
"plan": "free",
"results_limit": 100,
"quota": { "used": 2, "limit": 5, "period": "day", "resets_at": "2026-10-21T00:00:00Z" },
"upgrade_url": "https://assetdiscovery.io/pricing"
}
}Pagination
With format=full, next_cursor is set when more results are available within your plan. Pass it as ?cursor= and repeat until it is null. When truncated is true, the remaining results are beyond your plan's results-per-query limit and meta.upgrade_url points to the plans that return them.
curl "https://api.assetdiscovery.io/api/domain/example.com?format=full&cursor=c_3uo" \
-H "Api-Key: $ASSETDISCOVERY_KEY"Quota headers
Every response, including errors, carries your current quota so you can pace requests without an extra call. A 429 also includes Retry-After in seconds.
| Header | Example | Description |
|---|---|---|
| X-Quota-Limit | 5 | Queries allowed in the current period. unlimited on plans without a cap. |
| X-Quota-Remaining | 3 | Queries left in the current period, after this request. |
| X-Quota-Reset | 2026-10-21T00:00:00Z | When the period resets, as an ISO 8601 UTC timestamp. |
curl -sI "https://api.assetdiscovery.io/api/domain/example.com" \
-H "Api-Key: $ASSETDISCOVERY_KEY" | grep -i '^x-quota'HTTP/2 200
content-type: application/json
x-quota-limit: 5
x-quota-remaining: 3
x-quota-reset: 2026-10-21T00:00:00ZErrors
Errors return a JSON body with a stable code to branch on. The message is for people and may change.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Slow down and retry shortly.",
"retry_after_seconds": 42,
"docs_url": "https://assetdiscovery.io/docs#errors"
}
}| Code | HTTP | Meaning | What to do |
|---|---|---|---|
| unauthorized | 401 | The Api-Key header is missing, malformed or the key was revoked. | Check the header name and value. Create a new key under API keys if this one was revoked. |
| email_not_verified | 403 | The account email is not verified, so its keys are inactive. | Open the verification email and confirm. You can resend it from the app. |
| quota_exceeded | 429 | The daily or monthly query allowance for your plan is used up. | Wait until resets_at or X-Quota-Reset, or upgrade your plan. |
| rate_limited | 429 | Too many requests per minute for this key. | Retry after retry_after_seconds (also sent as Retry-After). Back off instead of retrying in a loop. |
| plan_required | 402 | The request uses a feature your plan does not include, such as format=txt. | Remove the parameter, or compare plans to find the one that includes it. |
| invalid_domain | 422 | The domain is not a valid hostname. | Send a bare hostname such as example.com, without https:// or a path. |
Rate limits
Limits apply per key and come from your plan. The quota headers and meta.quota show where you stand.