Skip to main content
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 — 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:
WhatWhere to find itExample
Tenant slugAPI keys page → “Tenant slug” columnacme-7a3f
Signing secretAPI keys page → “Reveal” on the row matching your tenant8f2c9d… (32 hex chars)
Phone numberPhone numbers page → any active line in your project+14152165723
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.
You can also confirm your tenant identity any time:
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.
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."
  }'
A successful send returns:
Response
{
  "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.
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}.

3. Confirm delivery

Look up one message by message_id:
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:
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.

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

GoalRead
Sign requests with HMAC for productionAuthentication
Send multi-part messages, group chats, attachmentsCreate a group
Wire a production webhook receiverReceiving replies
Look up an error codeErrors

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.

See also