Reference
API reference
Every public endpoint, its parameters, request body and answer, generated from the API itself. The base URL is https://api.spiiksi.fi.
Authenticate every request with Authorization: Bearer <key or token>; see Authentication. The same reference as an OpenAPI document, for code generators and API clients: openapi.json.
Account
/v1/accountAccount
The key's organization, its balance and prices. A cheap way to check a key works.
Response 200
Calls
/v1/callsList Calls
Parameters
| Name | Type | Description |
|---|---|---|
statusquery | "open" | "ended" | null | |
external_idquery | string | null | max 200 characters |
limitquery | integer | min 1 · max 100 · default 50 |
Response 200
array of CallOut
/v1/callsCreate Call
Start a voice or video call in which the agent and the customer each hear the other in their own language. agent_url and customer_url open the call in a browser; given only now.
A machine client (a phone bridge, a contact center) takes part instead of a browser: GET /calls/public/{id} with the key from its link's fragment (#k=) in X-Call-Key returns the WebSockets to send that side's voice to and to hear the other side on.
Request body application/json
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | The language the agent speaks and hears: a code such as en or fi.min 2 characters · max 12 characters |
agent_name | string | null | Who the customer talks to: "Acme Support", or the agent's name.max 80 characters |
customer_language | string | null | Leave out for the customer to pick when they join.min 2 characters · max 12 characters |
customer_name | string | null | The customer's name, shown to the agent.max 80 characters |
external_id | string | null | A note of the agent's own: the ticket, the order.max 200 characters |
metadata | object of string | integer | number | boolean | null | null | Handed back with every event about the call. |
video | boolean | Whether the two may see each other; the voices are translated either way.default true |
Response 201
/v1/calls/{call_id}Get Call
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string |
Response 200
/v1/calls/{call_id}/dialDial
Ring a phone from the organization's Twilio number; when it is answered, the line plays side of the call. Needs the Twilio connector.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string |
Request body application/json
| Name | Type | Description |
|---|---|---|
side | "agent" | "customer" | Which side the phone plays; usually the customer.default "customer" |
torequired | string | The phone number to ring, in international form: +358401234567. |
Response 200
/v1/calls/{call_id}/endEnd Call
End the call for both sides; translation and billing stop.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string |
Response 200
/v1/calls/{call_id}/linkNew Call Link
A new link for one side; their old one, and its microphone, stop working.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string |
Request body application/json
| Name | Type | Description |
|---|---|---|
siderequired | "agent" | "customer" | Which side's link to replace. |
Response 200
/v1/calls/{call_id}/phone-linePhone Line
A line id for a PBX to join side through Asterisk AudioSocket. A new id replaces the side's old one.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string |
Request body application/json
| Name | Type | Description |
|---|---|---|
side | "agent" | "customer" | default "customer" |
Response 200
Joining a call
/calls/public/{call_id}Join
Who the call is with, and once both languages are known, where to send this side's voice and where to hear the other side.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string | |
x-call-keyheader | string | null |
Response 200
/calls/public/{call_id}/endHang Up
The agent ends the call for both. A customer who hangs up only leaves, and can come back with the same link.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string | |
x-call-keyheader | string | null |
Response 200
/calls/public/{call_id}/meMy Settings
This side's language, name, or voice. On a new language or name the other side's page hears to reconnect, so its voice is translated into the new language; on a new voice this side's page reconnects its own.
Parameters
| Name | Type | Description |
|---|---|---|
call_idrequiredpath | string | |
x-call-keyheader | string | null |
Request body application/json
| Name | Type | Description |
|---|---|---|
language | string | null | min 2 characters · max 12 characters |
name | string | null | min 1 characters · max 80 characters |
voice | string | null | The voice the other side hears you in: alloy, coral, verse… An empty string goes back to the engine's own voice. |
Response 200
Support chats
/v1/sessionsList Sessions
Sessions, newest first; by your own reference with external_id.
Parameters
| Name | Type | Description |
|---|---|---|
statusquery | "open" | "closed" | null | |
external_idquery | string | null | max 200 characters |
limitquery | integer | min 1 · max 100 · default 50 |
Response 200
array of SessionOut
/v1/sessionsCreate Session
Open a session. customer_url is the customer's link to the chat; it is given only now.
Request body application/json
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | The language the agents read and write.min 2 characters · max 12 characters |
agent_name | string | null | Shown to the customer as who they talk to: "Acme Support".max 80 characters |
customer_language | string | null | Leave out to learn it from the customer's first message.min 2 characters · max 12 characters |
customer_name | string | null | The customer's name, shown to the agents.max 80 characters |
external_id | string | null | Your own reference: a ticket, chat or call id.max 200 characters |
metadata | object of string | integer | number | boolean | null | null | Handed back with every event about the session. |
retention_days | integer | null | Days the messages are kept.min 1 · max 365 |
Response 201
/v1/sessions/{session_id}Get Session
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Response 200
/v1/sessions/{session_id}Delete Session
Erase a session and everything said in it, for good.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Response 204
No content.
/v1/sessions/{session_id}/closeClose Session
End the session: nobody can post, and the customer's page says so. The messages are kept their retention days.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Response 200
/v1/sessions/{session_id}/customer-linkNew Customer Link
A new link for the customer; the one given before stops working.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Response 200
/v1/sessions/{session_id}/messagesList Messages
Messages after the id after, oldest first; the latest ones when after is 0.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string | |
afterquery | integer | min 0 · default 0 |
limitquery | integer | min 1 · max 200 · default 100 |
Response 200
/v1/sessions/{session_id}/messagesPost Message
Post what an agent or the customer wrote. It comes back translated for the other side: customer_text for the customer, agent_text for the agents.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Request body application/json
| Name | Type | Description |
|---|---|---|
author_name | string | null | Who wrote it, shown to the other side: the agent's own name.max 80 characters |
language | string | null | The language it is written in, when you know; detected otherwise.min 2 characters · max 12 characters |
senderrequired | "agent" | "customer" | Who wrote it: an agent or the customer. |
textrequired | string | The message, as written (up to 4,000 characters).min 1 characters · max 4000 characters |
Response 201
/v1/sessions/{session_id}/streamSession Stream
The session's events as they happen (server-sent events).
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Response 200
A stream of server-sent events (text/event-stream).
/v1/sessions/{session_id}/typingTyping
Show the other side that someone is writing.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Request body application/json
| Name | Type | Description |
|---|---|---|
author_name | string | null | max 80 characters |
senderrequired | "agent" | "customer" | Who is typing. |
Response 204
No content.
/v1/sessions/{session_id}/voicePost Voice
Post a recording of what an agent or the customer said (up to two minutes: WebM, Ogg, MP4/M4A, MP3 or WAV). Billed per minute.
Parameters
| Name | Type | Description |
|---|---|---|
session_idrequiredpath | string |
Request body multipart/form-data
| Name | Type | Description |
|---|---|---|
audiorequired | string | |
author_name | string | null | max 80 characters |
senderrequired | "agent" | "customer" |
Response 201
Text translation
/v1/translateTranslate
Translate one text, or up to 100 in one go, into target. Billed per character actually translated: text already in the target language is free.
Request body application/json
| Name | Type | Description |
|---|---|---|
context | string | null | A sentence on where the text comes from, to steer the wording: "Replies from a bicycle shop's support team".max 500 characters |
glossary | object of string | null | Your own terms and how to render them: {"Spiiksi": "Spiiksi"}. |
source | string | null | Leave out to have it detected.min 2 characters · max 12 characters |
targetrequired | string | The language to translate into: a code such as en, fi or pt-BR.min 2 characters · max 12 characters |
textrequired | string | array of string | One text, or a list of up to 100, each up to 10,000 characters (50,000 in all). |
Response 200
Live events
/v1/eventsOrg Stream
Response 200
A stream of server-sent events (text/event-stream).
OAuth
/oauth2/revokeRevoke
Revoke an access or refresh token, and with it the app's connection (RFC 7009). Answers 200 whatever the token was.
Request body application/x-www-form-urlencoded
| Name | Type | Description |
|---|---|---|
tokenrequired | string |
Response 200
JSON.
/oauth2/tokenToken
Trade a code, or a refresh token, for tokens (RFC 6749). The app authenticates with its secret (Basic or in the form), or, for a code with a PKCE challenge, with the verifier alone.
Request body application/x-www-form-urlencoded
| Name | Type | Description |
|---|---|---|
client_id | string | null | |
client_secret | string | null | |
code | string | null | |
code_verifier | string | null | |
grant_typerequired | string | |
redirect_uri | string | null | |
refresh_token | string | null |
Response 200
JSON.
Schemas
AccountOut
| Name | Type | Description |
|---|---|---|
balance | number | null | Prepaid organizations pay from this; null for the invoiced. |
currencyrequired | string | |
mode | string | "live" or "test": the mode of the key (an app is always live).default "live" |
org_idrequired | string | |
org_namerequired | string | |
scopes | array of string | What the key or app may do. |
text_rate_per_million_charactersrequired | number | Excluding VAT. |
voice_rate_per_minuterequired | number |
ApiCallCreate
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | The language the agent speaks and hears: a code such as en or fi.min 2 characters · max 12 characters |
agent_name | string | null | Who the customer talks to: "Acme Support", or the agent's name.max 80 characters |
customer_language | string | null | Leave out for the customer to pick when they join.min 2 characters · max 12 characters |
customer_name | string | null | The customer's name, shown to the agent.max 80 characters |
external_id | string | null | A note of the agent's own: the ticket, the order.max 200 characters |
metadata | object of string | integer | number | boolean | null | null | Handed back with every event about the call. |
video | boolean | Whether the two may see each other; the voices are translated either way.default true |
ApiMessageIn
| Name | Type | Description |
|---|---|---|
author_name | string | null | Who wrote it, shown to the other side: the agent's own name.max 80 characters |
language | string | null | The language it is written in, when you know; detected otherwise.min 2 characters · max 12 characters |
senderrequired | "agent" | "customer" | Who wrote it: an agent or the customer. |
textrequired | string | The message, as written (up to 4,000 characters).min 1 characters · max 4000 characters |
ApiMessageOut
| Name | Type | Description |
|---|---|---|
agent_textrequired | string | What each side reads. |
author_namerequired | string | |
created_atrequired | date-time | |
customer_textrequired | string | |
idrequired | integer | |
kindrequired | string | |
language | string | null | The language it was written or spoken in. |
senderrequired | "agent" | "customer" | |
session_idrequired | string | |
textrequired | string | As written or said. |
translations | object of string | By base language code. |
ApiMessagesOut
| Name | Type | Description |
|---|---|---|
cursorrequired | integer | The last message's id: ask for what comes after it. |
messagesrequired | array of ApiMessageOut |
CallCreated
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | |
agent_namerequired | string | |
agent_urlrequired | string | Each side's own link. Shown only now: keep them. |
created_atrequired | date-time | |
customer_language | string | null | Null until the customer picks it. |
customer_name | string | null | |
customer_urlrequired | string | |
ended_at | date-time | null | |
external_id | string | null | |
idrequired | string | |
livemode | boolean | False for a call made in test mode.default true |
metadata | object | |
statusrequired | string | 'open', or 'ended' once the agent or the API ended it. |
support_session_id | string | null | |
videorequired | boolean |
CallLinkIn
| Name | Type | Description |
|---|---|---|
siderequired | "agent" | "customer" | Which side's link to replace. |
CallLinkOut
| Name | Type | Description |
|---|---|---|
urlrequired | string | The side's new link; their old one stops working. |
CallOut
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | |
agent_namerequired | string | |
created_atrequired | date-time | |
customer_language | string | null | Null until the customer picks it. |
customer_name | string | null | |
ended_at | date-time | null | |
external_id | string | null | |
idrequired | string | |
livemode | boolean | False for a call made in test mode.default true |
metadata | object | |
statusrequired | string | 'open', or 'ended' once the agent or the API ended it. |
support_session_id | string | null | |
videorequired | boolean |
CallSettingsIn
| Name | Type | Description |
|---|---|---|
language | string | null | min 2 characters · max 12 characters |
name | string | null | min 1 characters · max 80 characters |
voice | string | null | The voice the other side hears you in: alloy, coral, verse… An empty string goes back to the engine's own voice. |
DialIn
| Name | Type | Description |
|---|---|---|
side | "agent" | "customer" | Which side the phone plays; usually the customer.default "customer" |
torequired | string | The phone number to ring, in international form: +358401234567. |
DialOut
| Name | Type | Description |
|---|---|---|
twilio_call_sidrequired | string |
ListenOut
Where this side hears the other, translated: a WebSocket at {path}?unlock={unlock}, sending WAV chunks (24 kHz mono PCM16) as binary frames and JSON text frames (captions, provenance).
| Name | Type | Description |
|---|---|---|
channel_idrequired | string | |
pathrequired | string | |
unlockrequired | string |
LiveStreamCreate
| Name | Type | Description |
|---|---|---|
event_id | string | null | Attach to an existing event in the same organization. |
languages | array of string | Languages to interpret into: captions and a voice for each. The spoken language is left out if listed.max 12 items |
namerequired | string | What the stream is, e.g. "Sunday service". Shown only to you.min 1 characters · max 200 characters |
original_captions | boolean | Captions in the spoken language too. Free while at least one language is translated (they come from its transcript); without one, billed as live captions.default true |
sample_captions | boolean | default false |
source_languagerequired | string | The language spoken on the stream, or "auto" to detect it sentence
by sentence when speakers switch languages. A known language is
recognized more accurately.min 2 characters · max 12 characters |
voice | boolean | An interpreted voice for each language too, at the interpretation price. Off, the languages are translated captions only, at the lower captions price.default false |
LiveStreamIngest
| Name | Type | Description |
|---|---|---|
audio_page_urlrequired | string | Open on the streaming computer and choose the sound input, e.g. the mixer's USB input. Nothing to install. |
rtmp | RtmpIngest | null | None until RTMP ingest is enabled on this Spiiksi installation. |
srt | SrtIngest | null | |
websocket_urlrequired | string | Send mono 16-bit little-endian PCM at 24 kHz as binary frames. |
LiveStreamOut
| Name | Type | Description |
|---|---|---|
created_atrequired | date-time | |
event_id | string | null | |
event_is_demo | boolean | default false |
event_title | string | null | |
idrequired | string | |
ingestrequired | LiveStreamIngest | |
livemoderequired | boolean | |
namerequired | string | |
on_airrequired | boolean | Sound is arriving right now. |
original_captionsrequired | boolean | |
outputsrequired | array of LiveStreamOutput | |
receiving_video | boolean | RTMP or SRT is coming in now.default false |
restreams | array of RestreamOut | Where the picture goes on to, while it comes in over RTMP or SRT. |
room | boolean | An event room's video stream, managed from the room.default false |
sample_captions | boolean | The overlay links show sample captions instead of live ones.default false |
source_languagerequired | string | |
stream_keyrequired | string | Opens the stream's sound input. Keep it private; rotate it with POST /v1/streams/{id}/key. |
video_streams | boolean | The organization's plan includes video streams (Pro and up): sending on, and a room's video.default false |
voicerequired | boolean |
LiveStreamOutput
| Name | Type | Description |
|---|---|---|
audio_ws_url | string | null | The interpreted voice: WAV packets (24 kHz mono PCM16). None for the spoken language, and for captions-only languages. |
captions_off | string | null | Why this output's captions aren't running though the sound arrives, for example no balance or card to pay for them. None while they run, or when the stream has not been on air for a while. |
captions_ws_urlrequired | string | Caption text only, as JSON frames, for your own graphics. |
channel_idrequired | string | The channel serving this output now. It can change when the stream's
languages change; output and overlay_url do not. |
languagerequired | string | A language code; "auto" for the spoken language's captions on a
stream that detects it. |
originalrequired | boolean | The spoken language's own captions, not an interpretation. |
output | string | The output's name: "original" for the spoken language, else the
language code.default "" |
overlay_urlrequired | string | A transparent page with this language's captions, for a browser
source in OBS or vMix. Add &audio=1 to play the voice as well;
style parameters are in the docs. |
LiveStreamUpdate
| Name | Type | Description |
|---|---|---|
event_id | string | null | Attach to an event; null detaches into a standalone stream. |
languages | array of string | null | The full new list. Languages kept keep their overlay links.max 12 items |
name | string | null | min 1 characters · max 200 characters |
original_captions | boolean | null | |
sample_captions | boolean | null | Show sample captions on every overlay link instead of live ones, to set the scene up before going live. Nothing is sent or billed for them. |
source_language | string | null | min 2 characters · max 12 characters |
voice | boolean | null |
PhoneLineIn
| Name | Type | Description |
|---|---|---|
side | "agent" | "customer" | default "customer" |
PhoneLineOut
| Name | Type | Description |
|---|---|---|
audiosocket_idrequired | string | Pass this to AudioSocket in the PBX's dialplan: AudioSocket(<audiosocket_id>,<host>:<port>) |
hostrequired | string | |
portrequired | integer |
RestreamOut
| Name | Type | Description |
|---|---|---|
audiorequired | "voice" | "background" | "original" | |
bitraterequired | integer | |
captionsrequired | boolean | |
enabledrequired | boolean | |
error | string | null | Why it is retrying. |
idrequired | string | |
key_hintrequired | string | The key's last characters, to tell keys apart. |
namerequired | string | |
original_volumerequired | integer | |
outputrequired | string | |
state | string | null | While on air: "connecting", "live" or "retrying"; None off air. |
urlrequired | string | |
videorequired | "source" | "1080p" | "720p" | "480p" |
RtmpIngest
| Name | Type | Description |
|---|---|---|
serverrequired | string | OBS: Settings → Stream → Service "Custom…" → Server. |
stream_keyrequired | string | OBS: Stream Key. |
urlrequired | string | Server and key in one, for encoders that take a single URL. |
SessionCreate
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | The language the agents read and write.min 2 characters · max 12 characters |
agent_name | string | null | Shown to the customer as who they talk to: "Acme Support".max 80 characters |
customer_language | string | null | Leave out to learn it from the customer's first message.min 2 characters · max 12 characters |
customer_name | string | null | The customer's name, shown to the agents.max 80 characters |
external_id | string | null | Your own reference: a ticket, chat or call id.max 200 characters |
metadata | object of string | integer | number | boolean | null | null | Handed back with every event about the session. |
retention_days | integer | null | Days the messages are kept.min 1 · max 365 |
SessionOut
| Name | Type | Description |
|---|---|---|
agent_languagerequired | string | |
agent_namerequired | string | |
closed_at | date-time | null | |
created_atrequired | date-time | |
customer_language | string | null | Null until the customer's language is known. |
customer_last_seen_at | date-time | null | |
customer_name | string | null | |
customer_url | string | null | The link that opens the chat for the customer. Only when a link is made: keep it, it can't be read back. |
external_id | string | null | |
idrequired | string | |
livemode | boolean | False for a session made in test mode.default true |
metadata | object | |
retention_days | integer | null | |
statusrequired | string |
SrtIngest
| Name | Type | Description |
|---|---|---|
urlrequired | string |
StreamOut
Where this side sends its voice: a WebSocket on the API's address, {path}?token={token}&source_id={source_id}, taking binary frames of mono 16-bit little-endian PCM at 24 kHz.
| Name | Type | Description |
|---|---|---|
channel_idrequired | string | |
pathrequired | string | |
source_idrequired | string | |
tokenrequired | string |
TranslateIn
One text, or a list translated in the same order.
| Name | Type | Description |
|---|---|---|
context | string | null | A sentence on where the text comes from, to steer the wording: "Replies from a bicycle shop's support team".max 500 characters |
glossary | object of string | null | Your own terms and how to render them: {"Spiiksi": "Spiiksi"}. |
source | string | null | Leave out to have it detected.min 2 characters · max 12 characters |
targetrequired | string | The language to translate into: a code such as en, fi or pt-BR.min 2 characters · max 12 characters |
textrequired | string | array of string | One text, or a list of up to 100, each up to 10,000 characters (50,000 in all). |
TranslateOut
| Name | Type | Description |
|---|---|---|
characters_billedrequired | integer | Characters of source text a model translated (and that were billed). |
chargedrequired | number | What the request cost, in currency, excluding VAT. |
currencyrequired | string | |
targetrequired | string | |
translationsrequired | array of TranslationOut |
TranslationOut
| Name | Type | Description |
|---|---|---|
detected_source_language | string | null | The language the text was written in. |
textrequired | string | The translation, or the text itself when it was already in the target language. |
translatedrequired | boolean | False when it was already in the target language (and cost nothing). |
TypingIn
| Name | Type | Description |
|---|---|---|
author_name | string | null | max 80 characters |
senderrequired | "agent" | "customer" | Who is typing. |
app__schemas__call__JoinOut
| Name | Type | Description |
|---|---|---|
companyrequired | string | The organization the call is with. |
ice_servers | array of object | RTCIceServer entries for the video connection. |
idrequired | string | |
listen | ListenOut | null | |
my_language | string | null | |
my_name | string | null | |
my_voice | string | null | The voice the other side hears this side in; null for the engine's own. |
other_language | string | null | |
other_name | string | null | |
readyrequired | boolean | Both languages are known and the call is open: stream and listen are given. |
rolerequired | "agent" | "customer" | Which side this key opens. |
statusrequired | string | |
stream | StreamOut | null | |
videorequired | boolean |