Preview. This site is still being built. Features, prices and terms may change, and nothing here is a binding offer. Read the preview notice

Preview. Still being built; nothing here is a binding offer. Details

E2EE relay

36 routes. Paths are relative to https://api.intersink.com/v1.

All groups

The account's backups

GET/e2ee/blobs

Needs a signed-in user (Bearer token or access_token cookie).

?purpose=backup&latest=1 → the current backup { id, size, created, completed } or null (only a finished backup is ever the latest). ?purpose=backup → every backup of the account, newest first, each with its delete_token.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
purposerequiredstring, query
latestrequiredstring, query

Response

200. data is object[]. Without latest: the account's backups. With latest=1: one backup or null.

FieldTypeDescription
idrequiredstring
statusrequiredstringOne of: "pending", "ready".
sizerequirednumber
currentrequiredbooleanThe backup a new phone restores
createdrequirednumber
completedrequirednumber
expiresrequirednumber
delete_tokenrequiredstring

Start an encrypted blob upload

POST/e2ee/blobs

Needs a signed-in user (Bearer token or access_token cookie).

Single PUT (default): { id, upload_url, expires, delete_token, status }. With resumable: true a multipart upload: { id, upload_token, delete_token, status, size, part_size, parts, expires, max_parallel }; then POST /e2ee/blobs/:id/parts and /complete. Errors: 400 BLOB_SIZE_INVALID, IDEMPOTENCY_KEY_INVALID, RESUMABLE_DISABLED; 409 IDEMPOTENCY_CONFLICT, BACKUP_IN_PROGRESS; 413 BLOB_TOO_LARGE (details.max_bytes); 429 RATE_LIMITED, UPLOAD_BUDGET_EXCEEDED (details.resets_at), TOO_MANY_PENDING_UPLOADS; 503 STORAGE_UNAVAILABLE; 507 MEDIA_STORAGE_FULL.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
Idempotency-Keystring, headerA UUID per upload; a replay with the same body answers 200 with the same blob

Request body application/json

FieldTypeDescription
sizerequirednumberExact ciphertext size in bytes (a whole number, at least 1)
purposerequiredstringOne of: "attachment", "avatar", "backup".
resumablebooleantrue: a resumable upload in parts (POST /e2ee/blobs/:id/parts, /complete) instead of one presigned PUT

Response

201. data is object (BlobCreatedDto).

FieldTypeDescription
idrequiredstring
statusrequiredstringOne of: "pending".
upload_urlstringSingle PUT: the presigned URL (PUT exactly size bytes, application/octet-stream)
upload_tokenstringResumable: the write capability for parts, complete and abort
delete_tokenstringThe sender's delete capability (DELETE with X-Delete-Token)
sizenumber
part_sizenumberBytes per part (every part but the last)
partsnumberNumber of parts
expiresrequirednumberEpoch ms: single PUT URL expiry, or the resumable upload's deadline
max_parallelnumberParts to send at once (advice)

Download link for a finished blob

GET/e2ee/blobs/{id}

Needs a signed-in user (Bearer token or access_token cookie).

{ id, url, expires, size, accept_ranges }. The URL takes Range (206 / 416) and If-Range; when it expires (403) ask again and resume at the same byte. Errors: 404 BLOB_NOT_FOUND; 409 BLOB_NOT_READY (Retry-After); 429 RATE_LIMITED; 503 STORAGE_UNAVAILABLE.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
idrequiredstring, path

Response

200. data is object (BlobLinkDto).

FieldTypeDescription
idrequiredstring
urlrequiredstringDownload URL; takes Range (206/416), expires with 403
expiresrequirednumberEpoch ms
sizerequirednumber
accept_rangesrequiredboolean

Delete a blob (sender's delete for everyone, or one's own backup)

DELETE/e2ee/blobs/{id}

Needs a signed-in user (Bearer token or access_token cookie).

