API reference

Verified numbers

Prove you control a recipient phone number with a one-time code, then list or remove verified numbers.

A verified number is a recipient number the workspace has proved it controls by entering a 6-digit code sent to it. Accounts that are restricted to verified numbers can only call these. The restriction itself is switched with PATCH /user/settings.

Listing needs the viewer role. Requesting a code, confirming it and deleting a number are changes under /phone-numbers, so they need admin. An API key acts as an admin.

OperationMethod and pathMinimum role
List verified numbersGET /phone-numbers/verified/allviewer
Request a verification codePOST /phone-numbers/verifiedadmin
Confirm a verification codePOST /phone-numbers/verified/confirmadmin
Delete a verified numberDELETE /phone-numbers/verified/{verified_id}admin

Limitation: The code is sent as an SMS through the operator's message provider. The default provider is mock, which sends nothing: the code is returned in the response as mock_otp so you can complete the flow in development. The mock provider is refused for codes in production. The real SMS adapters have only been tested against local fakes. See Messaging.

List verified numbers

GET /phone-numbers/verified/all

Lists the workspace's verified and pending numbers, newest first.

Auth: API key or session token. Role: viewer and up.

Request

bash
curl https://api.sevennadi.si/phone-numbers/verified/all \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
[
  {
    "id": "4b0f5e9a-2c0b-4a43-8d0f-7c5e1f1d2a90",
    "phone_number": "+919876500000",
    "status": "verified",
    "created_at": "2026-10-13T09:00:00Z",
    "humanized_created_at": "5 minutes ago",
    "verified_at": "2026-10-13T09:01:10Z"
  },
  {
    "id": "8d1a6c3e-9f5b-4f0e-b1a2-3c4d5e6f7a81",
    "phone_number": "+919876500001",
    "status": "pending",
    "created_at": "2026-10-13T09:04:00Z",
    "humanized_created_at": "1 minute ago",
    "expires_at": "2026-10-13T09:14:00Z"
  }
]

status is pending or verified. Fields without a value are left out: verified_at appears once verified, expires_at (when the code stops working) only while pending.

Request a verification code

POST /phone-numbers/verified

Sends a 6-digit code to the number. The code is valid for 10 minutes. Calling it again for a pending number sends a new code and resets the wrong-attempt count.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
phone_numberbodystringyesE.164, for example +919876500000. Spaces and hyphens are removed.
channelbodystringnosms (default) or call. Codes by voice call are not available with a real provider.

Request

bash
curl -X POST https://api.sevennadi.si/phone-numbers/verified \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"phone_number": "+919876500000"}'

Response 201 Created

json
{
  "id": "4b0f5e9a-2c0b-4a43-8d0f-7c5e1f1d2a90",
  "phone_number": "+919876500000",
  "status": "pending",
  "created_at": "2026-10-13T09:00:00Z",
  "humanized_created_at": "just now",
  "expires_at": "2026-10-13T09:10:00Z",
  "channel": "sms",
  "message": "A verification code was sent to +919876500000",
  "mock_otp": "123456"
}

mock_otp is present only when the operator's SMS provider is mock.

Rate limit: one code per number every 30 seconds, and 10 code requests per workspace per hour.

Errors

StatusMessage
400channel must be sms or call
400phone_number must be in E.164 format, e.g. +919876543210
400This phone number is already verified
429A code was just sent. Wait 30 seconds before requesting another.
429Too many verification requests. Try again in an hour.
501No SMS provider is configured for verification codes (SMS_PROVIDER) (the mock provider in production)
501Verification codes by voice call are not available; use channel sms
502The verification code could not be sent. Try again in a moment.

Confirm a verification code

POST /phone-numbers/verified/confirm

Checks the code and marks the number verified. Confirming a number that is already verified returns it unchanged.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
phone_numberbodystringyesThe number the code was sent to.
otpbodystringyesThe 6-digit code.

Request

bash
curl -X POST https://api.sevennadi.si/phone-numbers/verified/confirm \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"phone_number": "+919876500000", "otp": "123456"}'

Response 200 OK

json
{
  "id": "4b0f5e9a-2c0b-4a43-8d0f-7c5e1f1d2a90",
  "phone_number": "+919876500000",
  "status": "verified",
  "created_at": "2026-10-13T09:00:00Z",
  "humanized_created_at": "1 minute ago",
  "verified_at": "2026-10-13T09:01:10Z"
}

Rate limit: 5 wrong codes per code sent. After that, request a new code.

Errors

StatusMessage
400otp must be the 6-digit code
400phone_number must be in E.164 format, e.g. +919876543210
400The verification code has expired. Request a new one.
400Incorrect verification code. 4 attempts left.
404No verification was requested for this phone number
429Too many incorrect codes. Request a new one.

Delete a verified number

DELETE /phone-numbers/verified/{verified_id}

Removes a verified or pending number from the workspace.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
verified_idpathstring (UUID)yesThe entry's id from the list (not the phone number).

Request

bash
curl -X DELETE https://api.sevennadi.si/phone-numbers/verified/4b0f5e9a-2c0b-4a43-8d0f-7c5e1f1d2a90 \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{"message": "success", "state": "deleted"}

Errors

StatusMessage
403Your role (member) can't change phone numbers. It needs admin access; ask an owner or admin of the workspace.
404Verified phone number not found