API Documentation

Trigger AI phone calls from your code, automation platform, or CRM. Receive a webhook when each call completes with transcript, summary, and cost.

Authentication

All API requests require an API key. Create one in your profile settings under Integrations.

Pass your key in the X-API-Key header:

curl https://api.mio.gg/api/v1/me \
  -H "X-API-Key: sk_live_your_key_here"

API keys carry your full account permissions. Keep them secret — don't commit them to version control or expose them in client-side code.

Profile

Returns your account info. Useful for verifying your API key works.

GET https://api.mio.gg/api/v1/me

Returns your user profile. No request body needed.

Response

{
  "id": "a1b2c3d4-...",
  "name": "Jane",
  "phoneNumber": "+15551234567",
  "balance": 450
}

The balance field is in cents. 450 = $4.50.


Make a call

Initiate an AI phone call. Mio calls the number, follows your instructions, and delivers results via webhook when done.

POST https://api.mio.gg/api/v1/calls

Creates and initiates a phone call. Returns 201 with the call object.

Request body

Parameter Description
phoneNumber required Phone number in E.164 format (e.g. +15551234567)
instructions required What the AI should accomplish on the call. Max 5,000 characters.
firstMessage optional The first thing the AI says when the call connects. Max 1,000 characters.
callAt optional ISO 8601 UTC timestamp to schedule the call (e.g. 2026-03-21T14:00:00Z). Omit for immediate.
name optional Name of the person or business being called.

Example

curl https://api.mio.gg/api/v1/calls \
  -X POST \
  -H "X-API-Key: sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+15551234567",
    "instructions": "Call Joe'\''s Pizza and order a large pepperoni for pickup at 7pm.",
    "firstMessage": "Hi, I'\''d like to place an order for pickup please."
  }'

Response 201

{
  "id": "d4e5f6a7-...",
  "status": "initiated",
  "direction": "outbound",
  "toNumber": "+15551234567",
  "fromNumber": "+15559876543",
  "instructions": "Call Joe's Pizza and order...",
  "createdAt": "2026-03-20T18:30:00.000Z"
}

For scheduled calls, status will be "scheduled" and the callAt field will be set.


Webhooks

Webhooks notify your server when a call completes. You get the transcript, summary, cost, and duration — everything you need to process the result.

Managing webhooks

GET https://api.mio.gg/api/v1/webhooks

List all your webhooks.

POST https://api.mio.gg/api/v1/webhooks

Create a webhook. Requires HTTPS URL. A signing secret is generated and returned once.

Parameter Description
url required HTTPS endpoint that will receive POST requests.
events optional Array of event types. Default: ["call.completed"]
PUT https://api.mio.gg/api/v1/webhooks/:id

Update a webhook's URL, events, or active status.

DELETE https://api.mio.gg/api/v1/webhooks/:id

Delete a webhook.

POST https://api.mio.gg/api/v1/webhooks/:id/test

Send a test payload to verify your endpoint is receiving events correctly.

Webhook payload

When a call completes, Mio sends a POST request to each active webhook:

{
  "event": "call.completed",
  "timestamp": "1711000000",
  "call": {
    "id": "d4e5f6a7-...",
    "direction": "outbound",
    "status": "completed",
    "name": "Joe's Pizza",
    "toNumber": "+15551234567",
    "fromNumber": "+15559876543",
    "instructions": "Order a large pepperoni...",
    "summary": "Ordered a large pepperoni pizza for pickup at 7pm. Total $18.50.",
    "transcript": [
      { "role": "agent", "text": "Hi, I'd like to place an order..." },
      { "role": "human", "text": "Sure, what can I get for you?" }
    ],
    "cost": 42,
    "duration": 45,
    "attempt": 1,
    "startedAt": "2026-03-20T18:30:05.000Z",
    "endedAt": "2026-03-20T18:30:50.000Z",
    "createdAt": "2026-03-20T18:30:00.000Z"
  }
}

cost is in cents, duration is in seconds.


Webhook security

Each webhook gets a signing secret (prefixed whsec_) returned when you create it. Mio signs every delivery so you can verify it came from us.

Headers

Header Description
X-Mio-Signature HMAC-SHA256 signature of the payload.
X-Mio-Timestamp Unix timestamp (seconds) of when the event was sent.
X-Mio-Event Event type, e.g. call.completed
X-Mio-Delivery Unique delivery ID (UUID).

Verifying signatures

The signature is computed as HMAC-SHA256(secret, "{timestamp}.{body}") where body is the raw JSON request body.

import crypto from 'crypto';

function verifyWebhook(secret, timestamp, body, signature) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${body}`)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Always use constant-time comparison to prevent timing attacks. Reject requests where the timestamp is more than 5 minutes old to prevent replay attacks.

Failure handling

If your endpoint returns a non-2xx status or times out (10s), Mio retries with exponential backoff up to 10 times. After 10 consecutive failures, the webhook is automatically disabled. You can re-enable it via the API.


Errors

The API uses standard HTTP status codes. Error responses include a JSON body with an error field.

Status Meaning
400 Invalid request body or parameters.
401 Missing or invalid API key.
402 Insufficient balance. Add funds to continue.
409 Conflict — e.g. a call is already active on this chat.
500 Server error. Try again or contact support.
// Example error response
{
  "error": "Insufficient balance. Please top up to make calls."
}

Ready to build?

Create your API key and make your first call in under a minute.

Get your API key

Free $5 credit on signup. No card required.