Errors
Every error from the Qudra Partner API returns a stable JSON shape with both English and Arabic copy, so you can surface the right message to your users without an intermediate translation layer.
Error shape
{
"error": {
"code": "partner.validation_error",
"message": "Validation failed: title is required",
"messageAr": "فشل التحقق: العنوان مطلوب",
"fields": {
"title": "must be a non-empty string"
},
"request_id": "req_01HXY8N1K9PZ3R…"
}
}| Field | Type | Description |
|---|---|---|
| code | string | Stable machine-readable identifier — switch on this, not on message. |
| message | string | Human-readable English explanation. |
| messageAr | string | Human-readable Arabic explanation — surface this in Arabic UIs. |
| fields | object | Field-level validation details. Present only for 422 responses. |
| request_id | string | Echo this back when contacting support — it pinpoints the exact request. |
Error codes
| HTTP | Code | When |
|------|-------------------------------|-----------------------------------------------------------------|
| 400 | partner.invalid_request | Malformed body, wrong content-type, or unknown query param. |
| 401 | partner.unauthorized | Missing, malformed, expired, or revoked API key. |
| 403 | partner.forbidden | Key valid but lacks permission (e.g. webhooks on free plan). |
| 404 | partner.not_found | Resource doesn't exist or is not owned by your partner. |
| 409 | partner.duplicate | Idempotency key reused with different body, or unique conflict. |
| 422 | partner.validation_error | Body shape is right but values fail validation — see fields. |
| 429 | partner.rate_limit | Per-minute rate limit hit — back off using Retry-After. |
| 429 | partner.plan_limit_exceeded | Monthly job quota hit — upgrade plan or wait for reset. |
| 500 | partner.internal | Our fault. Includes request_id — please report it. |
Switch on code, not message
The message and messageAr fields are tuned for display and may change wording. The code is stable across versions — use it in your retry, alerting, and switch-case logic.
Field-level validation
When code is partner.validation_error, the fields object maps each invalid field to a short reason:
{
"error": {
"code": "partner.validation_error",
"message": "Validation failed",
"messageAr": "فشل التحقق",
"fields": {
"salary_min": "must be a positive integer",
"employment_type":"must be one of: full_time, part_time, contract, internship",
"city": "is required"
},
"request_id": "req_01HXY…"
}
}Handling errors in code
import { QudraClient, QudraError } from '@qudra/sdk';
try {
await qudra.jobs.create({ title: '', city: 'Riyadh' });
} catch (e) {
if (e instanceof QudraError) {
switch (e.code) {
case 'partner.validation_error':
showValidation(e.fields);
break;
case 'partner.rate_limit':
await sleep(e.retryAfter * 1000);
break;
case 'partner.plan_limit_exceeded':
promptUpgrade();
break;
default:
reportToSentry(e.requestId);
}
}
}