Skip to content

Guides / Phone API

Phone API

Manage your numbers, team, call flows, voicemail and call history from your own software.

Open Phones

Overview

The Phone API lets your own software manage your Splash Nodes business numbers: where calls are forwarded, the message callers hear first, what happens if nobody answers, and your call history. It does the same things as Phones in your workspace.

It does not make calls, send texts or buy numbers. New numbers are ordered through the basket.

API access is switched on per account by our team. If you need it, contact us. Some features (messages, showing the caller's number) can also be switched off for your account, and the limits on your account apply to the API too.

Authentication

  1. Open Phones, go to Phone API and choose Create key. Only the account owner can do this.
  2. Copy the key straight away. It starts spk_ and is shown once.
  3. Send it on every request in the Authorization header.
curl https://phone.splashnodes.com/api/v1/phone/account \
  -H "Authorization: Bearer spk_your_key"

Anyone with a key can change your forwarding, so keep keys out of websites, apps and shared code. Delete a key in Phones as soon as it is no longer needed or may have leaked; it stops working at once. Our team can also revoke keys.

All requests use HTTPS. Request and response bodies are JSON (Content-Type: application/json). Phone numbers are returned in international format, for example +441134960000; you can send them in any common UK format.

Account

GET /account returns what your account can do.

{
  "account": {
    "configured": true, "active": true, "suspended": false,
    "numbers": { "used": 1, "allowed": 1 },
    "maxCallMinutes": 60,
    "callerIdChoice": true,
    "messages": { "enabled": true, "charactersPerMonth": 3000, "charactersUsed": 412 },
    "api": { "enabled": true },
    "emergency": { "status": "not_enabled", "label": "Not enabled" }
  }
}

Numbers

GET /numbers lists your numbers. GET /numbers/{id} returns one.

{
  "id": 12,
  "number": "+441134960000",
  "label": "Main line",
  "enabled": true,
  "forwardTo": "+447700900123",
  "ringSeconds": 30,
  "whileConnecting": "ring",
  "callerIdMode": "did",
  "greetingMessageId": 4,
  "unavailableMessageId": null,
  "maxCallMinutes": 60
}

PATCH /numbers/{id} changes how a number behaves. Send only the fields you want to change:

  • forwardTo: a UK landline (01, 02, 03), mobile (07, not 070 or 076) or 080 number.
  • ringSeconds: 5 to 120.
  • whileConnecting: ring or moh (hold music).
  • callerIdMode: did shows your Splash Nodes number on your phone; caller shows the caller's number, if your account allows it.
  • greetingMessageId, unavailableMessageId: one of your messages, or null for none (connect straight away / hang up).
  • enabled: false makes callers hear busy.
  • label: a name for your own reference.
curl -X PATCH https://phone.splashnodes.com/api/v1/phone/numbers/12 \
  -H "Authorization: Bearer spk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"forwardTo": "07700 900123", "ringSeconds": 25}'

Changes take effect within about 15 seconds. You cannot change the number itself or the longest call length through the API.

Messages

Messages are spoken recordings made from text. GET /voices lists the voices you can use; GET /voices/{id}/preview returns a short sample.

POST /messages makes one:

curl -X POST https://phone.splashnodes.com/api/v1/phone/messages \
  -H "Authorization: Bearer spk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Welcome", "voiceId": "VOICE_ID",
       "text": "Thanks for calling. Please hold while we connect you."}'

Optional: settings with stability, similarity_boost, style (0 to 1) and speed (0.7 to 1.2). Each message counts its characters against your monthly allowance (see /account). The text can be up to 1,500 characters.

GET /messages lists them, GET /messages/{id}/audio returns the recording as WAV, and DELETE /messages/{id} removes one that no number is using.

Calls

GET /calls?limit=50 returns the newest calls to your numbers, up to 500 at a time. To page back, pass before with the startedAt of the oldest call you have.

{
  "calls": [{
    "id": "1728040000.42",
    "number": "+441134960000",
    "from": "+447700900456",
    "forwardedTo": "+447700900123",
    "startedAt": "2026-10-04T09:30:00.000Z",
    "answeredAt": "2026-10-04T09:30:09.000Z",
    "endedAt": "2026-10-04T09:34:12.000Z",
    "durationSeconds": 252,
    "talkSeconds": 243,
    "result": "answered"
  }]
}

result is answered, no_answer, busy or failed. from is null when the caller withheld their number. Call records are kept for 12 months.

Team

Included with Essence, Elevate and Momentum.

Each person has a 3-digit extension (100–899), voicemail, and logins for Splash Phone and SIP apps.

  • GET /users, POST /users, PATCH /users/{id}, DELETE /users/{id}
  • GET /users/{id}/login: SIP and browser-phone details. Treat the password like any other password.
  • POST /users/{id}/reset-password: new SIP password; their apps must sign in again.
