Skip to main content
In this tutorial, you’ll learn how to deliver a 2FA token to any mobile number and verify that token using the Telnyx v2 API. Examples are provided in curl, Node.js, Python, Ruby, Go, Java, .NET, and PHP.

Prerequisites

1

Create a Telnyx account

Sign up at telnyx.com if you don’t have an account yet.
2

Get your API key

Follow the API Keys guide to generate an API key. Set it as an environment variable:
export TELNYX_API_KEY="YOUR_API_KEY"
3

Install an SDK (optional)

If you prefer using an SDK over curl, install one for your language:
npm install telnyx
For Java and .NET, the examples use the standard HTTP client libraries included with the platform.

Methods of verification

There are currently three verification methods available:
  • sms - the verification code is sent in a custom or default templated message.
  • call - the code is spoken aloud in a custom or default templated message when the user answers the call.
  • flashcall - the verification code is embedded in the caller ID of a brief “flash” call (the call rings once and hangs up). The user’s app extracts the code automatically.

Create a verify profile

A Verify Profile contains several important configurations that you’ll use when sending 2-factor authentication messages and receiving responses. Before you send any 2FA messages, you need a profile to go with them. Each profile can have one of each verification method configured. It is recommended that if you wish to configure multiple applications, you use a different profile for each one. In the below example we will set up a verification profile that can use SMS using a selected message template and speech to text calling.

Select a message template

curl --location --request GET 'https://api.telnyx.com/v2/verify_profiles/templates' \
--header 'Authorization: Bearer YOUR_API_KEY'

Example response

{
    "data": [
        {
            "id": "0abb5b4f-459f-445a-bfcd-488998b7572d",
            "text": "Your {{app_name}} verification code is: {{code}}."
        },
        {
            "id": "2ca3f1da-5621-4aa6-ae56-df21caff79e0",
            "text": "{{code}} is your verification code for {{app_name}}."
        },
        {
            "id": "33dfb056-6c1b-40bd-920e-4243e01248a5",
            "text": "Your {{app_name}} verification code is: {{code}}. Do not share this code with anyone; our employees will never ask for the code."
        },
        {
            "id": "46acd63c-be57-4993-ae8d-0e4067ad1d57",
            "text": "Your {{app_name}} verification code is: {{code}}. This code will expire in {{default_verification_timeout_secs}} minutes."
        },
        {
            "id": "723ead5e-ada6-4c29-a962-349170866187",
            "text": "{{code}} is your verification code for {{app_name}}. This code will expire in {{default_verification_timeout_secs}} minutes."
        },
        {
            "id": "88d0781f-f4c7-4b78-8d0a-1f3e4de78b5e",
            "text": "Your {{app_name}} verification code is: {{code}}. This code will expire in {{default_verification_timeout_secs}} minutes. Do not share this code with anyone; our employees will never ask for the code."
        }
    ]
}
If not selected then the default template is “Your verification code is {code}.”
Want to use your own branded verification messages? You can now create custom templates that match your brand voice and compliance requirements.

Create a verify profile

curl --location --request POST 'https://api.telnyx.com/v2/verify_profiles' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data-raw '{
    "name": "foobar-en-v1",
    "language": "en-US",
    "sms": {
        "messaging_template_id": "0abb5b4f-459f-445a-bfcd-488998b7572d",
        "whitelisted_destinations": ["US", "CA"],
        "default_timeout_secs": 300,
        "code_length": 5
    },
    "call": {
        "default_timeout_secs": 600
    }
}'

Example response

{
    "data": {
        "id": "4900017a-e7c8-e79e-0a7c-0d98f49b09cc",
        "name": "foobar-en-v1",
        "created_at": "2024-03-27T11:45:41.292913",
        "updated_at": "2024-03-27T11:45:41.292913",
        "record_type": "verify_profile",
        "sms": {
            "messaging_template_id": "0abb5b4f-459f-445a-bfcd-488998b7572d",
            "whitelisted_destinations": ["US", "CA"],
            "default_timeout_secs": 300,
            "code_length": 5
        },
        "call": {
            "default_timeout_secs": 600
        },
        "language": "en-US"
    }
}
Don’t forget to set your TELNYX_API_KEY environment variable or replace YOUR_API_KEY in the curl examples.
Take note of the profile’s id that’s returned to you, you’ll need it to send 2FA verifications. At any time, you can access all of your created Verify Profiles by API as well. You are now ready to send 2-factor authentication messages!

Trigger a verification request

To send a verification attempt, you need the Verify Profile ID, the phone number that will receive the message, and the verification type. Choose the method that best fits your use case:
SMS verification sends a code via text message. This is the most common method with the widest global coverage.
curl -X POST \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --data '{"phone_number":"+13035551234","verify_profile_id":"4900017a-e7c8-e79e-0a7c-0d98f49b09cc"}' \
  https://api.telnyx.com/v2/verifications/sms
User experience: The user receives a text message with a numeric code (e.g., “Your verification code is: 17686”). They enter this code in your application.

Example response (all methods)

{
  "data": {
    "created_at": "2020-09-14T17:03:32.965812",
    "id": "12ade33a-21c0-473b-b055-b3c836e1c292",
    "phone_number": "+13035551234",
    "record_type": "verification",
    "status": "pending",
    "timeout_secs": 300,
    "verify_profile_id": "4900017a-e7c8-e79e-0a7c-0d98f49b09cc",
    "type": "sms",
    "updated_at": "2020-09-14T17:03:32.965812"
  }
}

Choosing the right verification method

FeatureSMSCallFlashcall
Delivery speed1–5 seconds10–20 seconds (ring + answer)2–5 seconds
User interactionRead code, type it inListen to code, type it inAutomatic (app reads caller ID)
Works on web✅ Yes✅ Yes❌ No (mobile only)
Works on landlines❌ No✅ Yes❌ No
CostPer-message ratePer-minute ratePer-call rate (very short)
Global coverageWidestWideLimited
AccessibilityGoodBest (audio)App-dependent
Best forGeneral purposeLandlines, accessibilityMobile apps with auto-read
Fallback strategy: Configure multiple methods in your verify profile. Start with SMS (fastest and widest coverage), fall back to call if SMS fails. For mobile apps, consider flashcall as a zero-friction primary method with SMS as fallback.

Verify a 2FA code

The user provides the code they received (via SMS or call). Submit it to Telnyx to verify it matches:
curl -X POST \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --data '{"code":"17686", "verify_profile_id": "4900017a-e7c8-e79e-0a7c-0d98f49b09cc"}' \
  https://api.telnyx.com/v2/verifications/by_phone_number/+13035551234/actions/verify

Example response

{
  "data": {
    "phone_number": "+13035551234",
    "response_code": "accepted"
  }
}
A response_code of "accepted" confirms the code matches. Other possible values:
Response CodeMeaning
acceptedCode is correct - verification successful
rejectedCode is incorrect
expiredVerification timed out (exceeded timeout_secs)
max_attempts_exceededToo many incorrect attempts
Telnyx Verify supports webhooks to receive instant notifications when users complete verification, eliminating the need for polling. This enables event-driven workflows for faster user experiences.Learn more: Receiving Webhooks for Telnyx Verify

Next steps

Now that you’ve completed a basic verification flow, explore these guides to build a production-ready implementation: