# Sandchest docs

The open-source speech-to-text API. Real word-level timestamps in milliseconds, an AssemblyAI-compatible surface, and a native TypeScript SDK.

Sandchest turns audio into words. Every word comes back with its own start and end
in milliseconds, its own confidence score, and the identifier of the model that
actually produced it. This page tells you which door to walk through; the rest of
the docs are linear, imperative and end with something you can check.

## What it is

A speech-to-text API you can read the source of. Two HTTP surfaces sit on the same
engine: an AssemblyAI-compatible one at `/v2/*`, and a native one at `/api/v1/*`.
The hosted service runs at `https://stt-api.sandchest.com`; the same code runs on
your own GPU or Apple Silicon machine.

| | |
| --- | --- |
| Base URL | `https://stt-api.sandchest.com` |
| Auth | `Authorization: <your key>` (a `Bearer` prefix also works) |
| Dashboard | [sandchest.com/dashboard](https://sandchest.com/dashboard) |
| Source | [CapSoftware/Sandchest](https://github.com/CapSoftware/Sandchest) |
| Machine-readable | [`/llms.txt`](/llms.txt) · [`/llms-full.txt`](/llms-full.txt) · [`/openapi.json`](/openapi.json) |

## Three ways in

**Keep the AssemblyAI SDK you already have.** Change `apiKey` and `baseUrl`, change
nothing else. Upload, create, poll, list, delete, sentences, paragraphs, word search,
SRT and VTT all work. See [Using the AssemblyAI SDK](/docs/assemblyai).

```ts title="transcribe.ts"
import { AssemblyAI } from "assemblyai";

const client = new AssemblyAI({
  apiKey: process.env.SANDCHEST_API_KEY,
  baseUrl: "https://stt-api.sandchest.com",
});
```

**Use the native SDK.** `@sandchest/sdk` is small, fully typed, and cancels through
uploads, requests and polling. See [TypeScript SDK](/docs/sdk).

```ts title="transcribe.ts"
import { Sandchest } from "@sandchest/sdk";

const client = new Sandchest({ apiKey: process.env.SANDCHEST_API_KEY });
```

**Call the HTTP API directly.** Ten endpoints, `{ "error": "..." }` on failure, no
client library required. See the [API reference](/docs/api).

```bash
curl https://stt-api.sandchest.com/v2/transcript/$ID \
  -H "Authorization: $SANDCHEST_API_KEY"
```

## Give this to your agent

These docs are written to be handed to an AI coding agent. Paste this prompt into
Claude Code, Cursor, Codex or anything else that can fetch a URL:

```text
Add Sandchest speech-to-text to this project.
Docs: https://sandchest.com/llms.txt (index) — fetch https://sandchest.com/llms-full.txt for everything.
API key: read it from the SANDCHEST_API_KEY environment variable (never hardcode it).
Base URL: https://stt-api.sandchest.com
Use the official assemblyai package if it is already installed (change apiKey + baseUrl), otherwise @sandchest/sdk.
Transcribe <file>, print each word with its start/end in milliseconds, and add a small test.
```

Every page here is also served as plain Markdown at `/docs/<slug>.md`, and answers
to `Accept: text/markdown`. [Set up with an AI agent](/docs/agents) has the details
and a snippet for your `CLAUDE.md` or `AGENTS.md`.

## Everything else

| Page | What it covers |
| --- | --- |
| [Quickstart](/docs/quickstart) | Key, environment variable, first transcript, three ways |
| [Set up with an AI agent](/docs/agents) | The agent prompt, `llms.txt`, raw Markdown, editor rules |
| [Authentication](/docs/authentication) | Keys, header forms, workspaces and roles, rotation |
| [Using the AssemblyAI SDK](/docs/assemblyai) | The two-line swap, what is supported, what is rejected |
| [Transcript options](/docs/transcripts) | Every request field, the transcript object, the word object |
| [Languages](/docs/languages) | Detection, explicit codes, the supported list, models |
| [Webhooks](/docs/webhooks) | Payload, auth header, retries, local testing |
| [API reference](/docs/api) | Every endpoint, request, response and error |
| [TypeScript SDK](/docs/sdk) | `@sandchest/sdk` in full |
| [Errors and limits](/docs/errors) | Status codes, size limits, rate limits, deadlines |
| [Billing](/docs/billing) | Prepaid credits, per-second metering, top-ups |
| [Self-hosting](/docs/self-hosting) | Apple Silicon, Docker Compose, required environment |

## Verify

You are ready to start when this prints your workspace's ten most recent
transcripts (an empty list is a pass — it means the key authenticated):

```bash
curl -sS "https://stt-api.sandchest.com/v2/transcript?limit=10" \
  -H "Authorization: $SANDCHEST_API_KEY"
```

```json title="expected shape"
{
  "page_details": { "limit": 10, "result_count": 0, "current_url": "...", "prev_url": null, "next_url": null },
  "transcripts": []
}
```

If you get `{"error":"A valid Sandchest API key is required."}`, the key is missing,
misspelled or revoked. Start at the [Quickstart](/docs/quickstart).

## Next

[Quickstart](/docs/quickstart) — get a key and your first transcript in about two minutes.
