VERIFICATION

Verification (OTP)

Send a one-time passcode and check it back with two calls. AtomMatrix generates and stores the code, delivers it over the fastest healthy channel, falls back automatically, and enforces expiry, retries, and rate limits — so you never store or compare raw codes yourself.

Start a verification

POST/v1/verifications
ParameterDescription
to stringREQUIREDPhone number to verify, E.164.
channel stringOPTIONALsms (default) or voice.
fallback stringOPTIONALChannel to try if the first isn't confirmed in time — e.g. voice after sms.
code_length integerOPTIONAL4–8 digits. Default 6.
expires_in integerOPTIONALSeconds until the code expires. Default 600.
locale stringOPTIONALLanguage for the message template, e.g. en, ja, es.
curl https://api.atommatrix.ai/v1/verifications \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155550123",
    "channel": "sms",
    "fallback": "voice",
    "code_length": 6,
    "expires_in": 600
  }'

Response 201 Created

{
  "id": "vrf_01HN9R4T...",
  "object": "verification",
  "to": "+14155550123",
  "channel": "sms",
  "status": "pending",
  "expires_at": "2026-07-07T12:10:00Z"
}
The code never leaves the platform. You don't receive the passcode in the response, and you never store it. That's the point — it removes an entire class of bugs and breaches from your side.

Check a code

POST/v1/verifications/check
ParameterDescription
to stringREQUIREDThe number being verified (or pass verification_id).
code stringREQUIREDThe code the user entered.
curl https://api.atommatrix.ai/v1/verifications/check \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+14155550123", "code": "481920" }'

Response

{
  "id": "vrf_01HN9R4T...",
  "object": "verification",
  "status": "approved"
}

A correct, unexpired code returns status: "approved". A wrong code returns status: "pending" (so the user can retry) and increments the attempt counter. Once the maximum attempts or the expiry is reached, the status becomes expired and you must start a new verification.

Statuses

StatusMeaning
pendingAwaiting a correct code; retries remain.
approvedVerified successfully. Terminal.
expiredToo many attempts or past expiry. Start again.

Fraud & rate controls

Verification applies velocity limits per destination number and detects patterns associated with SMS pumping and toll fraud. If a request is throttled or blocked you'll receive a 429 or a 422 with a specific error code. Tune limits and allow/deny rules in the console.

Step-up verification inside an agent

Verification is also how an AI agent proves who it's talking to before it does something sensitive. Expose verification to the agent as an approval guardrail or a tool: when a customer asks to change an address or move money, the agent starts a verification, waits for the customer to read the code back in the same SMS, voice, or chat thread, checks it, and only then calls the tool that makes the change.

// The agent starts a verification as a tool call mid-conversation:
POST /v1/verifications
{ "to": "+14155550123", "channel": "sms" }

// After the customer replies with the code, the agent checks it,
// then proceeds with the guarded action only on "approved":
POST /v1/verifications/check
{ "to": "+14155550123", "code": "481920" }
Because the code never reaches the agent's reasoning or the transcript, step-up stays secure even inside an automated conversation. See agent guardrails.