Openings

For HR administrators

An opening is one round of hiring on a position: when you open a position for hiring, Jadiroon starts an opening for it, and candidates apply to that opening. Use these endpoints to open positions for hiring from your HR or ERP system, to see which openings are live, and to close them. Candidates on an opening are Applications.

All endpoints sit under /api/v1 and need an API key (Authorization: Bearer jdr_live_…) created by your Workspace Admin in Settings → Integrations.

Endpoints

Method and pathWhat it doesPermission
GET /api/v1/openingsList openings (cursor pagination, updatedSince, ?positionId=, ?status=)recruitment.view
POST /api/v1/openingsOpen a position for hiringrecruitment.hiring.open
GET /api/v1/openings/{id}Get one openingrecruitment.view
POST /api/v1/openings/{id}/closeClose an openingrecruitment.hiring.open

Opening and closing use the same permission as in the app. An opening's id is its own id, not the position's. A position has at most one OPEN opening at a time; earlier rounds stay listed as CLOSED or FILLED. An id from another workspace returns 404 not_found.

The opening object

FieldTypeNotes
idstringThe opening's id.
positionIdstringThe position being hired for. See Positions.
title{ ar, en }The position's title; a missing language falls back to its job description's name.
statusstringOPEN, CLOSED (closed by hand or by archiving the position) or FILLED (closed by a hire).
hiringPathwaystring or nullWhile OPEN: INTERNAL_ONLY, INTERNAL_FIRST (employees first, then external) or EXTERNAL. Null otherwise.
externalAtISO 8601 or nullWhile OPEN: when the opening goes external (now for EXTERNAL, after the internal window for INTERNAL_FIRST, never for INTERNAL_ONLY).
openedAt, closedAtISO 8601closedAt is null while open.
externalRefsarray[{ system, externalId }] links to your systems.
createdAt, updatedAtISO 8601

Opening a position for hiring

POST /api/v1/openings takes the position, by id or by your external id, an optional pathway and an optional posting text:

{ "position": { "externalSystem": "oracle-hcm", "externalId": "POS-2207" }, "hiringPathway": "INTERNAL_FIRST" }

Without hiringPathway, the position's previous pathway is reused (INTERNAL_FIRST the first time). The same rules as the app apply:

  • the position must have a job description and a placement in the Organizational Structure (422 validation_failed, details.reason not_hire_ready, with details.missing);
  • it must have a posting text (422 validation_failed, details.reason no_job_description). A position created through the API has none: send posting with the request when the position has none, { "posting": { "ar": "…", "en": "…" } } (at least one language). It is saved as the position's posting text (posting on the position), and a language you leave out or send blank keeps its current text;
  • its job description must not be archived (422 validation_failed, details.reason archived): applications to it would all fail;
  • an archived position can't be opened (409 conflict, position_archived); unarchive it in the app first;
  • a position that already has an OPEN opening returns 409 conflict with details.reason already_open and details.openingId.

The response is 201 Created with the opening. New positions are created with Positions; the API opens existing ones.

Closing

POST /api/v1/openings/{id}/close closes hiring on the position (its hiring status becomes CLOSED) and the opening. Closing an opening that is not OPEN changes nothing and returns it as is. Candidates on it keep their applications.

Webhook events

EventWhendata.object
opening.createdA position is created and opened in one step in the appThe opening
opening.openedHiring is opened on a position (app or API)The opening
opening.closedHiring is closed on a position (app or API), or its job description is archived or deletedThe opening
opening.archivedThe position is archived (its open opening is closed)The opening
opening.updatedThe opening's title changes, it is made external now, or its position is restored from the archive; data.changedFields lists the fields when knownThe opening

Opening and closing also change the position's hiring fields, so they send position.updated too, and a position created through the openings flow sends position.created. Each event carries the opening it is about; archiving a position that has no open opening sends no opening.archived.

Errors

Status and codeMeaning
403 forbiddenThe key lacks the permission in the table above.
404 not_foundNo opening with that id in your workspace.
409 conflictalready_open or position_archived.
422 unresolved_referenceThe position reference didn't match a position in your workspace.
422 validation_failedThe body is invalid, or the position isn't ready to hire (not_hire_ready, no_job_description).

Example

curl -X POST https://jadiroon.com/api/v1/openings \
  -H "Authorization: Bearer $JADIROON_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: open-POS-2207-2026-10" \
  -d '{ "position": { "id": "cmvikf8270086knoq85hjhu3u" }, "hiringPathway": "INTERNAL_ONLY" }'
{
  "id": "cmvm6inad0002kncr1pytpf2x",
  "positionId": "cmvikf8270086knoq85hjhu3u",
  "title": { "ar": "طبيب أخصائي", "en": "Specialist Physician" },
  "status": "OPEN",
  "hiringPathway": "INTERNAL_ONLY",
  "externalAt": null,
  "openedAt": "2026-10-24T09:11:06.085Z",
  "closedAt": null,
  "externalRefs": [],
  "createdAt": "2026-10-24T09:11:06.085Z",
  "updatedAt": "2026-10-24T09:11:06.085Z"
}