curl -X POST https://phone.splashnodes.com/api/v1/phone/users \
  -H "Authorization: Bearer spk_your_key" -H "Content-Type: application/json" \
  -d '{"name": "Sam Taylor", "extension": "201", "email": "[email protected]",
       "mobile": "07700 900123", "ringMobile": true}'

Fields: name, extension, email (voicemail is emailed here), mobile, ringMobile, voicemail, voicemailPin, record (Elevate and Momentum), outbound, doNotDisturb, callerIdNumberId (which of your numbers shows when they call out). You can add as many people as your plan has users.

To make a number ring the whole team, PATCH /numbers/{id} with {"mode": "pbx"}.

Call flows

A call flow is a set of steps. Point a number at one with PATCH /numbers/{id} and {"mode": "flow", "callFlowId": 3}.

  • GET /call-flows, POST /call-flows, PUT /call-flows/{id}, DELETE /call-flows/{id}
{
  "name": "Main line",
  "graph": {
    "start": "hours",
    "nodes": {
      "hours": { "type": "hours", "schedule": { "mon": [["09:00", "17:30"]], "fri": [["09:00", "16:00"]] },
                 "holidays": ["2026-12-25"], "open": "menu", "closed": "vm" },
      "menu":  { "type": "menu", "prompt": 4, "options": { "1": "sales", "2": "vm" }, "timeout": "sales" },
      "sales": { "type": "ring", "users": [12, 13], "seconds": 25, "next": "vm" },
      "vm":    { "type": "voicemail", "user": 12 }
    }
  }
}

Step types: hours (UK time; open/closed), menu (Elevate and Momentum; prompt, options, timeout, invalid), ring (users, numbers, seconds, strategy all or order, next), queue (Momentum; queue, next), voicemail (user, optional prompt), play (prompt, next), forward (number, seconds, next), conference (Elevate and Momentum; conference) and hangup. Prompts are your message ids. A step with no next hangs up.

Queues and rooms

Included with Momentum (queues) and Elevate or Momentum (conference rooms).

  • GET/POST /queues, PUT/DELETE /queues/{id}: name, extension, strategy (ringall, rrmemory, leastrecent, fewestcalls), members (user ids), maxWait (seconds), announcePosition.
  • GET/POST /conferences, PUT/DELETE /conferences/{id}: name, extension, optional pin.

Your team dials the extension; callers reach them through a call flow.

Voicemail and recordings

  • GET /voicemail: newest first, with transcript when available.
  • GET /voicemail/{id}/audio: WAV. DELETE /voicemail/{id}.
  • GET /recordings, GET /recordings/{id}/audio, DELETE /recordings/{id} (Elevate and Momentum).

Voicemail is kept for 180 days and recordings for 90 days, then deleted. You must tell callers if calls are recorded.

Reports

Included with Momentum.

GET /reports?days=30 returns totals (calls in and out, answered, missed, average call, call charges), calls per day, per number and per person.

Webhooks

Included with Momentum.

We POST JSON to your HTTPS address when a call ends (call.ended) and when voicemail arrives (voicemail.new).

  • GET /webhooks, POST /webhooks with {"url": "https://…", "events": ["call.ended", "voicemail.new"]}, DELETE /webhooks/{id}. Up to 5. The signing secret is returned once.
POST https://your-crm.example.com/hook
X-Splash-Event: call.ended
X-Splash-Signature: sha256=5f2b…

{ "event": "call.ended", "at": "2026-10-04T09:34:13Z",
  "data": { "id": "1728040000.42", "direction": "in", "number": "+441134960000",
            "from": "+447700900456", "answeredBy": "201", "talkSeconds": 243, "result": "answered" } }

Check the signature: HMAC-SHA256 of the raw body with your secret, in hex, must equal the part after sha256=. Reply with any 2xx within 8 seconds; we don’t retry.

999

Emergency calls do not work on Splash Nodes numbers until they are enabled for your account. To enable them you must book a call with our sales team and give us the address where each number is used. Until we confirm, keep another way to call 999.

  • GET /emergency returns the status (not_enabled, requested or enabled) and the full notice.
  • POST /emergency/accept records that you have read the notice.
  • POST /emergency/request asks us to enable 999. It does not enable it by itself: you still need to book the call.

Errors

Errors return a status code and a JSON body with a plain-English error:

{ "error": "Only UK landlines (01, 02, 03), mobiles (07, not 070 or 076) and 080 numbers can be forwarded to" }
  • 400: something in the request isn't valid.
  • 401: missing, wrong or deleted key, or API access is switched off.
  • 403: the feature is switched off for your account, or the account is suspended.
  • 404: no such number, message or endpoint on your account.
  • 409: the message is still used by a number.
  • 429: too many requests (120 a minute per key), or not enough message characters left this month.

Everything done through the API is recorded in your account's activity log, marked as made through the API.

Need a hand?

Get help and support with your service, or browse all guides.