Skip to content

API Reference

1. Create User

Anyone can register. Accounts are created pending admin approval — you will not be able to log in or generate API keys until an administrator approves your account. You'll receive a confirmation email once the account is active.

curl -L -i -k \
  -X POST "https://zonefeeds.com/api/auth/register" \
  -H "Content-Type: application/json" \
  --data-raw '{
    "username":"<YOUR_USERNAME>",
    "email":"<YOUR_EMAIL>",
    "password":"<YOUR_PASSWORD>"
  }'

2. Generate API Key

Authenticate with your username and password in the body (no Bearer header on this endpoint). expires_in_days is optional — omit it to use the default for your plan (Trial: 7 days, Basic / Enterprise: 365 days).

curl -L -i -k \
  -X POST "https://zonefeeds.com/api/auth/api-keys/generate" \
  -H "Content-Type: application/json" \
  --data-raw '{
    "username":"<YOUR_USERNAME>",
    "password":"<YOUR_PASSWORD>",
    "name":"<KEY_NAME>",
    "expires_in_days":<DAYS_UNTIL_EXPIRY>
  }'

3. List User API Keys

Returns all active API keys for your account.

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/auth/api-keys" \
  -H "Authorization: Bearer ${API_KEY}"

4. Delete an API Key

Remove a key by its name. Key names that contain spaces or other reserved URL characters must be URL-encoded in the path (e.g. a key called prod key becomes prod%20key).

curl -L -i -k \
  -X DELETE "https://zonefeeds.com/api/auth/api-keys/<KEY_NAME>" \
  -H "Authorization: Bearer ${API_KEY}"

5. Get User Info

Fetch details about the user tied to your API key.

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/auth/me" \
  -H "Authorization: Bearer ${API_KEY}"

6. Search Domains

Search the “dev.zone” dataset for matching domains. Tip: You can replace dev.zone with any zone name returned by List All Zones. Use *.zone (i.e. set the path segment to *) to search across all zones in one query (subject to your plan's limits). Limits: Maximum date range is 10 days. Maximum limit is 10,000 per request. Your plan also applies a ceiling to the effective limit — see Query Parameters below.

Response status codes

Code Meaning
200 Results returned. An empty results array on a cursor request means you've reached the last page.
400 Invalid search pattern, invalid date, start / end in the future, or after / pit sent without the other.
404 First-page query returned zero matching domains. Clients should stop; cursor pages never return 404.
410 The pit session has expired (2 minutes of inactivity). Restart from page 1 to obtain a fresh pit.

First page

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/api/v1/download/dev.zone?search=<TERM>&limit=<N>" \
  -H "Authorization: Bearer ${API_KEY}"

Next page (cursor-based)

Use the pit and after values returned by the previous response.

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/api/v1/download/dev.zone?limit=<N>&pit=<PIT_ID>&after=<CURSOR_B64>" \
  -H "Authorization: Bearer ${API_KEY}"

7. Get Delta (google.zone)

Fetch the change-set (“delta”) between two timestamps in the “google.zone” dataset. Tip: You can replace google.zone with any zone name returned by List All Zones.

First page

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/api/v1/download/google.zone?search=<TERM>&start=<ISO_START>&end=<ISO_END>&limit=<N>" \
  -H "Authorization: Bearer ${API_KEY}"

Next page (cursor-based)

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/api/v1/download/google.zone?start=<ISO_START>&end=<ISO_END>&limit=<N>&pit=<PIT_ID>&after=<CURSOR_B64>" \
  -H "Authorization: Bearer ${API_KEY}"

8. List All Zones

Retrieve a list of all available zones.

curl -L -i -k \
  -X GET "https://zonefeeds.com/api/api/v1/zones/" \
  -H "Authorization: Bearer ${API_KEY}"

Query Parameters

Parameter Type Description
search string Domain match applied against the domain field (case-insensitive). If the value contains *, a wildcard match is used (e.g. app*, *-bank*); otherwise a prefix match is used. Allowed characters: a-z, 0-9, ., *, and - (not at the start of a segment).
limit integer Maximum number of records to return. Range: 110000. Default: 1000. Your plan applies its own ceiling on top of this — if you request more than your plan allows, the effective limit is capped server-side without error.
start string ISO 8601 timestamp indicating the inclusive lower bound (e.g. 2025-07-19T10:30:00Z). Must not be in the future.
end string ISO 8601 timestamp indicating the exclusive upper bound (e.g. 2025-07-23T10:30:00Z). Must not be in the future. The window end − start cannot exceed 10 days.
after string Base64-encoded sort cursor to fetch the next page of results. Must be sent together with pit.
pit string Elasticsearch Point-In-Time id used to keep pagination consistent across pages. Returned by the first-page response; valid for 2 minutes after the last request.

Important note on pagination (migration change)

We’ve migrated to a new backend for faster searches. As part of this change, offset-based pagination with skip has been removed.
Use cursor-based pagination with pit and after (plus limit) instead:

  • The first page response includes a pit id. If more results exist, it also includes a next_cursor string.
  • To fetch the next page, send the original query parameters plus pit=<PIT_ID> and after=<next_cursor> (i.e. take the next_cursor value from the previous response and put it in the after= query parameter).
  • A response whose results array is empty or that has no next_cursor is the last page — stop paginating.
  • The pit is valid for 2 minutes after the last request. If it expires, the next cursor call returns 410 and you must restart from the first page to get a fresh pit.
  • Cursor (pagination) requests do not consume your monthly query quota — only the first-page request for a given search does.

Example

Initial request:

GET https://zonefeeds.com/api/api/v1/download/com.zone?start=2025-12-20T10:30:00Z&end=2025-12-25T10:30:00Z&limit=1000&search=technology

Response body:

{
  "pit": "w8abBAYNZGN6ZHMucmVjb3JkcxZ...",
  "results": [
    { "domain": "technology-hub.com", "status": "active", "timestamp": 1734691200000 }
  ],
  "next_cursor": "WzEyODg2XQ=="
}

Next-page request — reuse the original filters and pass pit as-is, after=<next_cursor>:

GET https://zonefeeds.com/api/api/v1/download/com.zone?
  start=2025-12-20T10:30:00Z&
  end=2025-12-25T10:30:00Z&
  limit=1000&
  search=technology&
  pit=w8abBAYNZGN6ZHMucmVjb3JkcxZ...&
  after=WzEyODg2XQ==

Signature reference (server side):

after: Optional[str] = Query(None, description="Base64-encoded sort values")
pit:   Optional[str] = Query(None, description="Elasticsearch PIT id")