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.