Providers / Vonage

Test Vonage SMS without sending real messages

otpmock emulates the Vonage SMS API, Messages API and Verify v2 API. In your test environment, the official @vonage/server-sdk SDK talks to otpmock instead of Vonage; your end-to-end tests read each code over HTTP.

Updated October 8, 2026Tested with the official @vonage/server-sdk SDK
Short answer

Set OTPMOCK_URL=https://api.otpmock.com in your test environment, point the Vonage client at it, and use your otpmock API key as the Vonage credential. Your application code doesn't change, and production keeps sending real SMS through Vonage.

Setup

The SDK has documented restHost and apiHost options.

sms.js
import { Vonage } from "@vonage/server-sdk";

export const vonage = new Vonage(
  {
    apiKey: process.env.VONAGE_API_KEY,
    apiSecret: process.env.VONAGE_API_SECRET,          // otpmock API key in tests
    applicationId: process.env.VONAGE_APPLICATION_ID,  // otpmock API key in tests (Verify v2)
    privateKey: process.env.VONAGE_PRIVATE_KEY,
  },
  process.env.OTPMOCK_URL ? { restHost: process.env.OTPMOCK_URL, apiHost: process.env.OTPMOCK_URL } : {},
);

Credentials. In the test environment, set VONAGE_API_SECRET to your otpmock API key (SMS and Messages APIs use Basic auth). For Verify v2, which the SDK signs with a JWT, also set VONAGE_APPLICATION_ID to your otpmock API key; otpmock reads the JWT's application_id claim and does not check the signature, so your usual private key works.

What otpmock emulates

EndpointWhat it does
POST /sms/jsonSMS API (rest.nexmo.com): send an SMS
POST /v1/messagesMessages API with channel sms and message_type text
POST /v2/verifyVerify v2: start a verification (otpmock generates the code; code_length and code are honoured)
POST /v2/verify/{request_id}Verify v2: check a code (200 completed, 400 wrong, 410 after 3 wrong attempts)
DELETE /v2/verify/{request_id}Verify v2: cancel

Responses and errors follow Vonage's own format, so the SDK parses them as usual. Authentication failures and an exhausted monthly allowance also come back in Vonage's error shape.

Phone numbers

Vonage sends numbers without a leading + (15550142). otpmock stores them as +15550142, so tests can query the E.164 form.

Read the code in your tests

signup.spec.ts
const phone = otp.randomPhone();
const since = Date.now() - 5_000;
await page.getByRole("button", { name: "Send code" }).click(); // your app calls Vonage
const { code } = await otp.waitForCode(phone, { since });

The otp helper is a single file: get it from the docs. Full walkthroughs: Playwright, Cypress.

Good to know

FAQ

Does otpmock send real SMS through Vonage?

No. In the test environment your app's Vonage requests go to otpmock, which stores the message for 10 minutes and never contacts Vonage or any carrier. Production keeps using Vonage because otpmock is only enabled when OTPMOCK_URL is set.

Is the official @vonage/server-sdk SDK supported?

Yes. otpmock's Vonage endpoints are tested end to end with the official @vonage/server-sdk package for Node.js. Other languages work too if their Vonage client lets you change the API host.

Which Vonage APIs does otpmock support?

POST /sms/json (SMS API (rest.nexmo.com): send an SMS); POST /v1/messages (Messages API with channel sms and message_type text); POST /v2/verify (Verify v2: start a verification (otpmock generates the code; code_length and code are honoured)); POST /v2/verify/{request_id} (Verify v2: check a code (200 completed, 400 wrong, 410 after 3 wrong attempts)); DELETE /v2/verify/{request_id} (Verify v2: cancel).

Test Vonage flows today

The free plan includes 100 messages a month. Using an AI coding assistant? Point it at otpmock.com/llms-full.txt.

Get a free API key

Other providers