Qudra Partner API — Vol. 01
QudraPartner API Docs
Get API key

Jobs API

The Jobs resource is the heart of the Qudra Partner API. Every job you create flows through the embedding pipeline and becomes matchable against the Qudra seeker graph within ~30 seconds.

The job object

{
  "id": "job_01HXY8N1K9PZ3R…",
  "title": "Senior Backend Engineer",
  "description": "Build the Qudra matching pipeline…",
  "city": "Riyadh",
  "employment_type": "full_time",
  "salary_min": 18000,
  "salary_max": 30000,
  "currency": "SAR",
  "status": "active",
  "embedding_status": "ready",
  "match_ready": true,
  "qudra_url": "https://qudrah.io/jobs/senior-backend-engineer-01hxy…",
  "created_at": "2026-05-21T08:14:22.123Z",
  "updated_at": "2026-05-21T08:14:54.802Z"
}
FieldTypeDescription
id
stringjob_<ulid>Stable Qudra-issued id.
title
string3–200 chars. Used in matching — be specific.
description
stringUp to 20,000 chars. Markdown is rendered on the public page.
city
stringKSA city in English (Riyadh, Jeddah, Dammam, NEOM, …).
employment_type
enumEmployment type.
Enumfull_timepart_timecontractinternship
salary_min
integerSARMonthly SAR. Required for full_time and contract.
salary_max
integerSARMonthly SAR. Must be ≥ salary_min.
currency
stringReserved for future expansion.
DefaultSAR
status
enumLifecycle state.
DefaultactiveEnumactivepausedclosed
embedding_status
enumAsync pipeline state — wait for `ready` before relying on matching.
Enumprocessingreadyfailed
match_ready
boolean`true` once embedding is ready and the job is in the match graph.
Defaultfalse
qudra_url
stringURLPublic canonical URL on qudrah.io.
created_at
stringISO-8601Server creation time.
updated_at
stringISO-8601Last mutation time.

Create

POST/v1/partner/jobsv1Bearer

Create a single job. Counts against your monthly quota and per-minute rate limit. Returns 201 with the new job.

The embedding runs asynchronously — listen for job.created and job.matched webhooks rather than polling.

Request body

FieldTypeDescription
title
string3–200 chars. Be specific — used for matching.
description
stringUp to 20,000 chars. Markdown is rendered on the public page.
city
stringKSA city in English.
employment_type
enumEmployment type.
Enumfull_timepart_timecontractinternship
salary_min
integerSARMonthly SAR.
salary_max
integerSARMonthly SAR. Must be ≥ salary_min.
currency
stringReserved.
DefaultSAR

Request

curl -X POST https://api.qudrah.io/v1/partner/jobs \
  -H "Authorization: Bearer $QUDRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Senior Backend Engineer",
    "description": "Build the Qudra matching pipeline. Stack: NestJS, Postgres, pgvector, Redis.",
    "city": "Riyadh",
    "employment_type": "full_time",
    "salary_min": 18000,
    "salary_max": 30000,
    "currency": "SAR"
  }'

Response — 201 Created

{
  "id": "job_01HXY8N1K9PZ3R…",
  "status": "active",
  "embedding_status": "processing",
  "match_ready": false,
  "qudra_url": "https://qudrah.io/jobs/senior-backend-engineer-01hxy…",
  "created_at": "2026-05-21T08:14:22.123Z"
}

Idempotency

Pass Idempotency-Key: <uuid> to safely retry a create. We deduplicate by hash of (partnerId, idempotencyKey) for 24 hours.

List

GET/v1/partner/jobsv1Bearer

List your partner's jobs in reverse-chronological order with cursor pagination.

Query params

FieldTypeDescription
limit
integerPage size. Min 1, max 100.
Default20
cursor
stringOpaque cursor from the `next_cursor` of the previous response.
status
enumFilter by job status.
Enumactivepausedclosed
city
stringFilter by KSA city (English).

Response

{
  "data": [
    { "id": "job_01HXY…", "title": "…", "status": "active", "match_ready": true, "…": "…" }
  ],
  "next_cursor": "eyJpZCI6Imp…",
  "has_more": true
}

Retrieve

GET/v1/partner/jobs/:idv1Bearer

Returns the full job object. 404 partner.not_found if the job isn't owned by your partner.

Update

PATCH/v1/partner/jobs/:idv1Bearer

Partial update — send only the fields you want to change. Mutating title/description re-runs the embedding pipeline.

curl -X PATCH https://api.qudrah.io/v1/partner/jobs/job_01HXY… \
  -H "Authorization: Bearer $QUDRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "paused" }'

Delete

DELETE/v1/partner/jobs/:idv1Bearer

Soft-delete. The job disappears from the seeker feed immediately; we retain it for 30 days for audit. Returns 204 No Content.

Bulk

POST/v1/partner/jobs/bulkv1Bearer

Growth and Scale only. Create up to 100 jobs in a single call. One request against rate limit, N against monthly quota.

Request

curl -X POST https://api.qudrah.io/v1/partner/jobs/bulk \
  -H "Authorization: Bearer $QUDRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobs": [
      { "title": "Backend Engineer",  "city": "Riyadh", "employment_type": "full_time", "salary_min": 15000, "salary_max": 22000 },
      { "title": "Frontend Engineer", "city": "Jeddah", "employment_type": "full_time", "salary_min": 14000, "salary_max": 20000 }
    ]
  }'

Response — 207 Multi-Status

{
  "created": [
    { "index": 0, "id": "job_01HXY…", "status": "active" },
    { "index": 1, "id": "job_01HXZ…", "status": "active" }
  ],
  "errors": []
}

Per-item failures are reported in errors with the same shape as a top-level validation error — the rest of the batch still succeeds.