Claude
Skills
Sign in
Back

sinch-verification-api

Included with Lifetime
$97 forever

Verify phone numbers via SMS, Flashcall, Phone Call, Data (seamless carrier-level), or WhatsApp with Sinch Verification API. Use when implementing user phone verification, OTP, two-factor authentication, or number ownership confirmation flows.

Backend & APIs

What this skill does


# Sinch Verification API

## Overview

The Sinch Verification API verifies phone numbers through SMS OTP, Flashcall (missed call CLI), Phone Call (spoken OTP), Data (carrier-level), and WhatsApp OTP. Used for registration, 2FA, and number ownership confirmation.

## Agent Instructions

Before generating code, gather from the user (skip any item already specified in the prompt or context):

1. **Verification method** — `sms`, `flashcall`, `callout`, `seamless`, or `whatsapp`.
2. **Approach** — SDK or direct API calls (curl/fetch/requests)?
3. **Language** — for SDK: Node.js, Python, Java, or .NET. For direct API: any language, or curl.

When the user chooses **SDK**, refer to the [sinch-sdks](../sinch-sdks/SKILL.md) skill for installation and client initialization, then to the Verification API Reference linked in Links.

When the user chooses **direct API calls**, refer to the Verification API Reference linked in Links for request/response schemas.

**Security**: See the Security section below for url fetching policy, handling inbound callback content, and credential handling.

## Getting Started

### Agent Credentials handling

Store credentials in environment variables — never hardcode application keys or secrets in commands or source code:

```bash
export SINCH_APPLICATION_KEY="your-application-key"
export SINCH_APPLICATION_SECRET="your-application-secret"
```

### Authentication

Ensure that authentication headers are properly set when making API calls. The Verification API uses **Application Key + Application Secret** (from your Sinch dashboard app), not project-level OAuth2:

```bash
-u "$SINCH_APPLICATION_KEY:$SINCH_APPLICATION_SECRET"
```

See [sinch-authentication](../sinch-authentication/SKILL.md) skill for dashboard setup.

Three auth methods are supported:

