Skip to main content

Sessions API

A session binds two real phone numbers to a proxy MSISDN for a bounded period. See Concepts for the state machine.

Endpoints​

MethodPathSummary
POST/v1/sessionsCreate a masking session
GET/v1/sessionsList sessions with filters
GET/v1/sessions/:idGet one session
PATCH/v1/sessions/:idUpdate metadata / extend grace period
PATCH/v1/sessions/:id/targetSwap party B without changing the proxy
POST/v1/sessions/:id/endEnd a session (enters GRACE_PERIOD)
GET/v1/sessions/verifySDK call-verification lookup
GET/v1/sessions/:id/callsList call records for one session
GET/v1/sessions/:id/smsList SMS records for one session

POST /v1/sessions​

Auth: Bearer JWT (tenant).

FieldTypeRequiredDescription
agentPhonestringyesE.164, e.g. +2348012345678
customerPhonestringyesE.164
metadataobjectnoFree-form key/value context
gracePeriodMinutesintegernoDefault 15
directionModestringnoBIDIRECTIONAL (default), A_TO_B_ONLY, B_TO_A_ONLY
maxDurationMinutesintegernoHard timeout, default 120
recordingEnabledbooleannoDefault false
consentPromptstringnoDEFAULT, CUSTOM, NONE. Must not be NONE if recording is enabled

Request

curl -X POST https://api.relavoi.com/v1/sessions \
-H "Authorization: Bearer $RELAVOI_JWT" \
-H "Content-Type: application/json" \
-d '{
"agentPhone": "+2348012345678",
"customerPhone": "+2348087654321",
"directionMode": "BIDIRECTIONAL",
"gracePeriodMinutes": 15,
"recordingEnabled": false,
"metadata": { "orderId": "DOC-1" }
}'

Response — 201 Created. The session becomes ACTIVE immediately and a proxy number is allocated.

{
"id": "5661962a-d7ad-4aea-88a0-210388e1285b",
"tenantId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"proxyNumber": "+2348000000009",
"state": "ACTIVE",
"directionMode": "BIDIRECTIONAL",
"metadata": { "orderId": "DOC-1" },
"gracePeriodMinutes": 15,
"maxDurationMinutes": 120,
"recordingEnabled": false,
"consentPrompt": "NONE",
"expiresAt": "2026-07-15T14:14:59.758Z",
"createdAt": "2026-07-15T12:14:59.758Z",
"activatedAt": "2026-07-15T12:14:59.758Z",
"endedAt": null,
"expiredAt": null,
"callCount": 0,
"lastCallAt": null
}

Errors

StatusCodeWhen
400validationBad E.164, invalid enum, or invalid recording/consent combination
429tier-session-limitTier concurrent-session quota exceeded
503pool-exhaustedNo proxy number satisfies the participant-overlap rule

GET /v1/sessions​

Auth: Bearer JWT (tenant).

QueryTypeRequiredDescription
statestringnoFilter by a single state: PENDING, ACTIVE, GRACE_PERIOD, EXPIRED, or FAILED
limitintegernoDefault 20, max 100
afterstringnoCursor from the previous page's pagination.after (a timestamp)

Request

curl "https://api.relavoi.com/v1/sessions?state=ACTIVE&limit=20" \
-H "Authorization: Bearer $RELAVOI_JWT"

Response

{
"data": [
{
"id": "5661962a-d7ad-4aea-88a0-210388e1285b",
"tenantId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"proxyNumber": "+2348000000009",
"state": "ACTIVE",
"directionMode": "BIDIRECTIONAL",
"metadata": { "orderId": "DOC-1" },
"gracePeriodMinutes": 15,
"maxDurationMinutes": 120,
"recordingEnabled": false,
"consentPrompt": "NONE",
"expiresAt": "2026-07-15T14:14:59.758Z",
"createdAt": "2026-07-15T12:14:59.758Z",
"activatedAt": "2026-07-15T12:14:59.758Z",
"endedAt": null,
"expiredAt": null,
"callCount": 0,
"lastCallAt": null
}
],
"pagination": {
"count": 1,
"after": "2026-07-13T14:56:45.562Z"
}
}

pagination.after is a timestamp cursor. When there are no more pages it is null. Pass it back as the after query parameter to fetch the next page.

Errors

StatusCodeWhen
400validationOut-of-range limit or invalid state
401unauthorizedMissing or expired JWT

GET /v1/sessions/:id​

Auth: Bearer JWT (tenant).

Path paramTypeRequiredDescription
idstringyesSession UUID

Request

curl https://api.relavoi.com/v1/sessions/5661962a-d7ad-4aea-88a0-210388e1285b \
-H "Authorization: Bearer $RELAVOI_JWT"

Response

{
"id": "5661962a-d7ad-4aea-88a0-210388e1285b",
"tenantId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"proxyNumber": "+2348000000009",
"state": "ACTIVE",
"directionMode": "BIDIRECTIONAL",
"metadata": { "orderId": "DOC-1" },
"gracePeriodMinutes": 15,
"maxDurationMinutes": 120,
"recordingEnabled": false,
"consentPrompt": "NONE",
"expiresAt": "2026-07-15T14:14:59.758Z",
"createdAt": "2026-07-15T12:14:59.758Z",
"activatedAt": "2026-07-15T12:14:59.758Z",
"endedAt": null,
"expiredAt": null,
"callCount": 0,
"lastCallAt": null
}

