# Admin API SDK

> Drive the TeleQuick console's entire administration surface from your own code — one org-scoped API key, end-to-end types.

`@telequick/admin-sdk` is a typed TypeScript client for the same administration
API the TeleQuick console runs on. Everything you can do in the console —
agents, trunks, call records, recordings, analytics, webhooks — is callable,
with input and output types generated from the live server surface. Build your
own dashboard or backoffice on it; the console itself consumes this exact
package, so the contract cannot drift.

## Install

```sh
npm install https://artifacts.clutchcall.dev/npm/tarballs/clutchcall-admin-sdk-0.1.0.tgz @trpc/client
```

(The artifacts origin is shared across brands — the same origin that serves the
[prebuilt binaries](/sdks/prebuilt-binaries).)

## Authenticate

Mint an API key in the console under **Settings → API keys**, choosing the
narrowest scopes your integration needs. A key:

* acts as the user who minted it, never exceeding what that user can do right
  now — demote or remove them and the key shrinks or stops with them;
* is pinned to one organization — naming another org is refused, not obeyed;
* carries narrow `mcp:<domain>:<action>` scopes — a key minted to read call
  records cannot create a trunk.

```ts
import { createAdminClient } from '@telequick/admin-sdk';

const admin = createAdminClient({
  baseUrl: 'https://portal.telequick.dev',
  apiKey: process.env.TELEQUICK_API_KEY!,   // mpk_…
  orgId: 'your-org-id',
});
```

## Call history, recordings, analytics

```ts
// Call history — start / end / duration / status per call, newest first.
const { rows, total } = await admin.cdr.list.query({
  orgId, limit: 50, fromMs: Date.now() - 86_400_000,
});

// Recordings — every call with a stored recording…
const recs = await admin.cdr.recordings.query({ orgId, limit: 50 });

// …and a 1-hour presigned download URL for one:
const { url } = await admin.storage.signedUrl.query({
  orgId, callSid: rows[0].call_id,
});
```

For **live** call lifecycle events (ringing, connected, ended) subscribe to
[webhooks](/modalities/voice/api/webhooks) instead of polling — the CDR surface is the
historical record, webhooks are the real-time feed.

## Voice agents

```ts
// Set the context metadata your external agent receives as ctx.job.metadata
// on every call (LiveKit transport plugin — see the LiveKit integration page):
await admin.adminAgents.updateConfig.mutate({
  orgId, agentId,
  patch: { metadata: { env: 'prod', team: 'sales' } },
});
```

## Notes

* Operations take `orgId` in their input. The client fills it in at runtime
  when omitted, but the types ask for it — pass it explicitly.
* Errors are `TRPCClientError`. `FORBIDDEN` naming a scope means the key is
  real but was minted without that authority — mint a purpose-specific key
  rather than widening an existing one.
* The account routes (sessions, passwords, identities) are excluded from the
  key-reachable surface by construction.
