Documentation menu

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

get/v1/account

Account

The key's organization, its balance and prices. A cheap way to check a key works.

Response 200

AccountOut

Calls

get/v1/calls

List Calls

Parameters

NameTypeDescription
statusquery"open" | "ended" | null
external_idquerystring | nullmax 200 characters
limitqueryintegermin 1 · max 100 · default 50

Response 200

array of CallOut

post/v1/calls

Create 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

NameTypeDescription
agent_languagerequiredstringThe language the agent speaks and hears: a code such as en or fi.min 2 characters · max 12 characters
agent_namestring | nullWho the customer talks to: "Acme Support", or the agent's name.max 80 characters
customer_languagestring | nullLeave out for the customer to pick when they join.min 2 characters · max 12 characters
customer_namestring | nullThe customer's name, shown to the agent.max 80 characters
external_idstring | nullA note of the agent's own: the ticket, the order.max 200 characters
metadataobject of string | integer | number | boolean | null | nullHanded back with every event about the call.
videobooleanWhether the two may see each other; the voices are translated either way.default true

Response 201

CallCreated

get/v1/calls/{call_id}

Get Call

Parameters

NameTypeDescription
call_idrequiredpathstring

Response 200

CallOut

post/v1/calls/{call_id}/dial

Dial

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

NameTypeDescription
call_idrequiredpathstring

Request body application/json

NameTypeDescription
side"agent" | "customer"Which side the phone plays; usually the customer.default "customer"
torequiredstringThe phone number to ring, in international form: +358401234567.

Response 200

DialOut

post/v1/calls/{call_id}/end

End Call

End the call for both sides; translation and billing stop.

Parameters

NameTypeDescription
call_idrequiredpathstring

Response 200

CallOut

post/v1/calls/{call_id}/link

New Call Link

A new link for one side; their old one, and its microphone, stop working.

Parameters

NameTypeDescription
call_idrequiredpathstring

Request body application/json

NameTypeDescription
siderequired"agent" | "customer"Which side's link to replace.

Response 200

CallLinkOut

post/v1/calls/{call_id}/phone-line

Phone Line

A line id for a PBX to join side through Asterisk AudioSocket. A new id replaces the side's old one.

Parameters

NameTypeDescription
call_idrequiredpathstring

Request body application/json

NameTypeDescription
side"agent" | "customer"default "customer"

Response 200

PhoneLineOut

Joining a call

get/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

NameTypeDescription
call_idrequiredpathstring
x-call-keyheaderstring | null

Response 200

app__schemas__call__JoinOut

post/calls/public/{call_id}/end

Hang Up

The agent ends the call for both. A customer who hangs up only leaves, and can come back with the same link.

Parameters

NameTypeDescription
call_idrequiredpathstring
x-call-keyheaderstring | null

Response 200

app__schemas__call__JoinOut

patch/calls/public/{call_id}/me

My Settings

This side's language, or name. The other side's page hears to reconnect, so its voice is translated into the new language.

Parameters

NameTypeDescription
call_idrequiredpathstring
x-call-keyheaderstring | null

Request body application/json

NameTypeDescription
languagestring | nullmin 2 characters · max 12 characters
namestring | nullmin 1 characters · max 80 characters

Response 200

app__schemas__call__JoinOut

Support chats

get/v1/sessions

List Sessions

Sessions, newest first; by your own reference with external_id.

Parameters

NameTypeDescription
statusquery"open" | "closed" | null
external_idquerystring | nullmax 200 characters
limitqueryintegermin 1 · max 100 · default 50

Response 200

array of SessionOut

post/v1/sessions

Create Session

Open a session. customer_url is the customer's link to the chat; it is given only now.

Request body application/json

NameTypeDescription
agent_languagerequiredstringThe language the agents read and write.min 2 characters · max 12 characters
agent_namestring | nullShown to the customer as who they talk to: "Acme Support".max 80 characters
customer_languagestring | nullLeave out to learn it from the customer's first message.min 2 characters · max 12 characters
customer_namestring | nullThe customer's name, shown to the agents.max 80 characters
external_idstring | nullYour own reference: a ticket, chat or call id.max 200 characters
metadataobject of string | integer | number | boolean | null | nullHanded back with every event about the session.
retention_daysinteger | nullDays the messages are kept.min 1 · max 365

Response 201

SessionOut

get/v1/sessions/{session_id}

Get Session

Parameters

NameTypeDescription
session_idrequiredpathstring

Response 200

SessionOut

delete/v1/sessions/{session_id}

Delete Session

Erase a session and everything said in it, for good.

Parameters

NameTypeDescription
session_idrequiredpathstring

Response 204

No content.

post/v1/sessions/{session_id}/close

Close Session

End the session: nobody can post, and the customer's page says so. The messages are kept their retention days.

Parameters

NameTypeDescription
session_idrequiredpathstring

Response 200

SessionOut

post/v1/sessions/{session_id}/customer-link

New Customer Link

A new link for the customer; the one given before stops working.