| Method | Use for |
|--------|---------|
| [Application Signed Request](https://developers.sinch.com/docs/verification/api-reference/authentication/application-signed-request.md) | Secure authentication method for production traffic |
| [Basic Auth](https://developers.sinch.com/docs/verification/api-reference/authentication/basic-authentication.md) | Simple method for prototyping and trying out API calls |
| [Public Auth](https://developers.sinch.com/docs/verification/api-reference/authentication/public-authentication.md) | Insecure environments (end user's device). Android/iOS SDK only, requires callback webhook |

Minimum auth level is configurable in the Sinch Dashboard — requests below that level are rejected. See the [Authentication Guide](https://developers.sinch.com/docs/verification/api-reference/authentication.md) for signing details.

### Base URL

- Base URL: `https://verification.api.sinch.com`
- URL path prefix: `/verification/v1/`

### SDK Setup

See [sinch-sdks](../sinch-sdks/SKILL.md) for installation and client initialization across all languages. All SDKs initialize with `applicationKey` + `applicationSecret` (not project credentials).

### Canonical Example — Start SMS Verification

```bash
# Uses Basic Auth (-u) for simplicity. Use Application Signed Requests in production.
curl -X POST \
  "https://verification.api.sinch.com/verification/v1/verifications" \
  -u "$SINCH_APPLICATION_KEY:$SINCH_APPLICATION_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{
    "identity": { "type": "number", "endpoint": "+12025550134" },
    "method": "sms"
  }'
```

Response includes `id` (verification ID), `sms.template`, `sms.interceptionTimeout`, and `_links` with localized URLs for status/report actions.

## Key Concepts

### Verification Methods

| Method | Value | Behavior |
|--------|-------|----------|
| SMS | `sms` | Sends OTP via SMS. User enters code. |
| FlashCall | `flashcall` | Missed call — caller ID is the OTP. Auto-intercepted on Android; manual entry on iOS/JS. |
| Phone Call | `callout` | PSTN call dictates an OTP code. User enters the code into the app (same flow as SMS). |
| Data | `seamless` | Carrier-level verification via mobile data. No user interaction. Requires account manager to enable. |
| WhatsApp | `whatsapp` | Sends OTP via WhatsApp message. User enters code. |

### Core Model

- **Identity**: Always `{ "type": "number", "endpoint": "+E164_NUMBER" }`
- **Verification ID**: Returned on start. Used to report code or query status.
- **Reference**: Optional unique tracking string in start request. Queryable via status endpoint.
- **Statuses**: `PENDING` | `SUCCESSFUL` | `FAIL` | `DENIED` | `ABORTED` | `ERROR`
- **Failure reasons** (most common): `Invalid code`, `Expired`, `Fraud`, `Blocked`, `Denied by callback`. Full list in the [API Reference](https://developers.sinch.com/docs/verification/api-reference/verification.md).

## API Endpoints

All endpoints documented in the [Verification API Reference](https://developers.sinch.com/docs/verification/api-reference/verification.md).

### Start Verification

`POST /verification/v1/verifications`

Set `method` to `sms`, `flashcall`, `callout`, `seamless`, or `whatsapp`. Optional fields:
- `reference` — unique tracking string, passed to all events
- `custom` — arbitrary text (max 4096 chars), passed to all events
- `Accept-Language` header — controls SMS language (default `en-US`)

Method-specific options (backend-originated signed requests only): `smsOptions`, `flashCallOptions`, `calloutOptions`, `whatsappOptions`. See the [API Reference](https://developers.sinch.com/docs/verification/api-reference/verification.md) for full schemas.

### Report Verification

Report by identity: `PUT /verification/v1/verifications/number/{endpoint}`  
Report by ID: `PUT /verification/v1/verifications/id/{id}`

Body includes `method` and a method-specific object with the user's input:
- SMS / Phone Call / WhatsApp: `{ "method": "sms", "sms": { "code": "1234" } }` (replace method name + key accordingly)
- FlashCall: `{ "method": "flashcall", "flashCall": { "cli": "+46000000000" } }` — the `cli` is the **full international caller ID** from the incoming missed call

### Get Verification Status

By ID: `GET /verification/v1/verifications/id/{id}`  
By method + number: `GET /verification/v1/verifications/{method}/number/{endpoint}`  
By reference: `GET /verification/v1/verifications/reference/{reference}`

**Note:** The by-identity endpoint requires `{method}` in the path — it is NOT `/verifications/number/{endpoint}`.

## Common Patterns

### Standard Verification Flow

1. **Start** — `POST /verification/v1/verifications` with identity + method → receive verification `id`
2. **Report** — User receives code/call → `PUT /verification/v1/verifications/id/{id}` with the code/CLI
3. **Check status** — `GET /verification/v1/verifications/id/{id}` → confirm `SUCCESSFUL`

If the code expires or verification fails, you **cannot re-report** — start a new verification.

### Webhooks (Callbacks)

For production flows, configure a callback URL in the Sinch Dashboard. The API sends:

- **VerificationRequestEvent** — fired when a verification starts. Respond with `action: allow` or `action: deny` to approve/reject.
- **VerificationResultEvent** — fired when a verification completes (success or failure). Use for logging, analytics, or triggering downstream actions.

Callbacks are signed — verify signatures using [Callback Signing](https://developers.sinch.com/docs/verification/api-reference/authentication/callback-signed-request.md).

## Gotchas and Best Practices

1. **Auth is Application Key + Secret, not OAuth2.** Do not use project-level credentials.
2. **Use Application Signed Requests in production.** Application auth protects integrity of a request
3. **Base64-decode the secret before signing.** The dashboard value is base64-encoded.
4. **FlashCall auto-intercepts on Android only.** iOS/JS users must manually enter the incoming number. Android SDK is required to intercept calls.
5. **Method availability varies by country.** SMS is the most widely available.
6. **Codes expire.** Configurable via `smsOptions.expiry`. Start a new veri

Related in Backend & APIs