One-time Passcodes

Send a Code

Generate a one-time passcode and deliver it by SMS or email. You get back an otpId — the code itself never comes back through the API, so it cannot leak from your logs.
POST/v1/otp/send

Parameters

channel"sms" | "email"optional

How to deliver the code. Defaults to "sms".

phonestringoptional

Required when channel is "sms". E.164 format, e.g. +220833001234. Rejected with 400 if it is not a valid number.

emailstringoptional

Required when channel is "email".

digitsintegeroptional

Length of the code, from 4 to 8. Defaults to 6.

Supports the Idempotency-Key header.

1. By SMS

  • Situation: You want to confirm a phone number with a 6-digit code.
curl -X POST https://api.transmitinfra.com/v1/otp/send \
  -H "Authorization: Bearer $TRANSMIT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: signup-4821" \
  -d '{
    "channel": "sms",
    "phone": "+220833001234",
    "digits": 6
  }'
  • Result: The user receives “Your verification code is 418290. Valid for 5 minutes. Do not share this code with anyone.” from your workspace's sender ID, or the Transmit default if you have not set one.
{
  "data": {
    "otpId": "9c1f0b7a-4d2e-4f61-9a3c-6b0e2d81f5aa",
    "message": "OTP sent successfully"
  }
}

2. By email

  • Situation: You want to confirm an email address instead, with a shorter 4-digit code.
curl -X POST https://api.transmitinfra.com/v1/otp/send \
  -H "Authorization: Bearer $TRANSMIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "email",
    "email": "awa@example.com",
    "digits": 4
  }'
  • Result: The user receives an email titled “Your verification code” showing the code and a 5-minute expiry notice. The response has the same shape as SMS.

Resending a code

There is no resend endpoint — call send again. Each call issues a new code with a new otpId and its own 5-minute window; nothing extends an existing code. Verify against the newest otpId.

One destination can receive 3 codes back to back, then one every 20 seconds. Anything faster answers 429, so put a cooldown on your resend button.

What happens next

  • The response is 202 Accepted: delivery is queued. A carrier failure afterwards does not change the response.
  • An otp.sent webhook fires to every endpoint subscribed to it.
  • If a delay on our side holds the message past the code's 5-minute expiry, it is not sent at all rather than delivered dead. The user can ask for a new code.
  • When the user types the code in, verify it with the otpId.