# Text your agent in 10 minutes > Create an agent in the nmbr app, then make it talk back from a terminal — with curl or the TypeScript SDK. > > Markdown mirror of https://nmbr.ai/developers/docs/quickstart-api/ — part of the nmbr Agent API docs (https://nmbr.ai/developers/docs/). Spec: https://nmbr.ai/developers/openapi.yaml · Site index: https://nmbr.ai/llms.txt You need: the nmbr app (iOS, Android or web), and a machine with outbound internet — a laptop is fine, nothing has to be reachable from the internet. ## 1. Create the agent (in the app) **[Available]** **Agents → Yours → Create an agent.** Give it a name. nmbr assigns a random `800-xxx-xxx` nmbr, adds you as its first contact, and shows its **token once**. Copy it: it starts with `agent:`. ```bash export TOKEN="agent:…" ``` > Lost it? Open the agent (Agents → Yours → your agent) and mint a new token; revoke the old one there too. ## 2. Say hello to yourself ```bash curl -s https://nmbr.ai/api/agent/v1/me -H "Authorization: Bearer $TOKEN" # {"id":"…","nmbr":"800-123-456","displayName":"My Agent",…} curl -s -X POST https://nmbr.ai/api/agent/v1/messages \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"to":"123-456-789","type":"text","content":"hello from my laptop"}' ``` Replace `123-456-789` with your own nmbr. Your phone buzzes. Reply to it in the app. ## 3. Receive the reply (long-poll) ```bash SEQ=$(curl -s https://nmbr.ai/api/agent/v1/updates/cursor -H "Authorization: Bearer $TOKEN" | jq .seq) curl -s "https://nmbr.ai/api/agent/v1/updates?afterSeq=$SEQ&wait=25" -H "Authorization: Bearer $TOKEN" ``` The request holds up to 25 s and returns as soon as something happens: ```json { "events": [ { "id": "…", "seq": 42, "type": "message.received", "ts": "…", "agentId": "…", "payload": { "conversationId": "…", "from": { "nmbr": "123-456-789", "displayName": "You" }, "message": { "id": "…", "type": "text", "content": "hi!" } } } ], "nextSeq": 42 } ``` Loop with `afterSeq=nextSeq`. That's the whole inbound story — no webhook, no tunnel. ## 4. An echo agent with the SDK **[Available]** ```bash npm i @nmbrai/sdk ``` ```ts import { NmbrAgent } from "@nmbrai/sdk"; const agent = new NmbrAgent({ token: process.env.TOKEN! }); for await (const event of agent.updates()) { // long-polls forever, resumes after errors if (event.type === "message.received") { const { conversationId, message } = event.payload as any; await agent.setTyping(conversationId); await agent.sendText({ conversationId }, `You said: ${message.content}`); } } ``` Run it with `node --env-file=.env echo.mjs` (Node ≥ 18). Text your agent. It answers. Swap the echo for an LLM call and you have a personal assistant on your phone that runs on your hardware. Voice notes arrive with `message.transcript` already filled in. ## 5. Ask before acting **[Available]** ```ts const decision = await agent.proposeAndWait({ to: "123-456-789", kind: "deploy", title: "Deploy v2 to prod?", payload: { ref: "abc123" }, }); if (decision.state === "approved") deploy(decision.editedPayload ?? decision.payload); // "rejected" and "expired" both mean: do not act. ``` Your phone shows an approval card with **Approve / Edit / Reject**. Nothing runs on nmbr's side — ever. See [Approvals](/developers/docs/approvals/). ## Next - Skip the typing: the [agent template](/developers/docs/template/) has all of the above as runnable files (`npm run echo`, `npm run agent`, `npm run approvals`, `npm run webhook`). - Prefer push over polling? [Set a webhook](/developers/docs/events/#webhooks) — deliveries are signed, and the SDK's `receiveWebhook` verifies them by default. - Read [Security](/developers/docs/security/) before you give an agent real powers. - [API reference](/developers/docs/reference/) for everything else: conversations, history, reactions, read receipts, profile.