Removes the object, the row and the edge copy. Idempotent: a valid token for a blob already gone answers ok. Errors: 404 BLOB_NOT_FOUND (wrong token, someone else's backup); 429 RATE_LIMITED; 503 STORAGE_UNAVAILABLE.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
idrequiredstring, path
X-Delete-Tokenstring, headerdelete_token from POST /e2ee/blobs

Response

200. data is object (BlobOkDto).

FieldTypeDescription
okrequiredboolean

Resumable blob upload: give up and drop the stored parts

POST/e2ee/blobs/{id}/abort

Needs a signed-in user (Bearer token or access_token cookie).

Errors: 404 UPLOAD_NOT_FOUND; 409 BLOB_ALREADY_READY (use DELETE).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
idrequiredstring, path

Request body application/json

FieldTypeDescription
upload_tokenrequiredstringupload_token from POST /e2ee/blobs with resumable: true At most 200 characters.

Response

200. data is object (BlobOkDto).

FieldTypeDescription
okrequiredboolean

Finish a blob upload

POST/e2ee/blobs/{id}/complete

Needs a signed-in user (Bearer token or access_token cookie).

Resumable: checks every part is stored at its exact size, then joins them. Single PUT: checks the object arrived. Safe to repeat: a ready blob answers the same body. Errors: 404 UPLOAD_NOT_FOUND; 409 BLOB_PARTS_INCOMPLETE (details: missing, wrong_size, unexpected), BLOB_NOT_UPLOADED, BLOB_SIZE_MISMATCH; 410 UPLOAD_EXPIRED.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
idrequiredstring, path

Request body application/json

FieldTypeDescription
upload_tokenstringupload_token from POST /e2ee/blobs (required for a resumable upload; a single PUT needs none) At most 200 characters.

Response

200. data is object (BlobReadyDto).

FieldTypeDescription
idrequiredstring
statusrequiredstringOne of: "ready".
sizerequirednumber
expiresrequirednumberEpoch ms when the blob expires; null for a current backup or a referenced avatar

Resumable blob upload: part URLs and the parts already stored

POST/e2ee/blobs/{id}/parts

Needs a signed-in user (Bearer token or access_token cookie).

{ upload_token, parts: [1, 2, ...] (at most 100), ttl_s?, md5? }. PUT each part to its url with the headers given and exactly size bytes; a 403 from storage means the URL expired: ask again. parts: [] after a restart answers what storage holds (uploaded). Errors: 400 BLOB_PARTS_INVALID; 404 UPLOAD_NOT_FOUND (wrong id or token); 410 UPLOAD_EXPIRED; 429 RATE_LIMITED.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
idrequiredstring, path

Request body application/json

FieldTypeDescription
upload_tokenrequiredstringupload_token from POST /e2ee/blobs with resumable: true At most 200 characters.
partsnumber[]Part numbers (1-based) to get upload URLs for, at most 100; empty: status only
ttl_snumberSeconds the part URLs live, 300..86400 (default 3600), clipped to the upload deadline
md5objectPart number → base64 MD5 of that part; signed into its URL so storage refuses a corrupted body

Response

200. data is object (BlobPartsResultDto).

FieldTypeDescription
idrequiredstring
statusrequiredstringOne of: "pending", "ready".
sizerequirednumber
part_sizerequirednumber
partsrequirednumber
uploadedrequiredobject[]Parts storage holds at their exact size
uploaded[].partrequirednumber
uploaded[].sizerequirednumber
urlsrequiredobject[]
urls[].partrequirednumber
urls[].sizerequirednumber
urls[].urlrequiredstring
urls[].methodrequiredstringOne of: "PUT".
urls[].headersrequiredobject
urls[].expiresrequirednumberEpoch ms
expiresrequirednumberEpoch ms: the upload's deadline

Stop the ring: the caller hung up, or the callee answered or declined on one device (the others stop)

POST/e2ee/calls/{call_id}/cancel

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
call_idrequiredstring, path

Request body application/json

FieldTypeDescription
reasonstringWhy the ring ends (default hangup) One of: "hangup", "timeout", "answered", "declined", "busy".

Response

200. The payload in data is not described in the spec yet.

Ring the callee's phones for a call (APNs VoIP / FCM high priority; call id and expiry only)

POST/e2ee/calls/{call_id}/ring

Needs a signed-in user (Bearer token or access_token cookie).

The call itself goes end to end encrypted as relay messages; this only rings. The push says nothing about the caller: the app shows who is calling from the decrypted call offer. Only a caller with the callee's access_key (unidentified-access key) rings, and only when neither has blocked the other; otherwise the answer is the same and nothing rings. Re-sending the same call id to the same callee rings again. Limits (429): 10 rings a minute and 60 an hour per caller, 3 in 2 minutes to the same person. Into one callee at most 6 a minute and 30 an hour ring; past that nothing rings, with the same answer. 409 CALL_ID_IN_USE: another caller or callee holds this id. 503: the block check failed, nothing rang.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
call_idrequiredstring, path

Request body application/json

FieldTypeDescription
torequiredstringThe callee's account id on this channel
access_keyrequiredstringThe callee's unidentified-access key (16 bytes, base64), the one a contact holds from the callee's profile key and uses for sealed-sender sends. Only a holder can ring the callee; with a wrong key the answer is the same and nothing rings At most 32 characters.
ttl_secondsnumberHow long it rings, 10 to 60 seconds (default 45) Minimum 10, maximum 60.
caller_blobstringOpaque caller details sealed by the app (base64url, at most 1024 characters), for the callee's ringing screen. Passed through untouched as cb in the VoIP and FCM ring push of every callee device; never logged, never stored, not sent with cancels. 400 CALLER_BLOB_INVALID when it is not base64url or too long At most 1024 characters.

Response

200. The payload in data is not described in the spec yet.

A 24-hour sealed-sender certificate for this device

GET/e2ee/certificate

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Response

200. The payload in data is not described in the spec yet.

Which push credentials are set (never the secrets)

GET/e2ee/channels/{channelId}/push

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
channelIdrequiredstring, path

Response

200. The payload in data is of type object.

Set APNs / FCM credentials and the wake alert text ("" clears)

PUT/e2ee/channels/{channelId}/push

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
channelIdrequiredstring, path

Request body application/json

FieldTypeDescription
apns_keystringAPNs .p8 key (PEM) At most 4096 characters.
fcm_service_accountstringFCM service-account JSON At most 8192 characters.
alert_titlestringWake alert title (default: channel title) At most 60 characters.
alert_bodystringWake alert body (default: New message) At most 120 characters.
apns_key_idstring
apns_team_idstring

Response

200. The payload in data is of type object.

My devices

GET/e2ee/devices

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Response

200. The payload in data is not described in the spec yet.

Register this device (first = 1; others need link_token). With no bearer: a device linked from the phone (bound link_token + provisioning_address) is registered and signed in

POST/e2ee/devices

Public: no sign-in needed.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
x-refstring, headerchannel id (required without a bearer token)

Request body application/json

FieldTypeDescription
registration_idrequirednumberMinimum 1, maximum 16380.
identity_keyrequiredstringbase64url, 33 bytes At most 64 characters.
name_ctstringencrypted device name (opaque) At most 1024 characters.
provisioning_addressstringThe provisioning address this device showed as a QR. Required with a link_token bound to it, and to register without signing in (the response then also carries tokens).
reregisterbooleanReplace every device and the identity key (lost primary). Needs a session signed in within the last 10 minutes.
device_keyobjectThis device's own signing key. Optional until the device-key grace ends, required afterwards. A keyed device is acted for only with a device token.
device_key.algrequiredstringOne of: "ed25519", "p256".
device_key.public_keyrequiredstringbase64url public key: Ed25519 32 bytes; P-256 65 bytes uncompressed (or 33 compressed) At most 96 characters.
device_key.signaturerequiredstringbase64url signature by this key over "kodkila-e2ee-device-key-v1\n<channel_id>\n<account_id>\n<registration_id>\n<alg>\n<public_key>" (P-256: raw r||s or DER) At most 128 characters.
signed_pre_keyrequiredobject
signed_pre_key.signaturerequiredstringAt most 100 characters.
signed_pre_key.idrequirednumberMinimum 0, maximum 16777215.
signed_pre_key.public_keyrequiredstringAt most 64 characters.
kyber_pre_keyrequiredobject
kyber_pre_key.idrequirednumberMinimum 0, maximum 16777215.
kyber_pre_key.public_keyrequiredstringAt most 2200 characters.
kyber_pre_key.signaturerequiredstringAt most 100 characters.
pre_keysrequiredobject[]
pre_keys[].idrequirednumberMinimum 0, maximum 16777215.
pre_keys[].public_keyrequiredstringAt most 64 characters.
kyber_pre_keysrequiredobject[]
kyber_pre_keys[].idrequirednumberMinimum 0, maximum 16777215.
kyber_pre_keys[].public_keyrequiredstringAt most 2200 characters.
kyber_pre_keys[].signaturerequiredstringAt most 100 characters.
capabilitiesobject
link_tokenstringAt most 64 characters.

Response

201. The payload in data is of type object.

Remove a device with its queue and keys

DELETE/e2ee/devices/{device_id}

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
device_idrequiredstring, path

Response

200. The payload in data is not described in the spec yet.

Add a device key to a device from before device keys (linked session of that device, or a sign-in within 10 minutes), or replace it (device token of the current key)

PUT/e2ee/devices/{device_id}/key

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
device_idrequiredstring, path

Request body application/json

FieldTypeDescription
device_keyrequiredobject
device_key.algrequiredstringOne of: "ed25519", "p256".
device_key.public_keyrequiredstringbase64url public key: Ed25519 32 bytes; P-256 65 bytes uncompressed (or 33 compressed) At most 96 characters.
device_key.signaturerequiredstringbase64url signature by this key over "kodkila-e2ee-device-key-v1\n<channel_id>\n<account_id>\n<registration_id>\n<alg>\n<public_key>" (P-256: raw r||s or DER) At most 128 characters.

Response

200. The payload in data is not described in the spec yet.

Set this device's push token (apns / apns_voip / fcm)

PUT/e2ee/devices/{device_id}/push

Needs a signed-in user (Bearer token or access_token cookie).

Optional route_tag (16 to 32 base64url characters, random, made by the client per account and device): every push to this device then carries it as rt (APNs alert, background and VoIP payloads, FCM data), so an app with several accounts on one phone routes the push to the right one. Left out, the stored tag stays. It is cleared with the device's push tokens and never logged.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
device_idrequiredstring, path

Request body application/json

FieldTypeDescription
route_tagstringRoute tag for this account on this device: 16 to 32 random base64url characters made by the client. Every push to the device carries it as rt. Left out: the stored tag stays. Example: "q3Vx9JkLm2Tz0pRw8Ya4bC"
platformrequiredstringOne of: "apns", "apns_voip", "fcm".
tokenrequiredstringAt least 8 characters, at most 4096 characters.
environmentstringOne of: "production", "sandbox".
topicstring

Response

200. The payload in data is not described in the spec yet.

Remove this device's push token (apns / apns_voip / fcm), e.g. on sign-out or when calls are turned off

DELETE/e2ee/devices/{device_id}/push

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
device_idrequiredstring, path
platformrequiredstring, queryWhich token to remove One of: "apns", "apns_voip", "fcm".

Response

200. The payload in data is not described in the spec yet.

Prove this device with its device key (signed ts + single-use nonce) → a device token for this session

POST/e2ee/devices/{device_id}/token

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
device_idrequiredstring, path

Request body application/json

FieldTypeDescription
tsrequirednumberthe device's clock, epoch ms (within 5 minutes of the server)
noncerequiredstring16 to 64 random base64url characters, never reused
signaturerequiredstringbase64url signature by the device key over "kodkila-e2ee-device-proof-v1\n<channel_id>\n<account_id>\n<device_id>\n<ts>\n<nonce>" At most 128 characters.

Response

200. The payload in data is not described in the spec yet.

A single-use 10-minute token to link a new device (device 1 only); optionally bound to the new device's provisioning address

POST/e2ee/devices/link-token

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Request body application/json

FieldTypeDescription
provisioning_addressstringBind the token to this provisioning address (the new device's QR): it then works only with that address, after the new device received the message, and lets the new device sign in without a password.

Response

200. The payload in data is not described in the spec yet.

Username → account id (30/hour; 404 when not discoverable)

POST/e2ee/directory/lookup

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Request body application/json

FieldTypeDescription
usernamerequiredstringAt least 3 characters, at most 64 characters.

Response

200. The payload in data is not described in the spec yet.

Deliveries

GET/e2ee/gateway/deliveries

Needs a signed-in user (Bearer token or access_token cookie).

Gateway: Server-Sent Events of this channel's deliveries (data: = the same JSON as the Redis e2ee:deliver channel).

Response

200. The payload in data is not described in the spec yet.

Gateway: report devices whose client proved it is there ({ devices }, each lasts 40 s); devices that disconnected go in { gone }

PUT/e2ee/gateway/live

Needs a signed-in user (Bearer token or access_token cookie).

Report a device only when its client itself sent something since the last report (an app frame or a WebSocket pong it answered), never because its socket is merely open: a suspended app keeps its socket open for minutes. Report every 25 s. A call skips its push only on a report at most 35 s old.

Request body application/json

FieldTypeDescription
devicesrequiredobject[]
devices[].account_idrequiredstring
devices[].device_idrequirednumberMinimum 1, maximum 2147483647.
goneobject[]Devices that just disconnected (no longer live, wake pushes resume at once).
gone[].account_idrequiredstring
gone[].device_idrequirednumberMinimum 1, maximum 2147483647.

Response

200. The payload in data is not described in the spec yet.

Upload pre-keys (one-time keys replace the unused ones)

PUT/e2ee/keys

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Request body application/json

FieldTypeDescription
signed_pre_keyobject
signed_pre_key.signaturerequiredstringAt most 100 characters.
signed_pre_key.idrequirednumberMinimum 0, maximum 16777215.
signed_pre_key.public_keyrequiredstringAt most 64 characters.
kyber_last_resortobject
kyber_last_resort.idrequirednumberMinimum 0, maximum 16777215.
kyber_last_resort.public_keyrequiredstringAt most 2200 characters.
kyber_last_resort.signaturerequiredstringAt most 100 characters.
pre_keysobject[]
pre_keys[].idrequirednumberMinimum 0, maximum 16777215.
pre_keys[].public_keyrequiredstringAt most 64 characters.
kyber_pre_keysobject[]
kyber_pre_keys[].idrequirednumberMinimum 0, maximum 16777215.
kyber_pre_keys[].public_keyrequiredstringAt most 2200 characters.
kyber_pre_keys[].signaturerequiredstringAt most 100 characters.

Response

200. The payload in data is not described in the spec yet.

Pre-key bundle(s); consumes one-time keys (bearer or uak)

GET/e2ee/keys/{account_id}/{device_id}

Public: no sign-in needed.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
account_idrequiredstring, path
device_idrequiredstring, path
unidentified-access-keystring, header

Response

200. The payload in data is not described in the spec yet.

Unused one-time keys of this device (replenish under 20)

GET/e2ee/keys/count

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Response

200. The payload in data is not described in the spec yet.

Queued envelopes of this device, oldest first

GET/e2ee/messages

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
limitrequiredstring, query

Response

200. The payload in data is not described in the spec yet.

Send envelopes to every device of an account (bearer or sealed sender)

PUT/e2ee/messages/{account_id}

Public: no sign-in needed.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
account_idrequiredstring, path
unidentified-access-keystring, header

Request body application/json

FieldTypeDescription
callbooleanWake with the call push (apns_voip / FCM {c:1}) instead of the message push
timestamprequirednumberMinimum 0.
onlineboolean
urgentboolean
messagesrequiredobject[]
messages[].device_idrequirednumberMinimum 1, maximum 2147483647.
messages[].registration_idrequirednumberMinimum 1, maximum 16380.
messages[].typerequirednumberOne of: 1, 3, 6, 8.
messages[].contentrequiredstringAt least 1 characters, at most 350000 characters.

Response

200. The payload in data is of type object.

Acknowledge (delete) an envelope; 404 when already gone

DELETE/e2ee/messages/{guid}

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
guidrequiredstring, path

Response

200. The payload in data is not described in the spec yet.

Store an encrypted profile version and the access key

PUT/e2ee/profile

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Request body application/json

FieldTypeDescription
uakrequiredstringbase64, 16 bytes At most 32 characters.
versionrequiredstring
commitmentrequiredstringAt most 512 characters.
name_ctstringAt most 2048 characters.
about_ctstringAt most 4096 characters.
avatar_blobstringAt most 64 characters.
unrestricted_unidentified_accessrequiredboolean

Response

200. The payload in data is not described in the spec yet.

An encrypted profile version (bearer or uak)

GET/e2ee/profile/{account_id}/{version}

Public: no sign-in needed.

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header
account_idrequiredstring, path
versionrequiredstring, path
unidentified-access-keystring, header

Response

200. The payload in data is not described in the spec yet.

New device: a one-use provisioning address (10 minutes) to show as a QR

POST/e2ee/provisioning

Public: no sign-in needed.

Parameters

NameTypeDescription
x-refstring, headerchannel id

Response

200. The payload in data is not described in the spec yet.

New device, long-poll fallback: waits up to ?timeout= s (default 25, max 55) → { body } or { body: null, expires }

GET/e2ee/provisioning/{address}

Public: no sign-in needed.

Parameters

NameTypeDescription
addressrequiredstring, path
timeoutrequiredstring, query

Response

200. The payload in data is not described in the spec yet.

Primary device: deliver the sealed provisioning message (once; the address is then burned)

PUT/e2ee/provisioning/{address}

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
addressrequiredstring, path

Request body application/json

FieldTypeDescription
bodyrequiredstringThe sealed provisioning message, base64url (at most 16384 bytes decoded)

Response

200. The payload in data is not described in the spec yet.

New device: SSE; one `provisioning.message` event { body }, then the stream ends

GET/e2ee/provisioning/{address}/stream

Public: no sign-in needed.

Parameters

NameTypeDescription
addressrequiredstring, path

Response

200. The payload in data is not described in the spec yet.

Can others find me by username?

PUT/e2ee/username/discoverable

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
x-device-tokenstring, headerdevice token (POST /e2ee/devices/:id/token); required for a device that has a device key
x-device-idstring, header

Request body application/json

FieldTypeDescription
discoverablerequiredboolean

Response

200. The payload in data is not described in the spec yet.