API reference (Swagger)
Every endpoint with its request, responses and errors. Try requests right in the browser.
Postman collection
Download and import. Sign-in requests save the token, so the rest are authenticated.
OpenAPI 3 document
For code generators and API clients (Dart, Swift, Kotlin, TypeScript…).
Health
MySQL up 1.8 ms·Redis up 0.8 ms
Request logs
Recent requests with their body, response, SQL and timing. Look up a failing call by its X-Request-Id.
Background jobs
Queued and scheduled jobs (file cleanup now; expiry and notifications later), with failures and retries.
Base paths
| Path | Used by | Signs in with | Token |
|---|---|---|---|
/v1/customer | Customer app (customers and guests)coming soon | Mobile number or email + one-time code | oa_cus_… |
/v1/provider | Provider app (individuals and companies)coming soon | Mobile number or email + one-time code | oa_pro_… |
/v1/admin | Control panelcoming soon | Mobile number + password | oa_adm_… |
Send the token as Authorization: Bearer <token>. A token only works in its own app's path. Guests call public routes without one.
Uploading files
A form that takes files is sent as one multipart/form-data request: its fields as text and each file in a named part (for example the commercial registration file when a company provider registers). Forms without files are JSON. The file type is read from its bytes; each kind has its own types and size limit (gallery images 10 MB, gallery videos 100 MB, chat images 10 MB). Private files (commercial registration, chat attachments) come back as signed links that expire. The first forms arrive with M1.
Conventions
Language
Send Accept-Language: ar, en, ur or bn (or ?lang=). Urdu and Bengali get English text for now. Arabic is the default; a signed-in account's saved language is used when the request names none.
Errors
Always { code, message, details?, requestId }. Branch on code; show message. details lists field problems with their own message.
Request IDs
Every response has an X-Request-Id header. Include it when reporting a problem.
Mobile numbers
Saudi numbers as typed (05…, 5…, +9665…, Arabic digits too); responses use +9665….
Dates
Times are ISO 8601 in UTC, for example 2026-10-07T09:30:00.000Z.
Lists
App lists scroll with { items, nextCursor }; control panel tables page with { items, page, limit, total }.
Error codes
All 36 codes with their HTTP status and English message
| Code | Status | Message |
|---|---|---|
VALIDATION_FAILED | 400 | The request data is invalid |
INVALID_JSON | 400 | The request body could not be read |
UNAUTHORIZED | 401 | Please log in to complete this action. |
FORBIDDEN | 403 | You don't have permission to do this |
ACCOUNT_DISABLED | 403 | This user is disabled. Please contact the administration. |
NOT_FOUND | 404 | The requested item was not found |
CONFLICT | 409 | The request conflicts with existing data |
PAYLOAD_TOO_LARGE | 413 | The request is larger than allowed |
TOO_MANY_REQUESTS | 429 | Too many requests, please try again shortly |
MOBILE_NOT_REGISTERED | 404 | No account is registered with this number. Please make sure the mobile number is correct. |
EMAIL_NOT_REGISTERED | 404 | No account is registered with this email. Please make sure the email address is correct. |
MOBILE_ALREADY_REGISTERED | 409 | The mobile number is already registered, please check the number. |
EMAIL_UNCHANGED | 400 | The new email is the same as your current email. |
MOBILE_UNCHANGED | 400 | The new number is the same as your current number. |
EMAIL_ALREADY_REGISTERED | 409 | The email address is already registered. |
IQAMA_ALREADY_REGISTERED | 409 | The residence number is already registered. |
CR_ALREADY_REGISTERED | 409 | Commercial registration number already registered. |
CITY_NOT_AVAILABLE | 400 | This city is not available. Please choose another. |
NEIGHBOURHOOD_NOT_AVAILABLE | 400 | This neighbourhood is not available. Please choose another. |
SERVICE_NOT_AVAILABLE | 400 | This service is not available. Please choose another. |
REPORT_REASON_NOT_AVAILABLE | 400 | This report reason is not available. Please choose another. |
OTP_INVALID | 400 | The verification code is incorrect. |
OTP_EXPIRED | 400 | The verification code is invalid or expired. Please request a new one. |
OTP_TOO_MANY_ATTEMPTS | 429 | Too many incorrect attempts. Please request a new code. |
OTP_RESEND_TOO_SOON | 429 | You can request a new code in {seconds} seconds. |
VERIFICATION_INVALID | 400 | This verification is no longer valid. Please request a new code. |
SMS_SEND_FAILED | 503 | The verification code could not be sent. Please try again. |
EMAIL_SEND_FAILED | 503 | The verification code could not be sent to this email. Please try again. |
FILE_REQUIRED | 400 | No file was attached. |
FILE_TOO_LARGE | 413 | File size exceeds the allowed limit ({maxMb} MB). |
FILE_TYPE_NOT_ALLOWED | 415 | Unsupported file type. Allowed: {allowed} |
FILE_NOT_AVAILABLE | 400 | This file can't be used. Please upload it again. |
IDEMPOTENCY_KEY_REUSED | 409 | This Idempotency-Key was already used for a different request. |
PACKAGE_NOT_AVAILABLE | 400 | This package is no longer available. Please choose another package. |
SUBSCRIPTION_ALREADY_ACTIVE | 409 | You already have an active subscription. You can subscribe again once it ends. |
INTERNAL_ERROR | 500 | Something went wrong, please try again |