Parameters

NameTypeDescription
session_idrequiredpathstring

Response 200

SessionOut

get/v1/sessions/{session_id}/messages

List Messages

Messages after the id after, oldest first; the latest ones when after is 0.

Parameters

NameTypeDescription
session_idrequiredpathstring
afterqueryintegermin 0 · default 0
limitqueryintegermin 1 · max 200 · default 100

Response 200

ApiMessagesOut

post/v1/sessions/{session_id}/messages

Post 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

NameTypeDescription
session_idrequiredpathstring

Request body application/json

NameTypeDescription
author_namestring | nullWho wrote it, shown to the other side: the agent's own name.max 80 characters
languagestring | nullThe 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.
textrequiredstringThe message, as written (up to 4,000 characters).min 1 characters · max 4000 characters

Response 201

ApiMessageOut

get/v1/sessions/{session_id}/stream

Session Stream

The session's events as they happen (server-sent events).

Parameters

NameTypeDescription
session_idrequiredpathstring

Response 200

A stream of server-sent events (text/event-stream).

post/v1/sessions/{session_id}/typing

Typing

Show the other side that someone is writing.

Parameters

NameTypeDescription
session_idrequiredpathstring

Request body application/json

NameTypeDescription
author_namestring | nullmax 80 characters
senderrequired"agent" | "customer"Who is typing.

Response 204

No content.

post/v1/sessions/{session_id}/voice

Post 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

NameTypeDescription
session_idrequiredpathstring

Request body multipart/form-data

NameTypeDescription
audiorequiredstring
author_namestring | nullmax 80 characters
senderrequired"agent" | "customer"

Response 201

ApiMessageOut

Text translation

post/v1/translate

Translate

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

NameTypeDescription
contextstring | nullA sentence on where the text comes from, to steer the wording: "Replies from a bicycle shop's support team".max 500 characters
glossaryobject of string | nullYour own terms and how to render them: {"Spiiksi": "Spiiksi"}.
sourcestring | nullLeave out to have it detected.min 2 characters · max 12 characters
targetrequiredstringThe language to translate into: a code such as en, fi or pt-BR.min 2 characters · max 12 characters
textrequiredstring | array of stringOne text, or a list of up to 100, each up to 10,000 characters (50,000 in all).

Response 200

TranslateOut

Live events

get/v1/events

Org Stream

Response 200

A stream of server-sent events (text/event-stream).

OAuth

get/.well-known/oauth-authorization-server

Metadata

Where everything is (RFC 8414).

Response 200

JSON.

post/oauth2/revoke

Revoke

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

NameTypeDescription
tokenrequiredstring

Response 200

JSON.

post/oauth2/token

Token

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

NameTypeDescription
client_idstring | null
client_secretstring | null
codestring | null
code_verifierstring | null
grant_typerequiredstring
redirect_uristring | null
refresh_tokenstring | null

Response 200

JSON.

Schemas

AccountOut

NameTypeDescription
balancenumber | nullPrepaid organizations pay from this; null for the invoiced.
currencyrequiredstring
modestring"live" or "test": the mode of the key (an app is always live).default "live"
org_idrequiredstring
org_namerequiredstring
scopesarray of stringWhat the key or app may do.
text_rate_per_million_charactersrequirednumberExcluding VAT.
voice_rate_per_minuterequirednumber

ApiCallCreate

NameTypeDescription
agent_languagerequiredstringThe language the agent speaks and hears: a code such as en or fi.min 2 characters · max 12 characters
agent_namestring | nullWho the customer talks to: "Acme Support", or the agent's name.max 80 characters
customer_languagestring | nullLeave out for the customer to pick when they join.min 2 characters · max 12 characters
customer_namestring | nullThe customer's name, shown to the agent.max 80 characters
external_idstring | nullA note of the agent's own: the ticket, the order.max 200 characters
metadataobject of string | integer | number | boolean | null | nullHanded back with every event about the call.
videobooleanWhether the two may see each other; the voices are translated either way.default true

ApiMessageIn

NameTypeDescription
author_namestring | nullWho wrote it, shown to the other side: the agent's own name.max 80 characters
languagestring | nullThe 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.
textrequiredstringThe message, as written (up to 4,000 characters).min 1 characters · max 4000 characters

ApiMessageOut

NameTypeDescription
agent_textrequiredstringWhat each side reads.
author_namerequiredstring
created_atrequireddate-time
customer_textrequiredstring
idrequiredinteger
kindrequiredstring
languagestring | nullThe language it was written or spoken in.
senderrequired"agent" | "customer"
session_idrequiredstring
textrequiredstringAs written or said.
translationsobject of stringBy base language code.

ApiMessagesOut

NameTypeDescription
cursorrequiredintegerThe last message's id: ask for what comes after it.
messagesrequiredarray of ApiMessageOut

CallCreated

