# Quickstart

Point your client at your operator's API URL (`ORDAN_API_URL`; local default
`http://localhost:4000`). The SDK/CLI packages are not yet published — until
a release is announced, do not assume a similarly named public package is
ORDan's client.

## Agent runtime: human pairing

Pairing gives an agent runtime its own credential under a human-approved
policy and budget. The CLI opens the device flow and prints a pairing
URL/code; the human signs in, chooses organization/policy/budget, and
approves:

```bash
ordan agents connect --name "Executive Assistant"
```

For direct integration, `POST /v1/oauth/device/authorize`:

```json
{
  "agent_name": "Executive Assistant",
  "requested_capabilities": ["numbers.provision", "voice.outbound", "sms.send", "sms.receive", "policy.check", "usage.read", "events.read"],
  "spend_limit_cents": 2500
}
```

Send the human `verification_uri_complete` and `user_code`. Poll
`POST /v1/oauth/token` with
`grant_type: urn:ietf:params:oauth:grant-type:device_code` and the secret
`device_code`, respecting the returned interval. Handle
`authorization_pending`, `slow_down`, `access_denied`, and `expired_token`.
Keep the credential in the runtime's secret store — never in a prompt or
conversation.

## Owner-authorized server integration

An owner creates a project key in the console. `agents:write` creates
agents; **`grants:write` additionally delegates authority under the owner's
policy** — without it, agent creation does not mint a grant.

```ts
import { Ordan } from "@ordan/sdk";
const client = new Ordan({ apiKey: process.env.ORDAN_API_KEY,
  baseUrl: process.env.ORDAN_API_URL });
const agent = await client.agents.create({ name: "Executive Assistant" });
const line = await client.lines.create({ agent: agent.id, country: "US" });
// Real carrier orders may return provisioning. Poll lines.retrieve(line.id)
// until active before using it; do not purchase another number to retry.
```

With an agent credential, omit `agent` — the agent acts as itself. A
project key names the agent when placing calls/texts. Every action needs a
live grant, pinned policy, Line binding, and sufficient budgets.

## Check, act, observe

An agent with `policy.check` can POST `/v1/policies/check`:

```json
{"action":"sms.send","to":"+12125550101","body":"Appointment confirmed."}
```

This reports policy, segment and cost estimates; it does not authorize or
reserve anything. Execute with `POST /v1/calls` or `/v1/messages`, one
stable `Idempotency-Key` per logical operation. On `approval_required`,
show the returned `apr_…` to the human, then retry with that `approval`
in the body and a **new** key (the body changed).

Poll calls/messages or subscribe to signed events. See
[errors](errors.md) for blocked/pending recovery and
[webhooks](webhooks.md) for delivery.

A call's `objective` is context and audit data: ORDan does not synthesize
speech or supply intelligence. Connect your own runtime for that.
