> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trychert.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> From signed-in console to a delivered iMessage in five minutes.

This guide walks you from the Chert console to a live iMessage. By the end you'll have your tenant slug, signing secret, and one phone number from your project, plus a working `curl` send.

If you'd rather hand the API to an LLM, [skip to the agent path](#hand-off-to-an-ai-agent) — copy one markdown blob from the console and paste it into Claude Code or Cursor.

## Before you begin

* A Chert account with at least one project provisioned. Ask your Chert admin if you're not sure.
* `curl` and a terminal.

## 1. Pull your credentials from the console

Open the Chert console and select the project you want to send from.

Three things you'll need, all visible from the project's sidebar:

| What               | Where to find it                                         | Example                  |
| ------------------ | -------------------------------------------------------- | ------------------------ |
| **Tenant slug**    | API keys page → "Tenant slug" column                     | `acme-7a3f`              |
| **Signing secret** | API keys page → "Reveal" on the row matching your tenant | `8f2c9d…` (32 hex chars) |
| **Phone number**   | Phone numbers page → any active line in your project     | `+14152165723`           |

<Note>
  The signing secret is shown in full only once at provisioning. If you've lost it, your admin can rotate via the API keys page — be aware rotation invalidates the previous secret immediately.
</Note>

You can also confirm your tenant identity any time:

```bash theme={null}
curl https://console.trychert.com/api/v1/whoami \
  -H "Authorization: Bearer $CHERT_SIGNING_SECRET"
```

The response includes your slug, project id, active state, and `endpoints_available`.

## 2. Send your first message

Bearer auth is the simplest mode — single-tenant accounts don't need any other header.

<CodeGroup>
  ```bash curl theme={null}
  curl https://console.trychert.com/api/v1/send \
    -H "Authorization: Bearer $CHERT_SIGNING_SECRET" \
    -H "Content-Type: application/json" \
    -d '{
      "phone": "+14155551234",
      "body": "Hi Sam — testing Chert."
    }'
  ```

  ```js Node.js theme={null}
  const res = await fetch("https://console.trychert.com/api/v1/send", {
    method: "POST",
    headers: {
      "authorization": `Bearer ${process.env.CHERT_SIGNING_SECRET}`,
      "content-type": "application/json",
    },
    body: JSON.stringify({
      phone: "+14155551234",
      body: "Hi Sam — testing Chert.",
    }),
  })
  console.log(await res.json())
  ```

  ```python Python theme={null}
  import os, requests

  r = requests.post(
      "https://console.trychert.com/api/v1/send",
      headers={
          "authorization": f"Bearer {os.environ['CHERT_SIGNING_SECRET']}",
          "content-type": "application/json",
      },
      json={"phone": "+14155551234", "body": "Hi Sam — testing Chert."},
  )
  print(r.json())
  ```
</CodeGroup>

A successful send returns:

```json Response theme={null}
{
  "status": "sent",
  "message_id": "46eb1003c8b54b7ea8f1c2b03e9a7d12",
  "lead_id": "0f2d3c1a-8b4e-4f6a-90d2-1a3b4c5d6e7f",
  "lead_created": true,
  "convo_id": "8c1a9d2e-3b4f-4a5e-b6c7-d8e9fa0b1c2d",
  "phone_line_id": "2a4b6c8d-0e1f-4a3b-8c5d-7e9f1a2b3c4d"
}
```

Treat ids as opaque strings. `message_id` is the Chert send id to reuse with message-scoped endpoints such as delivery lookup, reactions, and edits.

<Note>
  Route ids are scoped by the resource in the path: `/chats/{id}/messages` uses a `chat_id`; `/messages/{id}` and `/messages/{id}/react` use a `message_id`. In the `/send` response, `lead_id` is the chat id for chat-scoped routes. `convo_id` is kept for compatibility and is not the id to put in `/chats/{id}`.
</Note>

## 3. Confirm delivery

Look up one message by `message_id`:

```bash theme={null}
curl "https://console.trychert.com/api/v1/messages/46eb1003c8b54b7ea8f1c2b03e9a7d12" \
  -H "Authorization: Bearer $CHERT_SIGNING_SECRET"
```

You'll see status, timestamps, and the conversation it landed in.

## 4. Stream replies

Open the SSE feed in another terminal. New events arrive as `data:` lines as they happen:

```bash theme={null}
curl -N https://console.trychert.com/api/v1/events/stream \
  -H "Authorization: Bearer $CHERT_SIGNING_SECRET"
```

Reply from the recipient device. You'll see a `message.received` event within seconds.

For production, register a real webhook URL — see [Receiving replies](/api/receiving-replies).

## Hand off to an AI agent

If you're driving Chert from Claude Code, Cursor, or another agent loop:

1. In the console, open the **Documentation** tab inside your project.
2. Click **Copy markdown** at the top of the "Markdown reference" card. The blob already has your live tenant slug, signing secret, project id, and a curl example for listing your phone numbers — pre-substituted.
3. Paste it into your agent. Ask it to build whatever you want — first message, bot loop, attachment sender, group chat. Every endpoint in the blob has been verified end-to-end against this deployment.

The same Documentation tab also exposes a **Test-agent prompt** card — a self-contained brief that stands up a working iMessage bot (tapbacks, typing, attachments, contact card) in under 10 minutes. Treat the embedded credentials as sensitive.

## What's next

| Goal                                               | Read                                        |
| -------------------------------------------------- | ------------------------------------------- |
| Sign requests with HMAC for production             | [Authentication](/api/authentication)       |
| Send multi-part messages, group chats, attachments | [Create a group](/api/group-chats/create)   |
| Wire a production webhook receiver                 | [Receiving replies](/api/receiving-replies) |
| Look up an error code                              | [Errors](/api/errors)                       |

## Programmatic registration (advanced)

If you don't have a console account yet — for example, an end-user-driven agent — you can register a tenant over HTTP. See the unauthenticated `POST /api/v1/register` flow in [Authentication](/api/authentication).

## See also

* [Authentication](/api/authentication)
* [Sending](/api/sending)
* [Phone numbers](/api/phone-numbers)