NameTypeDescription
agent_languagerequiredstring
agent_namerequiredstring
agent_urlrequiredstringEach side's own link. Shown only now: keep them.
created_atrequireddate-time
customer_languagestring | nullNull until the customer picks it.
customer_namestring | null
customer_urlrequiredstring
ended_atdate-time | null
external_idstring | null
idrequiredstring
livemodebooleanFalse for a call made in test mode.default true
metadataobject
statusrequiredstring'open', or 'ended' once the agent or the API ended it.
support_session_idstring | null
videorequiredboolean

CallLinkIn

NameTypeDescription
siderequired"agent" | "customer"Which side's link to replace.

CallLinkOut

NameTypeDescription
urlrequiredstringThe side's new link; their old one stops working.

CallOut

NameTypeDescription
agent_languagerequiredstring
agent_namerequiredstring
created_atrequireddate-time
customer_languagestring | nullNull until the customer picks it.
customer_namestring | null
ended_atdate-time | null
external_idstring | null
idrequiredstring
livemodebooleanFalse for a call made in test mode.default true
metadataobject
statusrequiredstring'open', or 'ended' once the agent or the API ended it.
support_session_idstring | null
videorequiredboolean

CallSettingsIn

NameTypeDescription
languagestring | nullmin 2 characters · max 12 characters
namestring | nullmin 1 characters · max 80 characters

DialIn

NameTypeDescription
side"agent" | "customer"Which side the phone plays; usually the customer.default "customer"
torequiredstringThe phone number to ring, in international form: +358401234567.

DialOut

NameTypeDescription
twilio_call_sidrequiredstring

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).

NameTypeDescription
channel_idrequiredstring
pathrequiredstring
unlockrequiredstring

PhoneLineIn

NameTypeDescription
side"agent" | "customer"default "customer"

PhoneLineOut

NameTypeDescription
audiosocket_idrequiredstringPass this to AudioSocket in the PBX's dialplan: AudioSocket(<audiosocket_id>,<host>:<port>)
hostrequiredstring
portrequiredinteger

SessionCreate

NameTypeDescription
agent_languagerequiredstringThe language the agents read and write.min 2 characters · max 12 characters
agent_namestring | nullShown to the customer as who they talk to: "Acme Support".max 80 characters
customer_languagestring | nullLeave out to learn it from the customer's first message.min 2 characters · max 12 characters
customer_namestring | nullThe customer's name, shown to the agents.max 80 characters
external_idstring | nullYour own reference: a ticket, chat or call id.max 200 characters
metadataobject of string | integer | number | boolean | null | nullHanded back with every event about the session.
retention_daysinteger | nullDays the messages are kept.min 1 · max 365

SessionOut

NameTypeDescription
agent_languagerequiredstring
agent_namerequiredstring
closed_atdate-time | null
created_atrequireddate-time
customer_languagestring | nullNull until the customer's language is known.
customer_last_seen_atdate-time | null
customer_namestring | null
customer_urlstring | nullThe link that opens the chat for the customer. Only when a link is made: keep it, it can't be read back.
external_idstring | null
idrequiredstring
livemodebooleanFalse for a session made in test mode.default true
metadataobject
retention_daysinteger | null
statusrequiredstring

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.

NameTypeDescription
channel_idrequiredstring
pathrequiredstring
source_idrequiredstring
tokenrequiredstring

TranslateIn

One text, or a list translated in the same order.

NameTypeDescription
contextstring | nullA sentence on where the text comes from, to steer the wording: "Replies from a bicycle shop's support team".max 500 characters
glossaryobject of string | nullYour own terms and how to render them: {"Spiiksi": "Spiiksi"}.
sourcestring | nullLeave out to have it detected.min 2 characters · max 12 characters
targetrequiredstringThe language to translate into: a code such as en, fi or pt-BR.min 2 characters · max 12 characters
textrequiredstring | array of stringOne text, or a list of up to 100, each up to 10,000 characters (50,000 in all).

TranslateOut

NameTypeDescription
characters_billedrequiredintegerCharacters of source text a model translated (and that were billed).
chargedrequirednumberWhat the request cost, in currency, excluding VAT.
currencyrequiredstring
targetrequiredstring
translationsrequiredarray of TranslationOut

TranslationOut

NameTypeDescription
detected_source_languagestring | nullThe language the text was written in.
textrequiredstringThe translation, or the text itself when it was already in the target language.
translatedrequiredbooleanFalse when it was already in the target language (and cost nothing).

TypingIn

NameTypeDescription
author_namestring | nullmax 80 characters
senderrequired"agent" | "customer"Who is typing.

app__schemas__call__JoinOut

NameTypeDescription
companyrequiredstringThe organization the call is with.
ice_serversarray of objectRTCIceServer entries for the video connection.
idrequiredstring
listenListenOut | null
my_languagestring | null
my_namestring | null
other_languagestring | null
other_namestring | null
readyrequiredbooleanBoth languages are known and the call is open: stream and listen are given.
rolerequired"agent" | "customer"Which side this key opens.
statusrequiredstring
streamStreamOut | null
videorequiredboolean