export const metadata = {
  title: "Endpoint Reference",
  description:
    "Every endpoint, method, and path in the FaithTranscripts v1 API surface.",
  alternates: { canonical: "/docs/api/reference" },
};

# Endpoint Reference

Base URL: `https://www.faithtranscripts.com/api/v1`. Every request requires
a Bearer token — see [Authentication](/docs/api/authentication).

## Transcripts

<EndpointBadge method="POST" path="/api/v1/transcripts" />

Create a transcript from any of the four [ingestion methods](/docs/api/ingestion).
Supports `?wait=true` and `?timeout=<seconds>` for [sync mode](/docs/api/async).
Accepts `Idempotency-Key` header.

<EndpointBadge method="GET" path="/api/v1/transcripts" />

List transcripts, newest first. Cursor-paginated.

| Query             | Notes                                             |
| ----------------- | ------------------------------------------------- |
| `cursor`          | Opaque; pass `next_cursor` from the previous page. |
| `limit`           | 1–100, default 20.                                |
| `status`          | `pending` \| `processing` \| `completed` \| `failed`. |
| `source_type`     | `paste` \| `upload` \| `youtube` \| `url`.        |
| `ai_pass_status`  | `idle` \| `queued` \| `processing` \| `completed` \| `failed`. |
| `created_after`   | ISO 8601 timestamp.                               |
| `created_before`  | ISO 8601 timestamp.                               |

<EndpointBadge method="GET" path="/api/v1/transcripts/{id}" />

Fetch a transcript. Accepts `?include=suggestions` to return the full
before/after suggestion list (larger payload).

<EndpointBadge method="GET" path="/api/v1/transcripts/{id}/content" />

Fetch just the corrected text. Accepts `?format=` — `txt`, `srt`, `vtt`,
`markdown`, `json`.

<EndpointBadge method="POST" path="/api/v1/transcripts/{id}/ai-pass" />

Trigger the AI validation pass on an existing transcript that didn't run
one at creation. Returns `409 conflict` if one is already running.

<EndpointBadge method="DELETE" path="/api/v1/transcripts/{id}" />

Soft-delete. Restores are dashboard-only.

<EndpointBadge method="POST" path="/api/v1/transcripts/uploads" />

Step 1 of the presigned upload flow — see
[Ingestion → Upload](/docs/api/ingestion).

## Jobs

<EndpointBadge method="GET" path="/api/v1/jobs/{id}" />

Fetch job status and progress.

```json
{
  "id": "job_01HW...",
  "object": "job",
  "transcript_id": "tr_01HW...",
  "type": "process_transcript",
  "status": "processing",
  "progress": { "phase": "deterministic_pass", "percent": 45 },
  "error": null,
  "created_at": "...",
  "updated_at": "..."
}
```

## Webhooks (receiving events)

There are no API routes to register or manage webhook endpoints — configure
URLs and secrets in [Settings → Webhooks](/settings/webhooks). The API still
**sends** signed `POST` requests to those endpoints when events occur; see
[Webhooks](/docs/api/webhooks) for delivery format, headers, and verification.

## Meta

<EndpointBadge method="GET" path="/api/v1/me" />

Returns key metadata: api key id, organization id, label. Useful as an
authentication smoke test.

<EndpointBadge method="GET" path="/api/v1/healthz" />

Liveness probe. No auth required.

## Transcript response shape

```jsonc
{
  "id": "tr_01HW...",
  "object": "transcript",
  "organization_id": "org_01HW...",
  "created_at": "2026-04-19T14:22:00Z",
  "updated_at": "2026-04-19T14:22:18Z",

  "status": "completed",           // pending | processing | completed | failed
  "source_type": "youtube",        // paste | upload | youtube | url
  "source_format": "youtube_auto",
  "source_ref": "https://youtu.be/...",
  "title": "Sunday Service 2026-04-12",

  "ai_pass_status": "completed",   // idle | queued | processing | completed | failed
  "ai_pass_job_id": "job_01HW...",

  "content": "<corrected text>",

  "changes_summary": {
    "total": 42,
    "auto_applied": 30,
    "needs_review": 9,
    "ai_flagged": 3,
    "by_category": {
      "person": 12,
      "place": 4,
      "theology": 8,
      "church": 3,
      "bible": 15
    }
  },

  "options": { /* echoes what the caller requested */ },
  "metadata": { /* caller-supplied, echoed back */ },
  "error": null
}
```

Pass `?include=suggestions` to add a detailed `suggestions` array with
each change's original text, replacement text, confidence, category,
status (`auto_applied` / `needs_review` / `ai_flagged`), and source
(`deterministic` / `ai`).

## Pagination envelope

List endpoints wrap data with a cursor envelope:

```json
{
  "data": [ /* ... */ ],
  "next_cursor": "opaque-string-or-null"
}
```

Pass `next_cursor` as `?cursor=` on the next request to fetch the next
page. `null` means there are no more results.

## Request & response headers

| Header             | Direction | Purpose                                      |
| ------------------ | --------- | -------------------------------------------- |
| `Authorization`    | Request   | `Bearer ft_live_…`                           |
| `Content-Type`     | Request   | `application/json` for POST bodies.          |
| `Idempotency-Key`  | Request   | Optional; dedupes POSTs for 24 hours.        |
| `X-Request-Id`     | Response  | Correlates to our server logs. Always set.   |
| `X-RateLimit-*`    | Response  | Current bucket and remaining allowance.      |
| `Retry-After`      | Response  | Seconds to wait, on `429` and first poll.    |
