Skip to content
SIP.IO
DocsStart free

Quickstart

This quickstart walks the full inbound path: a caller dials your number, the routing brain resolves it to a call flow, the flow checks business hours and offers the caller to a queue, and an available agent is bridged.

Every step below is a real call against the public /v1 API, authenticated with an API key (x-api-key: sk_…).

You’ll want:

  • An account (your tenant). Multi-tenant and white-label accounts are described in Multi-Tenant & White-Label.
  • An API key with the schedules, queues, users, flows, and numbers scopes (or *). See Authentication.
  • A SIP domain for your account (the realm used for device authentication).
  • At least one DID (inbound number) pointed at your account, or provision one in step 5 below.
Caller → DID (number) → Call Flow
├─ timeCondition (business hours)
│ ├─ in_hours → enqueue (Support queue)
│ └─ out_of_hours → voicemail
└─ queue → available agent (bridged)
  1. Create a business-hours schedule.

    Terminal window
    curl -X POST https://api.sip.io/v1/schedules \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{
    "name": "Support hours", "timezone": "America/New_York",
    "rules": [
    { "kind": "weekly", "dow": 1, "start_time": "09:00", "end_time": "17:00" },
    { "kind": "weekly", "dow": 2, "start_time": "09:00", "end_time": "17:00" },
    { "kind": "weekly", "dow": 3, "start_time": "09:00", "end_time": "17:00" },
    { "kind": "weekly", "dow": 4, "start_time": "09:00", "end_time": "17:00" },
    { "kind": "weekly", "dow": 5, "start_time": "09:00", "end_time": "17:00" },
    { "kind": "date", "start_date": "2026-07-04", "is_closed": 1 }
    ]
    }'
    # → { "ok": true, "id": "sch_…" }

    dow is 06 (Sun–Sat). Rules replace as a full set on every write. See Business Hours for overnight intervals, date ranges, and holiday fallback.

  2. Create a queue.

    Terminal window
    curl -X POST https://api.sip.io/v1/queues \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{
    "name": "Support", "strategy": "longest_idle",
    "agent_ring_timeout_sec": 20, "max_wait_sec": 600, "wrap_up_sec": 10,
    "announce_position": 1, "moh_mode": "stream",
    "schedule_id": "sch_…",
    "timeout_dest_kind": "voicemail", "timeout_dest_id": "vm_…"
    }'
    # → { "ok": true, "id": "q_…" }

    See Queues & ACD for strategies, tiers, and the reserve/confirm fence.

  3. Create an agent and add them to the queue.

    Terminal window
    curl -X POST https://api.sip.io/v1/users \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{ "username": "1001", "display_name": "Dana", "is_agent": 1 }'
    # → { "ok": true, "id": "us_…" }
    curl -X POST https://api.sip.io/v1/queues/q_…/members \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{ "user_id": "us_…", "tier_level": 1, "mode": "static" }'
  4. Register a device for the agent.

    Terminal window
    curl -X POST https://api.sip.io/v1/devices \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{ "user_id": "us_…", "auth_username": "1001", "password": "a-strong-password", "transport": "tls" }'
    # → { "ok": true, "id": "dev_…" }

    The password is hashed to ha1 on the way in and never stored or returned in the clear. Point any softphone at your SIP domain with 1001 / the password you set. See Authentication.

  5. Build and publish the call flow.

    The flow is a JSON node-graph. This one checks hours, then offers an IVR that enqueues to Support, falling back to voicemail after hours.

    Terminal window
    curl -X POST https://api.sip.io/v1/flows \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{
    "name": "Support line", "publish": true,
    "graph": {
    "start": "hours",
    "nodes": [
    { "id": "hours", "type": "timeCondition", "data": { "kind": "timeCondition", "scheduleId": "sch_…" } },
    { "id": "welcome", "type": "menu", "data": { "kind": "menu", "promptText": "Press 1 for support", "maxDigits": 1, "timeoutSec": 5 } },
    { "id": "supQ", "type": "enqueue", "data": { "kind": "enqueue", "queueId": "q_…" } },
    { "id": "vm", "type": "voicemail", "data": { "kind": "voicemail", "mailboxId": "vm_…" } }
    ],
    "edges": [
    { "id": "e1", "source": "hours", "target": "welcome", "sourceHandle": "in_hours" },
    { "id": "e2", "source": "hours", "target": "vm", "sourceHandle": "out_of_hours" },
    { "id": "e3", "source": "welcome", "target": "supQ", "sourceHandle": "digit:1" },
    { "id": "e4", "source": "welcome", "target": "vm", "sourceHandle": "timeout" }
    ]
    }
    }'
    # → { "ok": true, "id": "flow_…", "version": 1 }

    publish: true is lint-gated: a broken graph returns 422 with the specific errors instead of going live. See Call Flows.

  6. Point your number at the flow.

    Terminal window
    curl -X POST https://api.sip.io/v1/numbers \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{ "e164": "12025550123", "dest_kind": "flow", "dest_id": "flow_…", "max_channels": 10 }'

    Already have the DID provisioned? PATCH /v1/numbers/{id} instead. See Numbers & Extensions.

  7. Bring the agent online.

    Terminal window
    curl -X POST https://api.sip.io/v1/agents/state \
    -H 'x-api-key: sk_…' -H 'content-type: application/json' \
    -d '{ "userId": "us_…", "event": "available", "queues": [{ "queueId": "q_…", "level": 1 }] }'

    See Agents & Presence.

  8. Call your number.

    • In hours: the caller hears the menu, presses 1, joins the Support queue with hold music and position announcements, and is bridged to Dana when she’s free.
    • After hours / on a holiday: the timeCondition routes straight to voicemail.
  1. the SIP signaling layer received the INVITE and asked the edge runtime /route what to do.
  2. /route matched the DID, ran admission control (CAC), and returned a flow directive.
  3. the media engine ran the flow via the /flow command loop, driven step-by-step by a per-call CallSessionEngine.
  4. The timeCondition node resolved against your schedule, the enqueue node handed the caller to the per-account PresenceEngine (the ACD brain), and the reserve→confirm→release fence bridged the agent.

Next: read Core Concepts, or jump into the guides.