Now in open beta: AI interviews in English and Arabic. Join the beta

Public API v1

A REST API for roles, applications, interviews, scorecards, offers and webhooks. It is in beta: these paths and names are fixed, and anything we add will not break them.

Status

  • Public API v1

    In beta

    The endpoints below.

  • API keys with scopes

    In beta

    Made by a workspace owner, each with its own scopes.

  • OAuth access tokens

    In beta

    For partner apps, acting as the person who signed in.

  • OpenAPI 3.1 specification

    In beta

    At /openapi.json under the base URL.

Available: live in production today. In beta: deployed and usable today; it may still change. Coming soon: not usable yet.

Basics

  • Base URL: https://api.octrahire.ai/api/v1/public
  • JSON in and out. Times are ISO 8601 in UTC
  • Lists take ?limit= (default 25, up to 100) and ?cursor=, and return {"data": [...], "next_cursor": ...}
  • Writes accept an Idempotency-Key header; the first response is replayed for 24 hours
  • Rate limits are per credential. Over the limit you get 429 with Retry-After
  • OpenAPI 3.1 specification: https://api.octrahire.ai/api/v1/public/openapi.json

Authentication

Send a credential as a bearer token. API keys start with ohk_ and OAuth access tokens with oat_. An API key can also go in an X-Api-Key header.

Who am I?
curl https://api.octrahire.ai/api/v1/public/me \
  -H "Authorization: Bearer ohk_your_key"

/me returns the workspace, the seat the credential acts as, and its scopes.

Scopes

A key or grant has only the scopes chosen for it, and never more than the seat that made it.

ScopeAllows
roles:readSee your roles and their pipelines
roles:writeCreate and edit roles
candidates:readSee candidates and applications
applications:writeAdd candidates and move them between stages
interviews:readSee AI interview results, reports and transcripts
interviews:writeInvite candidates to interviews and schedule them
scorecards:readSee scorecards and notes
scorecards:writeSubmit scorecards and add notes
offers:readSee offers
offers:writeDraft offers and send them for approval
approvals:writeApprove or decline requisitions and offers (owner only)
askAsk questions across interviews
reports:readSee hiring and Emiratisation reports
webhooks:manageManage webhook endpoints (owner only)

Endpoints

EndpointWhat it doesScope
GET /meThe workspace, seat and scopesany
GET /rolesList roles; ?status=open, closed or draftroles:read
GET /roles/{role_id}One roleroles:read
POST /rolesCreate a role: title, description, location, language, interview presetroles:write
PATCH /roles/{role_id}Edit a roleroles:write
POST /roles/{role_id}/openOpen a role (also /close)roles:write
GET /roles/{role_id}/pipelineCounts per stageroles:read
GET /applicationsList applications; ?role_id=, ?stage=, ?updated_since=candidates:read
GET /applications/{id}One applicationcandidates:read
POST /applicationsAdd a candidate to a roleapplications:write
POST /applications/{id}/moveMove to a stage, with a reasonapplications:write
POST /applications/{id}/rejectReject, with a reason category and noteapplications:write
POST /applications/{id}/interview-invitesInvite to an AI interview by email or WhatsAppinterviews:write
GET /applications/{id}/interviewReport summary, scores and evidenceinterviews:read
GET /applications/{id}/transcriptThe interview transcriptinterviews:read
POST /applications/{id}/scheduleSchedule a human interviewinterviews:write
GET /applications/{id}/scorecardsScorecardsscorecards:read
POST /applications/{id}/scorecardsSubmit a scorecard as your seatscorecards:write
GET /applications/{id}/notesNotesscorecards:read
POST /applications/{id}/notesAdd a notescorecards:write
GET /offersList offers; ?application_id=offers:read
GET /offers/{offer_id}One offeroffers:read
POST /offersDraft an offeroffers:write
POST /offers/{offer_id}/submitSend a draft for approvaloffers:write
POST /offers/{offer_id}/sendSend an approved offer to the candidateoffers:write
GET /approvalsApprovals waiting for your seatapprovals:write
POST /approvals/{approval_id}Approve or declineapprovals:write
GET /webhooksList webhookswebhooks:manage
POST /webhooksAdd a webhook; the secret is shown oncewebhooks:manage
DELETE /webhooks/{webhook_id}Remove a webhookwebhooks:manage
POST /webhooks/{webhook_id}/rotate-secretRotate a webhook's secretwebhooks:manage
GET /eventsThe event catalogueany

Add a candidate

Request
curl -X POST https://api.octrahire.ai/api/v1/public/applications \
  -H "Authorization: Bearer ohk_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a90-applicant-4471" \
  -d '{"role_id": "rol_123", "source": "careers-site",
       "candidate": {"name": "Mariam Al Hashimi", "email": "mariam@example.com"}}'

Errors

Every error has the same shape, with the HTTP status:

{"error": {"code": "insufficient_scope", "message": "This key needs applications:write"}}

Codes: unauthorized, insufficient_scope, forbidden, not_found, validation_error, conflict, rate_limited, idempotency_conflict.

Blind review

When a role hides candidate identity, name, email, phone and photo come back as null and anonymous_label is set, for every credential, including the owner's.

Webhooks →

See Octrahire with your own roles

A 30-minute walkthrough with your jobs or your programmes.