# API overview

Post Reef is a JSON API for turning any post into structured data: submit a public URL — a social video, a photo post or carousel, or an ordinary article — and get back metadata, transcript, comments, images, downloadable media, plus an optional structured JSON extraction conforming to a schema you provide. The web app runs the same pipeline for hands-on testing; everything it does is one of the calls below.

## Base URL

```
https://postreef.com
```

All endpoints live under `/v1`. Requests and responses are JSON (except file downloads, which stream the raw artifact).

## Authentication

Create an API key at [https://postreef.com/developers/api-keys](/developers/api-keys), then send it on every request. Either header works:

```bash
x-api-key: pr_...
# or
Authorization: Bearer pr_...
```

Keys act on behalf of your account: extractions they create also show up in the web app for inspection, and credits are drawn from the same balance.

## The loop

- **1. Quote (optional).** `POST /v1/probe` inspects the URL and returns the exact credit price for the body you intend to submit. Probing is free.
- **2. Submit.** `POST /v1/extractions` with the URL, your inputs and (optionally) a JSON Schema. Credits are debited up-front and refunded in full if the extraction fails.
- **3. Wait.** Poll `GET /v1/extractions/:id/result` (202 while running, 200 when done) or register a [webhook](/docs/api/webhooks) and skip polling entirely.
- **4. Collect.** The result carries the structured `extraction` object plus `artifacts` — ready-to-fetch URLs for every downloaded file (`artifacts.thumbnail`, `artifacts.transcript`, `artifacts.images`, a catch-all `artifacts.files` map by name, …), each pointing at `GET /v1/extractions/:id/files/:name`. Those URLs accept either your `x-api-key` or, if you're signed in to the web app, your browser session — so they also open directly in a tab. Check `outcome` first: `ok` means `extraction` holds your data, while `no_match`/`uncertain` mean the video didn't match your schema (`extraction` is null, `verdictReason` explains).

```json
"artifacts": {
  "thumbnail": "https://postreef.com/v1/extractions/ext_abc123/files/thumbnail.jpg",
  "transcript": "https://postreef.com/v1/extractions/ext_abc123/files/transcript.txt",
  "comments": "https://postreef.com/v1/extractions/ext_abc123/files/comments.json",
  "images": [],
  "files": {
    "thumbnail.jpg": "https://postreef.com/v1/extractions/ext_abc123/files/thumbnail.jpg",
    "transcript.txt": "https://postreef.com/v1/extractions/ext_abc123/files/transcript.txt",
    "comments.json": "https://postreef.com/v1/extractions/ext_abc123/files/comments.json"
  }
}
```

## OpenAPI spec

The full machine-readable spec lives at [/v1/openapi.json](/v1/openapi.json) (OpenAPI 3.1, no auth required). Import it straight into Postman, Insomnia, or your client generator. The [endpoint reference](/docs/api/reference) on this site is generated from the same document.

## Where to next

Jump into the [API quickstart](/docs/api/quickstart) for copy-paste examples, check [errors & limits](/docs/api/errors) before going to production, or try every endpoint live in the [interactive reference](/docs/api/reference).
