openapi: 3.2.0 info: title: Numbers Online Phone Intelligence Parsing API description: Phone number parsing, validation, and inbound caller-intelligence as a supplementary signal. version: 1.0.0 contact: name: Phone Numbers Online url: https://numbers.online servers: - url: https://numbers.online description: Production server - url: http://localhost:3000 description: Development server tags: - name: Parsing description: Phone number parsing and validation endpoints paths: /api/v1/parse: post: tags: - Parsing summary: Parse a phone number description: Parse and validate a single phone number, returning format variants, country, line type, and validity. Deterministic and free (priced $0; counted for analytics only). Requires an API key with the `parse` use case. The legacy `/api/parse` path is a frozen alias of this endpoint with a `{success:}` envelope. operationId: v1Parse security: - ApiKeyAuth: [] - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phoneNumber properties: phoneNumber: type: string description: The phone number to parse (E.164 format recommended) example: '+14155552671' defaultCountry: type: string description: Default country code (ISO 3166-1 alpha-2) for numbers without country code example: US responses: '200': description: Parsed phone number (schema_version-stamped parse row). content: application/json: schema: allOf: - type: object properties: schema_version: type: string example: '2026-06-18' - $ref: '#/components/schemas/ParsedPhoneNumber' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Authentication required content: application/json: schema: $ref: '#/components/schemas/Error' '429': $ref: '#/components/responses/RateLimited' /api/v1/parse/batch: post: tags: - Parsing summary: Parse multiple phone numbers description: 'Parse and validate up to 100 numbers in one request (named `batch` to match `/api/v1/lookup/batch`). Non-string entries return a uniform blank row with `valid: false` rather than failing the batch. Deterministic and free (priced $0). Requires the `parse` use case. The legacy `/api/parse/bulk` path is a frozen alias with a `{success:}` envelope.' operationId: v1ParseBatch security: - ApiKeyAuth: [] - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phoneNumbers properties: phoneNumbers: type: array items: type: string maxItems: 100 description: Array of phone numbers to parse example: - '+14155552671' - '+442071234567' - '+33123456789' defaultCountry: type: string description: Default country code for numbers without country code example: US responses: '200': description: Parsed phone numbers content: application/json: schema: type: object properties: schema_version: type: string example: '2026-06-19' count: type: integer results: type: array items: $ref: '#/components/schemas/ParsedPhoneNumber' summary: type: object properties: total: type: integer valid: type: integer invalid: type: integer '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Authentication required content: application/json: schema: $ref: '#/components/schemas/Error' '429': $ref: '#/components/responses/RateLimited' /api/parse: post: tags: - Parsing summary: Parse a phone number (legacy alias) deprecated: true description: Frozen permanent alias of `POST /api/v1/parse`, kept for existing integrations — same behavior, but wrapped in the legacy `{success:}` envelope. New integrations should use the v1 path. Parse and validate a single phone number, returning comprehensive information including format variants, country, type, and validity. operationId: parsePhoneNumber security: - ApiKeyAuth: [] - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phoneNumber properties: phoneNumber: type: string description: The phone number to parse (E.164 format recommended) example: '+14155552671' defaultCountry: type: string description: Default country code (ISO 3166-1 alpha-2) for numbers without country code example: US responses: '200': description: Successfully parsed phone number content: application/json: schema: $ref: '#/components/schemas/ParsedPhoneNumber' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Authentication required content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/Error' /api/parse/bulk: post: tags: - Parsing summary: Parse multiple phone numbers (legacy alias) deprecated: true description: Frozen permanent alias of `POST /api/v1/parse/batch`, kept for existing integrations — same behavior, but wrapped in the legacy `{success:}` envelope. New integrations should use the v1 path. Parse and validate multiple phone numbers in a single request. Maximum 100 numbers per request. operationId: parsePhoneNumbersBulk security: - ApiKeyAuth: [] - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phoneNumbers properties: phoneNumbers: type: array items: type: string maxItems: 100 description: Array of phone numbers to parse example: - '+14155552671' - '+442071234567' - '+33123456789' defaultCountry: type: string description: Default country code for numbers without country code example: US responses: '200': description: Successfully parsed phone numbers content: application/json: schema: type: object properties: success: type: boolean count: type: integer results: type: array items: $ref: '#/components/schemas/ParsedPhoneNumber' summary: type: object properties: total: type: integer valid: type: integer invalid: type: integer '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Authentication required content: application/json: schema: $ref: '#/components/schemas/Error' '429': $ref: '#/components/responses/RateLimited' components: schemas: Error: type: object properties: success: type: boolean example: false description: Legacy field emitted ONLY by the pre-v1 parse family (/api/parse, /api/parse/bulk, /api/countries). /v1 routes return only `error` — do not depend on `success` there. error: type: string description: Human-readable error message (prose — switch on `code`, not on this string). code: type: string enum: - missing_key - invalid_key - use_case_forbidden - rate_limited_key - rate_limited_pool - rate_limited_ip - signature_invalid - insufficient_balance - account_suspended - paid_verification_required - receipt_invalid description: 'Stable machine-readable error code (added 2026-06-12, additive — older errors may omit it). See the "Error codes" section in the API description for the full table. A valid key on the wrong use case returns 403 use_case_forbidden (not 401): re-authing will not fix a permissions problem.' retry_after_seconds: type: integer description: 'Present on 429s: seconds until the window resets (mirrors the Retry-After header).' required: - error ParsedPhoneNumber: type: object properties: valid: type: boolean description: Whether the phone number is valid according to E.164 / international numbering rules possible: type: boolean description: Whether the phone number is possibly valid (less strict than valid) input: type: string description: The original input string e164: type: - string - 'null' description: E.164 formatted number (e.g., +14155552671) national: type: - string - 'null' description: National format (e.g., (415) 555-2671) international: type: - string - 'null' description: International format (e.g., +1 415-555-2671) rfc3966: type: - string - 'null' description: RFC3966 URI format (e.g., tel:+1-415-555-2671) countryCode: type: - string - 'null' description: ISO 3166-1 alpha-2 country code countryCallingCode: type: - string - 'null' description: Country calling code (e.g., 1 for US) nationalNumber: type: - string - 'null' description: National number without country code type: type: - string - 'null' enum: - MOBILE - FIXED_LINE - FIXED_LINE_OR_MOBILE - TOLL_FREE - PREMIUM_RATE - SHARED_COST - VOIP - PERSONAL_NUMBER - PAGER - UAN - VOICEMAIL description: Type of phone number carrier: type: - string - 'null' description: Mobile carrier name (available for mobile numbers) location: type: - string - 'null' description: Geographic location associated with the number timezones: type: - array - 'null' items: type: string description: List of timezones for this phone number region uri: type: - string - 'null' description: Dialable URI raw: type: - object - 'null' description: Raw parsed data from the phone-number parser properties: country: type: string countryCallingCode: type: string nationalNumber: type: string number: type: string ext: type: string carrierCode: type: string error: type: - string - 'null' description: Error message if parsing failed responses: RateLimited: description: Per-key rate limit exceeded. Retry after the number of seconds in the Retry-After header. headers: Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/json: schema: $ref: '#/components/schemas/Error' securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-API-Key description: API key for authentication BearerAuth: type: http scheme: bearer description: Bearer token authentication CidQueryKeyAuth: type: apiKey in: query name: key description: API key in the `?key=` query param. Accepted by the header-less PBX endpoint GET /api/v1/cid/{number} and by the webhook adapters POST /api/v1/integrations/retell/inbound, POST /api/v1/integrations/vapi/tool, and POST /api/v1/sbc/redirect, whose upstream platforms set only a static webhook URL and cannot send an Authorization/X-API-Key header. The key can leak into access logs — use a dedicated, rotated key, and prefer header auth wherever the client supports it.