# Speech transcription

> Direct Deepgram transcription and speaker diarization using short-lived tokens and your shared credit.

```bash
npx extraorbital add deepgram
```

This provisions a stable refresh credential. Your audio goes directly to Deepgram.
Transcription and speaker diarization use your existing shared credit, including the
$5 machine allowance. There is no separate Deepgram free allocation.

## Credentials

| Variable | Purpose |
| --- | --- |
| `DEEPGRAM_BASE_URL` | Deepgram's API origin |
| `DEEPGRAM_TOKEN_URL` | Exchange your refresh credential for a temporary token |
| `DEEPGRAM_REFRESH_TOKEN` | Stable credential; keep it in your backend |

## Transcribe with speaker labels

Get a token immediately before making the request:

```js
const grant = await fetch(process.env.DEEPGRAM_TOKEN_URL, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.DEEPGRAM_REFRESH_TOKEN}` },
});
if (!grant.ok) throw new Error(`Token refused: ${grant.status}`);
const { access_token } = await grant.json();

const response = await fetch(
  `${process.env.DEEPGRAM_BASE_URL}/v1/listen?model=nova-3&diarize=true&utterances=true&smart_format=true`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${access_token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ url: "https://example.com/meeting.wav" }),
  },
);
if (!response.ok) throw new Error(`Transcription failed: ${response.status}`);
console.log(await response.json());
```

The token lasts 30 seconds and uses `Authorization: Bearer`. It is not a permanent
Deepgram API key. Binary audio and WebSocket connections also go directly to
Deepgram. Fetch a new token before each new request or connection; grants are limited
to one per resource per five seconds. An expired token requires a new grant.

## Credit and resuming access

Usage is polled every minute, subject to Deepgram's reporting delay. Actual provider
cost, including any selected features, is deducted from the same balance as other
resources. If credit runs out, token issuance returns 402. Add credit or increase
the exhausted budget cap and request a token again: the refresh credential stays
unchanged. A manually suspended resource must also be resumed by its operator.

If billing or usage reconciliation is unavailable, token issuance pauses until it
recovers. It does not fall back to free access.

Token expiry prevents new connections; **it does not disconnect an existing
WebSocket**. In-flight work and provider reporting delays may exceed the remaining
credit. This integration does not promise an immediate cutoff of active streams or
a strict provider-side spending cap.

Removing the resource permanently revokes its parent key. Removal is separate from
the reversible pause that happens when credit runs out.

---

More for agents: [Docs index](https://extraorbital.dev/sitemap.md) · [llms.txt](https://extraorbital.dev/llms.txt) · [agents.md](https://extraorbital.dev/agents.md)
