# SERPdive API Reference

> One endpoint, one job: `POST api.serpdive.com/v1/search` takes a question and returns answer-ready page content — extracted, cleaned, and sized for an LLM. This page is the entire API surface: if it's not here, you don't need it.

- [API Playground](https://serpdive.com/dashboard/playground)
- [Dashboard](https://serpdive.com/dashboard)
- [OpenAPI spec](https://serpdive.com/openapi.json)
- [llms.txt](https://serpdive.com/llms.txt)
- [Contact](mailto:hello@serpdive.com)

## Quickstart

Grab an API key from the [dashboard](https://serpdive.com/dashboard/keys) (free — 1,000 credits a month, no card), then:

```bash
curl -X POST https://api.serpdive.com/v1/search \
  -H "Authorization: Bearer $SERPDIVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "what happened between Trump and FIFA",
        "model": "mako" }'
```

That's a complete integration. The [playground](https://serpdive.com/dashboard/playground) generates this snippet — plus Node.js and Python — with your key preselected, and shows the live response next to it.

## Authentication

Every request carries your key in the `Authorization` header: `Bearer sd_live_…`. Keys are created, revealed and revoked in [API Keys](https://serpdive.com/dashboard/keys); revocation takes effect immediately. A missing or unknown key gets a `401` with `missing_api_key` or `invalid_api_key` — the search never runs, and nothing is billed.

## The request

`POST /v1/search` with a JSON body. Three parameters — everything else is decided for you:

| Parameter | Type | Description |
|---|---|---|
| `query` | string, required | The question, as you'd ask it. Up to 300 characters — longer queries are truncated, not rejected. |
| `model` | `"mako"` \| `"moby"` | Retrieval depth. `mako` (default) returns the fact-carrying sentences of each source; `moby` returns the full readable content of every page. Unknown values fall back to `mako`. |
| `verdict` | boolean | Opt-in direct answer. `true` adds a written answer built from the sources — concise on Mako, detailed with `[n]` citations on Moby. Included in the price, never extra credits. |

**Localization is automatic.** The query's language picks where we search: a German query searches the German-language web, a Japanese one the Japanese web — whoever and wherever the caller is. There is no country knob to set.

**Set a generous client timeout.** Mako answers in a few seconds; Moby reads whole pages and can take substantially longer on heavy sources. We recommend an 80-second client timeout — it's what our own playground uses.

## The response

A successful search returns `200` with this shape — nothing else, ever:

```json
{
  "query": "what happened between Trump and FIFA",
  "model": "mako",
  "response_time_ms": 2641,
  "verdict": null,
  "extra_info": null,
  "results": [
    {
      "url": "https://www.reuters.com/sports/soccer/…",
      "title": "Trump, FIFA's Infantino unveil …",
      "date": "2026-07-11",
      "content": "The announcement came during a joint press conference … [the fact-carrying sentences of the page]"
    },
    {
      "url": "https://www.bbc.com/sport/football/…",
      "title": "What the deal means for the 2026 World Cup",
      "content": "…"
    }
  ]
}
```

| Field | Type | Description |
|---|---|---|
| `query` | string | Your query, echoed untouched. |
| `model` | string | The model that answered — `mako` or `moby`. |
| `response_time_ms` | number | Wall-clock time we took, in milliseconds. |
| `verdict` | string \| null | The written answer when you sent `verdict: true` and one could be built from the sources; `null` otherwise. |
| `extra_info` | object \| null | A structured direct-answer block when the query has one — weather, exchange rates, definitions, live scores… Its `type` field says which kind; `null` when the query doesn't call for one. |
| `results` | array | The extracted sources, best first. Each has `url`, `title`, `content` (the extraction — sentences on Mako, the full readable page on Moby) and `date` when a publication date was found (ISO 8601). |

Results are **real page extractions only**: a source that couldn’t be read is simply absent — no snippet padding, no placeholders. Tracking parameters (`utm_*`, click IDs…) are stripped from URLs, so what you cite is clean.

Asking for the answer looks like this:

```json
{ "query": "who won the 2026 Champions League final",
  "model": "moby",
  "verdict": true }
```

## Errors

Failures return a JSON body with an `error` code (and sometimes a `detail`):

```json
{ "error": "invalid_api_key" }
```

| Status | Code | Meaning |
|---|---|---|
| 400 | `bad_json` | The body isn't valid JSON. |
| 400 | `missing_query` | No `query` in the body. |
| 401 | `missing_api_key` / `invalid_api_key` | No usable key in the `Authorization` header. |
| 502 | `upstream_timeout` / `upstream_error` | The search couldn't complete. Safe to retry. |
| 503 | `pool_empty` / `region_unavailable` / `auth_unavailable` | Momentarily out of capacity. `503`s may carry a `retry-after` header — honor it, then retry. |

**Failed searches are never billed.** Any non-`200` response costs zero credits, whatever the reason.

## Mako & Moby

| Model | Cost | What you get |
|---|---|---|
| `mako` | 1 credit | The lean default for agents: only the fact-carrying sentences of each source (~1k tokens total), answering in a few seconds. Verdict, when requested, is one concise paragraph. |
| `moby` | 1.5 credits | The deep read: the whole readable text of every source (up to ~15k tokens), for when your downstream model needs the full story. Verdict, when requested, is detailed with `[n]` citations. |

Rule of thumb: start with Mako. Reach for Moby when the task is synthesis — briefs, comparisons, anything where a missing paragraph changes the conclusion.

## Credits & limits

A Mako search costs 1 credit, a Moby search 1.5 — the `verdict` answer is always included, and failures are free. Every account gets 1,000 credits a month; they reset on the 1st and don't roll over. Live consumption is on your [Usage](https://serpdive.com/dashboard/usage) page, plans and pricing on [Billing](https://serpdive.com/dashboard/billing).

During launch there is no hard rate limit and we don't cut anyone off — searching at serious scale? [Talk to us](mailto:hello@serpdive.com).
