Skip to content
Documentation menu

Documentation

Official SDKs

Typed client libraries for Node.js, Python, Go, and PHP, generated from the public OpenAPI spec and kept in sync with the API.

Official SDKs wrap the same REST API with a typed client for your language. They are generated from the public OpenAPI spec, so they stay in sync with the API: the same four actions, send, verify, resend, and status, are available as methods.

Every SDK authenticates with your API key as a Bearer token and defaults to the base URL https://api.otp.com/api/v1. If your language is not listed, the REST API works everywhere.

The verify examples below apply to every channel. When a send routes to WhatsApp the response also carries an action_url: the user opens it to receive the code over chat, then you verify it with the same verifyOtp call. See WhatsApp verification.

Node.js

npm install @otp.com/sdk-node
import { Configuration, OTPApi } from '@otp.com/sdk-node';

const api = new OTPApi(new Configuration({ accessToken: process.env.OTP_API_KEY }));

// send
// clientIp = the END USER's IP from your request context (e.g. req.ip), not your server's.
const sent = await api.sendOtp({ sendRequest: { recipient: '+14155552671', locale: 'en', clientIp: '81.2.69.142' } });

// verify
const result = await api.verifyOtp({ verifyRequest: { otpId: sent.otpId, code: '123456' } });
// result.matched === true

Methods: sendOtp, verifyOtp, resendOtp, getOtpStatus.

Python

Not on PyPI yet, so install from GitHub. The distribution is otp-sdk, the import is otp_sdk:

pip install "otp-sdk @ git+https://github.com/otp-com/sdk-python@v1.1.0"
import otp_sdk

config = otp_sdk.Configuration(host="https://api.otp.com/api/v1")
config.access_token = "YOUR_API_KEY"

with otp_sdk.ApiClient(config) as client:
    api = otp_sdk.OTPApi(client)
    # client_ip = the END USER's IP from your request context, not your server's.
    sent = api.send_otp({"recipient": "+14155552671", "locale": "en", "client_ip": "81.2.69.142"})
    result = api.verify_otp({"otp_id": sent.otp_id, "code": "123456"})

Methods: send_otp, verify_otp, resend_otp, get_otp_status.

Go

go get github.com/otp-com/sdk-go
import (
    "context"
    "os"

    otp "github.com/otp-com/sdk-go"
)

client := otp.NewAPIClient(otp.NewConfiguration())
ctx := context.WithValue(context.Background(), otp.ContextAccessToken, os.Getenv("OTP_API_KEY"))

// send. SetClientIp = the END USER's IP from your request context, not your server's.
req := otp.NewSendRequest("+14155552671")
req.SetLocale("en")
req.SetClientIp("81.2.69.142")
sent, _, err := client.OTPAPI.SendOtp(ctx).SendRequest(*req).Execute()

// verify
result, _, err := client.OTPAPI.VerifyOtp(ctx).
    VerifyRequest(*otp.NewVerifyRequest(sent.GetOtpId(), "123456")).
    Execute()
// result.GetMatched() == true

Methods: SendOtp, VerifyOtp, ResendOtp, GetOtpStatus. The key travels on the context, so one client can serve several keys. Run go mod tidy after adding the import.

PHP

composer require otp-com/sdk-php
<?php
require_once __DIR__ . '/vendor/autoload.php';

use OtpCom\Sdk\Api\OTPApi;
use OtpCom\Sdk\Configuration;
use OtpCom\Sdk\Model\SendRequest;
use OtpCom\Sdk\Model\VerifyRequest;

$config = Configuration::getDefaultConfiguration()->setAccessToken(getenv('OTP_API_KEY'));
$otp = new OTPApi(new GuzzleHttp\Client(), $config);

// send. client_ip = the END USER's IP from your request context, not your server's.
$sent = $otp->sendOtp(new SendRequest([
    'recipient' => '+14155552671',
    'locale' => 'en',
    'client_ip' => '81.2.69.142',
]));

// verify
$result = $otp->verifyOtp(new VerifyRequest([
    'otp_id' => $sent->getOtpId(),
    'code' => '123456',
]));
// $result->getMatched() === true

Methods: sendOtp, verifyOtp, resendOtp, getOtpStatus. Model constructors take the wire field names (otp_id, not otpId).

More on the way

Additional SDKs and tools are being added. Building with an AI agent? The MCP server exposes the same actions as agent tools.