openapi: 3.0.3 info: title: Prelude Lookup Verification API description: 'Prelude is a phone and email verification, transactional messaging, phone number intelligence (lookup), and anti-fraud API - "the trust layer between your signups and your business." This document models Prelude''s public REST API v2 (base https://api.prelude.dev/v2) across four products: Verify (create / check one-time passcodes over SMS, WhatsApp, RCS, Viber, and voice), Notify (transactional messaging), Lookup / Intel (phone number intelligence - line type, carrier, ported / temporary flags, CNAM), and Watch (anti-fraud risk prediction and feedback). All requests authenticate with a Bearer API key (Authorization: Bearer YOUR_API_KEY) obtained from the Prelude dashboard under All Services > Configure > Keys. Endpoint paths and request / response schemas are grounded in the live Prelude documentation at docs.prelude.so as of 2026-07-11; the Watch events (dispatch-events) endpoint is modeled from documentation references and marked accordingly.' version: '2.0' contact: name: Prelude url: https://prelude.so servers: - url: https://api.prelude.dev/v2 description: Prelude API v2 security: - bearerAuth: [] tags: - name: Verification description: Create and check one-time passcode (OTP) verifications. paths: /verification: post: operationId: createVerification tags: - Verification summary: Create or retry a verification description: Creates a new verification for a phone number or email address and dispatches a one-time passcode. If a non-expired verification already exists for the same target within the verification window, this endpoint performs a retry instead of creating a new verification. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateVerificationRequest' responses: '200': description: The created or retried verification. content: application/json: schema: $ref: '#/components/schemas/Verification' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/RateLimited' /verification/check: post: operationId: checkVerification tags: - Verification summary: Check a code description: Validates a one-time passcode submitted by an end user against an active verification for the given target. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CheckVerificationRequest' responses: '200': description: The verification check result. content: application/json: schema: $ref: '#/components/schemas/VerificationCheck' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/RateLimited' components: schemas: CheckVerificationRequest: type: object required: - target - code properties: target: $ref: '#/components/schemas/Target' code: type: string description: The one-time passcode submitted by the end user. psd2: type: object description: Transaction details for PSD2 (dynamic linking) verifications. properties: amount: type: string currency: type: string recipient: type: string VerificationCheck: type: object properties: id: type: string example: vrf_01jc0t6fwwfgfsq1md24mhyztj status: type: string enum: - success - failure - expired_or_not_found - transaction_missing - transaction_mismatch metadata: $ref: '#/components/schemas/Metadata' request_id: type: string Signals: type: object description: Anti-fraud signals gathered from the end user's device / session. properties: ip: type: string device_id: type: string device_platform: type: string enum: - android - ios - web device_model: type: string os_version: type: string app_version: type: string user_agent: type: string ja4_fingerprint: type: string is_trusted_user: type: boolean additionalProperties: true CreateVerificationRequest: type: object required: - target properties: target: $ref: '#/components/schemas/Target' options: type: object description: Optional verification settings. properties: template_id: type: string variables: type: object additionalProperties: type: string method: type: string enum: - auto - voice locale: type: string sender_id: type: string app_realm: type: object additionalProperties: true code_size: type: integer custom_code: type: string callback_url: type: string format: uri preferred_channel: type: string enum: - sms - rcs - whatsapp - viber - voice force_challenge: type: boolean additionalProperties: true signals: $ref: '#/components/schemas/Signals' metadata: $ref: '#/components/schemas/Metadata' dispatch_id: type: string description: Identifier of a dispatch created by the Prelude frontend SDK. Target: type: object required: - type - value properties: type: type: string description: The kind of target identifier. enum: - phone_number - email_address value: type: string description: An E.164 formatted phone number or an email address. example: '+30123456789' Verification: type: object properties: id: type: string example: vrf_01jc0t6fwwfgfsq1md24mhyztj status: type: string enum: - success - retry - challenged - blocked - shadow_blocked method: type: string enum: - email - message - silent - voice reason: type: string description: Populated when status is blocked or shadow_blocked. channels: type: array description: Ordered sequence of delivery channels attempted. items: type: string silent: type: object additionalProperties: true risk_factors: type: array items: type: string metadata: $ref: '#/components/schemas/Metadata' request_id: type: string Metadata: type: object properties: correlation_id: type: string maxLength: 80 description: A user-defined identifier to correlate this call with others. Error: type: object properties: code: type: string message: type: string type: type: string request_id: type: string responses: RateLimited: description: Too many requests. content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/Error' BadRequest: description: The request was invalid. content: application/json: schema: $ref: '#/components/schemas/Error' securitySchemes: bearerAuth: type: http scheme: bearer description: 'Bearer API key passed as `Authorization: Bearer YOUR_API_KEY`. Obtain keys from the Prelude dashboard under All Services > Configure > Keys.'