Errors

StatusCodeWhen
404not-foundNo session with that id under this tenant

PATCH /v1/sessions/:id​

Auth: Bearer JWT (tenant).

Update a session in place. You can merge new keys into metadata and/or adjust the grace period. When the session is already in GRACE_PERIOD, changing gracePeriodMinutes also extends expiresAt.

FieldTypeRequiredDescription
metadataobjectnoMerged (shallow) into existing metadata
gracePeriodMinutesintegernoNew grace period; extends expiresAt if in GRACE_PERIOD

Unknown fields are rejected with a 400 validation error.

Request

curl -X PATCH https://api.relavoi.com/v1/sessions/5661962a-d7ad-4aea-88a0-210388e1285b \
-H "Authorization: Bearer $RELAVOI_JWT" \
-H "Content-Type: application/json" \
-d '{ "metadata": { "note": "x" } }'

Response — the full, updated session. Note metadata is merged, not replaced.

{
"id": "5661962a-d7ad-4aea-88a0-210388e1285b",
"tenantId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"proxyNumber": "+2348000000009",
"state": "ACTIVE",
"directionMode": "BIDIRECTIONAL",
"metadata": { "note": "x", "orderId": "DOC-1" },
"gracePeriodMinutes": 15,
"maxDurationMinutes": 120,
"recordingEnabled": false,
"consentPrompt": "NONE",
"expiresAt": "2026-07-15T14:14:59.758Z",
"createdAt": "2026-07-15T12:14:59.758Z",
"activatedAt": "2026-07-15T12:14:59.758Z",
"endedAt": null,
"expiredAt": null,
"callCount": 0,
"lastCallAt": null
}

Errors

StatusCodeWhen
400validationUnknown field or bad value
404not-foundUnknown session

POST /v1/sessions/:id/end​

Auth: Bearer JWT (tenant).

Transitions the session to GRACE_PERIOD and resets expiresAt to now + gracePeriodMinutes. After the grace period, state moves to EXPIRED.

Request

curl -X POST https://api.relavoi.com/v1/sessions/5661962a-d7ad-4aea-88a0-210388e1285b/end \
-H "Authorization: Bearer $RELAVOI_JWT"

Response — the full session, now in GRACE_PERIOD.

{
"id": "5661962a-d7ad-4aea-88a0-210388e1285b",
"tenantId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"proxyNumber": "+2348000000009",
"state": "GRACE_PERIOD",
"directionMode": "BIDIRECTIONAL",
"metadata": { "note": "x", "orderId": "DOC-1" },
"gracePeriodMinutes": 15,
"maxDurationMinutes": 120,
"recordingEnabled": false,
"consentPrompt": "NONE",
"expiresAt": "2026-07-15T12:29:59.959Z",
"createdAt": "2026-07-15T12:14:59.758Z",
"activatedAt": "2026-07-15T12:14:59.758Z",
"endedAt": "2026-07-15T12:14:59.959Z",
"expiredAt": null,
"callCount": 0,
"lastCallAt": null
}

Errors

StatusCodeWhen
400session-end-failedSession already EXPIRED or FAILED
404not-foundUnknown session

GET /v1/sessions/verify​

Auth: Bearer JWT (tenant). Called by the SDK to drive the call-verification banner; not typically called by your backend directly.

The tenant is derived from the JWT. Pass the user's raw E.164 phone number as userPhone — the backend hashes it internally with the per-tenant salt to look up an active session.

QueryTypeRequiredDescription
userPhonestringyesThe user's phone in raw E.164, e.g. +2348012340001

Request

curl "https://api.relavoi.com/v1/sessions/verify?userPhone=+2348012340001" \
-H "Authorization: Bearer $RELAVOI_JWT"

Response — verified

{
"verified": true,
"sessionId": "5661962a-d7ad-4aea-88a0-210388e1285b",
"proxyNumber": "+2348000000009",
"metadata": { "orderId": "DOC-1" }
}

Response — not verified

{
"verified": false
}

Errors

StatusCodeWhen
400validationMissing or non-E.164 userPhone
401unauthorizedMissing JWT

GET /v1/sessions/:id/calls​

Auth: Bearer JWT (tenant).

List the call records belonging to a single session. Returns the standard pagination envelope. See Calls API for the shape of each call record.

QueryTypeRequiredDescription
limitintegernoDefault 50, max 200
afterstringnoCursor from the previous page's pagination.after

Request

curl https://api.relavoi.com/v1/sessions/5661962a-d7ad-4aea-88a0-210388e1285b/calls \
-H "Authorization: Bearer $RELAVOI_JWT"

Response

{
"data": [],
"pagination": {
"count": 0,
"after": null
}
}

Errors

StatusCodeWhen
404not-foundUnknown session

GET /v1/sessions/:id/sms​

Auth: Bearer JWT (tenant).

List the SMS records belonging to a single session. Same pagination envelope as the calls endpoint.

QueryTypeRequiredDescription
limitintegernoDefault 50, max 200
afterstringnoCursor from the previous page's pagination.after

Request

curl https://api.relavoi.com/v1/sessions/5661962a-d7ad-4aea-88a0-210388e1285b/sms \
-H "Authorization: Bearer $RELAVOI_JWT"

Response

{
"data": [],
"pagination": {
"count": 0,
"after": null
}
}

Errors

StatusCodeWhen
404not-foundUnknown session