# Getting started with the DigStory API

Published 9 November 2026 on the [DigStory blog](https://digstory.io/blog.md).

> Create an API key, make your first request, page through large results and stay inside your daily quota, with the endpoints you will use most.

Everything you can see on DigStory's pages is also available as JSON. This guide gets you from zero to a working integration.

## 1. Create a key

Open **Team → API keys** and create a key. It starts with `dg_` and is shown once, so store it somewhere safe. Keys belong to your team; requests made with them count against the team's plan.

## 2. Make a request

Send the key as a bearer token:

```bash
curl -H "Authorization: Bearer dg_…" "https://localhost/api/v1/me"
```

`/me` tells you which team the key belongs to and how much of today's quota is left, which makes it a good first call for checking your setup.

Then look up a domain:

```bash
curl -H "Authorization: Bearer dg_…" "https://localhost/api/v1/domains/example.com"
```

## 3. The endpoints you will use most

| Endpoint | What it returns |
| --- | --- |
| `GET /api/v1/domains/{name}` | The domain's current records, registration and technologies |
| `GET /api/v1/domains/{name}/history` | Every DNS, WHOIS, availability and technology change |
| `GET /api/v1/domains/{name}/whois` | WHOIS history and the original record text |
| `GET /api/v1/domains/{name}/subdomains` | Known hostnames under the domain |
| `GET /api/v1/ips/{ip}` | What is known about an address |
| `GET /api/v1/reverse/ip/{ip}` | Every hostname on an IP address |
| `GET /api/v1/reverse/{cname\|ns\|mx}/{name}` | Every hostname pointing at a CNAME, NS or MX target |
| `GET /api/v1/technologies` and `/technologies/{slug}` | Technologies with counts, and one technology's domains |
| `GET /api/v1/collections` and `/collections/{slug}` | Curated domain sets and their members |
| `GET /api/v1/nod` | Newly observed domains |
| `GET /api/v1/whois/{list}` | The expiring, lapsing, dropped and new-registration lists |
| `GET /api/v1/watching` and `/watching/events` | Your team's watched domains and their change events |

## 4. Page through large results

Lists return a page of `data` and a `next` cursor. Pass it back as `after` to get the following page, and stop when `next` is `null`:

```python
import requests

BASE = "https://localhost/api/v1"
HEADERS = {"Authorization": "Bearer dg_…"}

def reverse_mx(target):
    after = None
    while True:
        params = {"limit": 1000}
        if after:
            params["after"] = after
        page = requests.get(f"{BASE}/reverse/mx/{target}", headers=HEADERS, params=params).json()
        yield from page["data"]
        after = page.get("next")
        if not after:
            break

for row in reverse_mx("aspmx.l.google.com"):
    print(row["domain"], row["since"])
```

`limit` sets the page size, up to 5,000. Fewer, larger pages use less of your quota.

## 5. Stay inside your quota

Each team has a daily request quota: 50 requests on the free plan, 2,000 on Pro and 20,000 on Business. Every response carries two headers:

- `x-ratelimit-limit`: your daily quota
- `x-ratelimit-remaining`: what is left today

When the quota runs out, the API answers `429` with a `retry-after` header giving the seconds until it resets at midnight UTC. A missing, wrong or revoked key gets `401`. Both come with a JSON body:

```json
{"error": {"code": "quota_exceeded", "message": "daily quota exceeded; it resets at midnight UTC"}}
```

## 6. Prefer webhooks for changes

If you are polling `/domains/{name}/history` to notice changes, watch the domains instead and set a webhook: DigStory will send you each change as it is seen, at no cost to your quota. See [Watch domains and get every change as a webhook](/blog/watching-and-webhooks).

You can also see every request your team has made under **Team → Requests**, which helps when a quota runs out sooner than expected.
