Skip to content

Quickstart

  1. In the dashboard, open Settings → API Keys and choose Create API key.

    Name it after the system that will use it, so you know what breaks if you ever revoke it. Then tick the permissions it needs. For this quickstart:

    • Read account (account:read)
    • Send messages (messages:send)

    Grant the least it needs. You can add scopes later without replacing the key.

    The key is shown once and never again. Nothing anywhere stores it, only a hash of it, so copy it now.

  2. Before sending anything, make the call that cannot go wrong.

    Terminal window
    curl https://k-message.kerneltics.com/v1/me \
    -H "Authorization: Bearer km_live_YOUR_KEY"
    Response
    {
    "organization": { "id": "8f3a...", "name": "Zaiti Auto Parts", "slug": "zaiti" },
    "api_key": {
    "name": "Orders service",
    "prefix": "km_live_a1b2c3d4",
    "scopes": ["account:read", "messages:send"],
    "rate_limit_per_min": 600
    },
    "whatsapp_accounts": [
    {
    "name": "Main",
    "display_phone_number": "+966 51 021 5213",
    "is_default_outgoing": true,
    "quality_rating": "GREEN"
    }
    ]
    }

    This call reaches the database, so a 200 means the key is real, active and scoped correctly. It cannot send anything or change anything, which is why it is the right first call: when an integration is misconfigured, this is what says so, before a failed send has confused matters.

    If it fails, the body names the reason. See Errors.

  3. Whether you can send free text depends on the 24-hour window. If the person has messaged your business in the last 24 hours, a text message goes through:

    Terminal window
    curl https://k-message.kerneltics.com/v1/messages \
    -H "Authorization: Bearer km_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: order-1001-shipped" \
    -d '{
    "to": "+966500000000",
    "type": "text",
    "text": { "body": "Your order has shipped." }
    }'
    Response 201
    {
    "id": "6f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
    "contact_id": "3f2a...",
    "to": "+966500000000",
    "from": "Main",
    "type": "text",
    "direction": "outgoing",
    "status": "pending",
    "content": "Your order has shipped.",
    "created_at": "2026-08-20T09:15:00Z"
    }

    If the person has not messaged you in the last 24 hours, this returns a failure and you need an approved template instead. See Send a template message.

  4. Two ways, and you want the second one in production.

    Read the message back, using the id from the response:

    Terminal window
    curl https://k-message.kerneltics.com/v1/messages/6f1c2d3e-... \
    -H "Authorization: Bearer km_live_YOUR_KEY"

    The status moves pendingsentdeliveredread, or lands on failed with an error_message explaining why.

    Or subscribe to webhooks, so the outcome arrives at your server without polling. Create one in Settings → Webhooks, tick message.delivered, message.read and message.failed, and read Receive messages.

  • Send a template message — required outside the 24-hour window, which in practice means most notifications.
  • Receive messages — get replies and delivery receipts pushed to you.
  • Errors — every code, what causes it, and what to do.
  • Going live — the checklist before you point production at this.