# Quickstart

> Create a test key, make your first authenticated call, and send a (simulated) text in under five minutes.

Source: https://dev.ody.co/get-started/quickstart

This quickstart uses a **test key**, so the text you send is recorded in your inbox but never actually transmitted. Switch to a live key when you're ready.

## 1. Create a test API key

1. Sign in to [app.ody.co](https://app.ody.co/?settings=developer) as a workspace **admin or owner**.
2. Open **Settings → Developer API**.
3. Name the key (for example "Local dev"), leave every scope selected, set **Key type** to **Test**, and click **Create key**.
4. Copy the `ody_test_…` secret from the banner — it's shown exactly once.

Export it so the commands below can use it:

```bash
export ODY_API_KEY="ody_test_…"
```

## 2. Make your first call

List the phone numbers in your workspace. A `200` with your numbers means the key works.

cURL:

```bash
curl https://api.ody.co/v1/api/numbers \
  -H "Authorization: Bearer $ODY_API_KEY"
```
TypeScript:

```ts
import { Ody } from "@ody/sdk";

const ody = new Ody(process.env.ODY_API_KEY!);
const numbers = await ody.numbers.list();
console.log(numbers);
```
Python:

```python
import os
from ody import Ody

client = Ody(os.environ["ODY_API_KEY"])
print(client.numbers.list())
```

Response:

```json
{
  "numbers": [
    { "e164": "+15125550100", "type": "local", "voiceMode": "app", "status": "active" }
  ]
}
```

> **About the SDK tabs:**
The TypeScript and Python SDKs are in preview: v0.3.0 is release-ready and installable from source while the npm and PyPI releases are being set up; see [SDKs](https://dev.ody.co/sdks/overview) for availability. Every example also works as plain HTTP, so the cURL tab is always enough.

> **No numbers yet?:**
Sending a text needs at least one active number. Buy one in the app, or follow [Buy numbers and register 10DLC](https://dev.ody.co/guides/agent-phone#2-buy-a-number) — with a test key the purchase is simulated.

## 3. Send a text

Send to a phone number in E.164 format. Ody picks your sending number, creates the conversation if it doesn't exist, and threads the message.

cURL:

```bash
curl https://api.ody.co/v1/api/messages \
  -H "Authorization: Bearer $ODY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quickstart-1" \
  -d '{"to":"+15125550123","body":"Hello from the Ody API"}'
```
TypeScript:

```ts
const sent = await ody.messages.send({
  to: "+15125550123",
  body: "Hello from the Ody API",
  idempotencyKey: "quickstart-1",
});
console.log(sent.conversationId, sent.simulated); // …, true
```
Python:

```python
sent = client.messages.send(
    to="+15125550123",
    body="Hello from the Ody API",
    idempotency_key="quickstart-1",
)
print(sent["conversationId"], sent.get("simulated"))
```

The response is `201` with `"simulated": true`. Open the inbox in the app — the message is in the thread with a **simulated** delivery status.

## 4. Go live

Create a second key with **Key type → Live** (`ody_live_…`) and swap it in. Nothing else in your code changes. For US texting from a local number, your workspace must be registered for 10DLC — see [Messaging (10DLC)](https://dev.ody.co/api/messaging).

## Next steps

- Get pushed new messages instead of polling: [Webhooks](https://dev.ody.co/webhooks/overview).
- Let an AI assistant do this for you: [Connect an MCP client](https://dev.ody.co/mcp/connect).
- Understand the objects you just touched: [Core concepts](https://dev.ody.co/get-started/core-concepts).
