SSoftLinkSMSDocs

Send one-time codes

Deliver login and verification codes fast, from your own sender ID, without ever sending a code twice.

One-time codes are the most time-sensitive SMS you'll send. This guide covers the three things that make them reliable: the right traffic class, safe retries, and knowing when a code arrived.

Before you start

Codes are transactional traffic, which needs approval. Check that GET /sending-profile shows sms / transactional as active; if not, see Sending access.

Send the code

Send with traffic_class: "transactional" and an Idempotency-Key that identifies this code, such as your own verification record's id:

import os
import requests

def send_code(verification_id: str, phone: str, code: str) -> dict:
    response = requests.post(
        "https://api.softlinksms.co.ke/api/v1/sms",
        headers={
            "X-Api-Key": os.environ["SOFTLINK_API_KEY"],
            "Idempotency-Key": f"otp-{verification_id}",
        },
        json={
            "recipients": [phone],
            "body": f"{code} is your Acme verification code. It expires in 5 minutes.",
            "traffic_class": "transactional",
        },
        timeout=10,
    )
    response.raise_for_status()
    return response.json()["messages"][0]

Transactional codes are sent ahead of bulk traffic, so large campaigns never delay them. The response's sender_id is the sender ID recipients see, the one approved for your account.

Retry safely

If the request times out, you can't know whether the code was sent. Retry with the same Idempotency-Key:

  • If the first request went through, you get its original response back with Idempotent-Replayed: true. Nothing is sent or charged again.
  • If it didn't, the retry sends the code.

Use a new key when the user asks for a new code. See Idempotency.

Know when it arrived

Subscribe to sms.delivered and sms.failed webhooks and match data.id to the message you sent. Handset delivery is usually confirmed within seconds.

On sms.failed, or if nothing arrives within your code's lifetime, offer the user another way in: resend, voice, or email.

Writing a good code message

  • Put the code first. Phones show the first line in notifications, and many keyboards offer to autofill it.
  • Say who it's from and when it expires. "482913 is your Acme code. It expires in 5 minutes."
  • Leave out links. Networks and users treat links in code messages as phishing.
  • Keep it under one segment. Short codes cost less and deliver faster; see Pricing and segments.

On this page