> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hadoseo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Snapshot

> Fetch the exact rendered HTML a bot was served, by snapshot ID

```
POST /functions/v1/get-snapshot
```

<Info>
  **Beta.** This endpoint is new and its response shape may still change. It is
  the companion to
  [Export Page Snapshots](/api-reference/endpoint/export-page-snapshots), which
  tells you *which* snapshot each bot received; this returns the HTML itself.
</Info>

Returns the stored HTML for a single snapshot ID. Every request re-checks that the snapshot belongs to a domain your account can access, so a snapshot ID is a **durable** reference — unlike the temporary `htmlUrl` links, it doesn't expire.

<Warning>
  Always call this endpoint from a **server-side environment** (backend API, serverless function, build script, etc.). Never include your API key in client-side code — it will be visible to anyone inspecting your frontend.
</Warning>

<Info>
  Programmatic (API key) access requires the **Pro plan and above** — requests
  from Starter accounts return `403 plan_upgrade_required`.
</Info>

## Which should I use?

|          | `htmlUrl` (from Export Page Snapshots) | `snapshot_id` + this endpoint          |
| -------- | -------------------------------------- | -------------------------------------- |
| Auth     | None — the link is pre-authorized      | Your API key, checked every time       |
| Lifetime | \~24 hours                             | Never expires                          |
| Quota    | Doesn't count against your quota       | Counts as one API call                 |
| Encoding | Gzipped; needs `curl --compressed`     | JSON string, ready to use              |
| Best for | Bulk export, immediate download        | Storing a reference and fetching later |

## Request

### Headers

| Header          | Required | Description                    |
| --------------- | -------- | ------------------------------ |
| `Authorization` | Yes      | `Bearer hado_sk_your_key_here` |
| `Content-Type`  | Yes      | `application/json`             |

### Body Parameters

| Parameter     | Type   | Required | Description                                                                                 |
| ------------- | ------ | -------- | ------------------------------------------------------------------------------------------- |
| `snapshot_id` | string | Yes\*    | A `snapshotId` from [Export Page Snapshots](/api-reference/endpoint/export-page-snapshots). |

\* Exactly one of `snapshot_id` or `id` is required. `id` refers to a live crawl-feed event and is used by the dashboard; API integrations should use `snapshot_id`.

### Example Request

```bash theme={null}
curl -X POST https://api.hadoseo.com/functions/v1/get-snapshot \
  -H "Authorization: Bearer hado_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "snapshot_id": "92c63e55-bfc6-4e0b-93f2-f1aff7a2f95a"
  }'
```

## Response

### Success (200)

```json theme={null}
{
  "html": "<!DOCTYPE html><html lang=\"en\"><head>..."
}
```

| Field  | Type   | Description                                                               |
| ------ | ------ | ------------------------------------------------------------------------- |
| `html` | string | The exact HTML that was served to the bot, decompressed and ready to use. |

### Error Responses

| Status | Body                                                                     | Description                                                                                                                                                   |
| ------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `{ "error": "id or snapshot_id required" }`                              | Neither identifier was supplied.                                                                                                                              |
| 400    | `{ "error": "invalid JSON body" }`                                       | The request body could not be parsed.                                                                                                                         |
| 401    | `{ "error": "invalid_api_key" }`                                         | API key is missing, invalid, or revoked.                                                                                                                      |
| 403    | `{ "error": "plan_upgrade_required" }`                                   | Programmatic access requires the Pro plan or above.                                                                                                           |
| 404    | `{ "error": "not found" }`                                               | No such snapshot, **or** it belongs to a domain your account can't access. The two are deliberately indistinguishable.                                        |
| 404    | `{ "error": "snapshot not found in storage" }`                           | The snapshot is known but its stored HTML is no longer retained — see below.                                                                                  |
| 429    | `{ "error": "rate_limit_exceeded_monthly", "usage": 300, "limit": 300 }` | Rate limit exceeded. The code is `rate_limit_exceeded_monthly` or `rate_limit_exceeded_per_minute` — match on the `rate_limit_exceeded` prefix to catch both. |
| 503    | `{ "error": "snapshot storage unavailable" }`                            | Snapshot storage is temporarily unreachable. Retry later.                                                                                                     |

<Note>
  **`snapshot not found in storage` is expected for older snapshots.** The
  stored HTML is retained on a rolling basis while the crawl history is kept
  indefinitely, so a snapshot ID can outlive its downloadable copy. Fetch the
  HTML soon after export if you need to keep it.
</Note>

## Example

Export a page's snapshot history, then pull the HTML for each distinct version:

```javascript theme={null}
const headers = {
  "Authorization": `Bearer ${process.env.HADOSEO_API_KEY}`,
  "Content-Type": "application/json",
};

const listed = await fetch("https://api.hadoseo.com/functions/v1/export-page-snapshots", {
  method: "POST",
  headers,
  body: JSON.stringify({ domainId, url: "/pricing", period: "30d" }),
}).then((r) => r.json());

// `snapshots` is already deduplicated, so this is one call per distinct version.
for (const [snapshotId, meta] of Object.entries(listed.snapshots)) {
  const res = await fetch("https://api.hadoseo.com/functions/v1/get-snapshot", {
    method: "POST",
    headers,
    body: JSON.stringify({ snapshot_id: snapshotId }),
  });
  if (res.status === 404) continue; // HTML no longer retained
  const { html } = await res.json();
  console.log(meta.contentHash.slice(0, 8), html.length);
}
```

<Tip>
  Iterate the `snapshots` dictionary rather than `rows` — a single version is
  usually served across many day × bot combinations, so keying off rows would
  fetch the same HTML repeatedly and burn your quota.
</Tip>
