Authentication

Pass the API key as a Bearer token.

All API routes live under https://notp.app/api/v1. You can authenticate with either the Authorization header or X-Api-Key.

Authorization: Bearer YOUR_API_KEY
X-Api-Key: YOUR_API_KEY

Send OTP

WhatsApp first, SMS only if the first leg fails.

nOtp stores the final delivery channel, fallback state, pricing, and verification lifecycle on a single OTP message record.

POST /api/v1/otp/send
Content-Type: application/json

{
  "recipient": "+15551234567",
  "purpose": "login",
  "code_length": 6,
  "expires_in_minutes": 5
}
{
  "message": "OTP sent successfully.",
  "data": {
    "id": "01JXYZ...",
    "status": "sent",
    "channel": "whatsapp",
    "fallback_used": false,
    "expires_at": "2026-03-31T09:25:00Z"
  }
}

Verify OTP

Verify using the returned message id and user code.

Verification updates the same record to verified, expired, or failed depending on state and retry limits.

POST /api/v1/otp/verify
Content-Type: application/json

{
  "message_id": "01JXYZ...",
  "code": "482913"
}

Account Endpoint

Read balance, package catalog, and usage counts.

Call GET /api/v1/account to get current balance, app count, API key count, and active credit packages.

Billing and Webhooks

Use hosted checkout for package purchases and balance top-ups.

The platform can sync package catalog items, create transaction-based checkout sessions, store billing events, and map successful purchases back to client balances automatically.

Flutter Package

A starter Dart package is included in this repository.

Use the package under packages/notp_flutter as a path dependency during development or publish it to your own package registry.

final client = NotpClient(
  baseUrl: 'https://your-domain.com',
  apiKey: 'YOUR_API_KEY',
);

final sent = await client.sendOtp(
  recipient: '+15551234567',
  purpose: 'login',
);

final verified = await client.verifyOtp(
  messageId: sent.id,
  code: '482913',
);