Basics
Base URL https://app.seekiq.io/api/v1. Send your key as Authorization: Bearer. Errors share one envelope with a code, a message and a request id. Lists take limit and cursor and return next_cursor and has_more.
Jobs
Jobs and their workflow stages
List jobs
GET/jobs
jobs:readParameters
closed also returns paused and archived jobs, which read as closed.
draftopenclosed- limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: Job[], next_cursor: string | null, has_more: boolean }
A page of jobs
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/jobs" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Create a job
POST/jobs
jobs:writeParameters
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- titlestringRequired
- levelJobLevel
internjuniormidseniorleadmanager - departmentstring | null
- locationstring | null
- jdobject
- workflow_template_idstring | null
- deadline_atstring (date-time) | null
Responses
Example
curl -X POST "https://app.seekiq.io/api/v1/jobs" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"title": "Customer support lead"
}'Get a job
GET/jobs/{job_id}
jobs:readParameters
- job_idIdpathRequired
Responses
Example
curl "https://app.seekiq.io/api/v1/jobs/job_01JB5C1N" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Update a job
PATCH/jobs/{job_id}
jobs:writeSetting status to open reopens a job published before; a job never published answers 422 unprocessable (publish it in the job wizard first). It answers 409 conflict with error.reason job_limit when the workspace already has as many open jobs as its plan allows (the trial: 3; Starter: 5; Growth and Enterprise: no limit). Close a job to free a slot. Setting status to draft on a published job answers 409 invalid_transition.
Parameters
- job_idIdpathRequired
Request body
- statusJobStatus
draftopenclosed - titlestring
- levelJobLevel
internjuniormidseniorleadmanager - departmentstring | null
- locationstring | null
- jdobject
- workflow_template_idstring | null
- deadline_atstring (date-time) | null
Responses
Example
curl -X PATCH "https://app.seekiq.io/api/v1/jobs/job_01JB5C1N" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "draft",
"title": "Customer support lead",
"level": "intern"
}'List the workflow stages of a job (resolved template + job override)
GET/jobs/{job_id}/stages
jobs:readParameters
- job_idIdpathRequired
Responses
- 200{ workflow_version: integer, data: Stage[] }
Ordered stages
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/jobs/job_01JB5C1N/stages" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Applications
Applications and stage moves
List applications
GET/applications
applications:readParameters
- job_idIdquery
- stage_idIdquery
- updated_sincestring (date-time)query
- limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: Application[], next_cursor: string | null, has_more: boolean }
A page of applications
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/applications" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Create an application
POST/applications
applications:writeconsent is required. AI screening waits for consent if consent.ai_screening is not true. The candidate needs a phone or an email (400 validation_failed otherwise) and is matched to an existing candidate by either. An unknown job_id answers 400 validation_failed, a job that is not open answers 422 unprocessable and a candidate who already applied to the job answers 409 conflict. cv_url and cv_upload_id are recorded in the audit log but the CV is not fetched or read yet, so cv_match stays null for applications created here.
Parameters
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- job_idIdRequired
- cv_urlstring (uri) | null
Recorded in the audit log; the CV is not fetched or read yet.
- cv_upload_idstring | null
Recorded in the audit log; the CV is not fetched or read yet.
- sourceApplicationSource
Defaults to api.
careers_siteembedapiemail_inboxreferralsourcedjob_board - answersobject[]
Answers to the job's apply form, checked against each question (an unknown question or a value that does not fit is a validation_failed). A multi choice answer is option ids separated by commas; yes or no is yes or no. File questions cannot be answered here.
Responses
- 201Application
Created
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/applications" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"job_id": "job_01JB7X4M2Q8Z",
"candidate": {
"name": "Nadia Rahman"
},
"consent": {
"ai_screening": true,
"text_version": "ai-screening-2026-10",
"captured_at": "2026-10-26T09:30:00Z"
}
}'Get an application
GET/applications/{application_id}
applications:readParameters
- application_idIdpathRequired
Responses
- 200Application
The application
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/applications/app_01JB7X4M2Q8Z" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Move an application to another stage
POST/applications/{application_id}/move
applications:writeCannot move to a rejected or archived state (that is a decision). Moving into the offer stage requires an approved, sent or signed offer (reason offer_not_approved). Hired is never a move: a person confirms the hire in the app once the candidate has signed (reason hire_is_a_decision). A stage that is not in the job's workflow, the stage the application is already in, or an application a person rejected also answer 409 invalid_transition.
Parameters
- application_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- to_stage_idIdRequired
- reasonstring | null
Responses
- 200Application
Moved
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/applications/app_01JB7X4M2Q8Z/move" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"to_stage_id": "stg_01JB7X4M2Q8Z"
}'Candidates
One candidate record across all jobs
List or look up candidates
GET/candidates
candidates:readParameters
- emailstring (email)query
- tagstringquery
- limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: Candidate[], next_cursor: string | null, has_more: boolean }
A page of candidates
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/candidates" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Create a candidate
POST/candidates
candidates:writeA phone and an email are both optional here. A candidate with the same phone or email answers 409 conflict. Without language the candidate's language is bn.
Parameters
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- namestringRequired
- phonePhone
- emailstring (email) | null
- photo_urlstring (uri) | null
URL of a photo the candidate chose to provide (up to 2000 characters). Stored, not returned on the Candidate. Never used in scoring.
- languageCandidateLanguage
enbnhiurartlesidms - tagsstring[]
Responses
Example
curl -X POST "https://app.seekiq.io/api/v1/candidates" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Nadia Rahman"
}'Get a candidate
GET/candidates/{candidate_id}
candidates:readParameters
- candidate_idIdpathRequired
Responses
Example
curl "https://app.seekiq.io/api/v1/candidates/cand_01JB6D2P" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Update a candidate
PATCH/candidates/{candidate_id}
candidates:writeA phone or email another candidate already has answers 409 conflict.
Parameters
- candidate_idIdpathRequired
Request body
- namestring
- phonePhone
- emailstring (email) | null
- photo_urlstring (uri) | null
URL of a photo the candidate chose to provide (up to 2000 characters). Stored, not returned on the Candidate. Never used in scoring.
- languageCandidateLanguage
enbnhiurartlesidms - tagsstring[]
Responses
Example
curl -X PATCH "https://app.seekiq.io/api/v1/candidates/cand_01JB6D2P" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Nadia Rahman",
"phone": "+8801712345678",
"email": "nadia@example.com"
}'Interviews
AI and human interviews
List interviews
GET/interviews
interviews:readScreening interviews and scheduled human interviews. A spoken walkthrough of a candidate's coding challenge or take-home is part of its assessment and is not listed here.
Parameters
- application_idIdquery
- kindstringquery
aihuman - limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: Interview[], next_cursor: string | null, has_more: boolean }
A page of interviews
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/interviews" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Get an interview
GET/interviews/{interview_id}
interviews:readParameters
- interview_idIdpathRequired
Responses
Example
curl "https://app.seekiq.io/api/v1/interviews/int_01JB9F4S" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Scorecards
AI scorecard and human feedback, read only, never merged
Get the AI scorecard and human feedback (read only, never merged)
GET/applications/{application_id}/scorecard
scorecards:readParameters
- application_idIdpathRequired
Responses
Example
curl "https://app.seekiq.io/api/v1/applications/app_01JB7X4M2Q8Z/scorecard" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Decisions
Human decisions (user-attributed keys only)
List decisions on an application
GET/applications/{application_id}/decisions
applications:readParameters
- application_idIdpathRequired
Responses
- 200{ data: Decision[] }
Decisions, newest first
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/applications/app_01JB7X4M2Q8Z/decisions" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Record a human decision (user-attributed key only)
POST/applications/{application_id}/decisions
decisions:writeNeeds a user-attributed keyHuman-in-the-loop rule: a named person approves every advance, hold or reject. A service key cannot hold decisions:write, so it gets 403 insufficient_scope; any other key that is not user-attributed gets 403 human_actor_required. The acting member must be able to decide on the job (403 forbidden otherwise). Audited with actor, key prefix and scorecard version. 409 conflict when the application is already rejected and a reject is sent, or with reason review_pending when an advance meets a score whose two passes disagree. More than 20 rejections in an hour from one key answer 429 rate_limited.
Parameters
- application_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
advanceholdreject- reasonstringRequired
- rejection_reason_codestring | null
For a rejection: one of the job's Archived stage rejection reasons (the workspace's list), required when that list is set (else 422 reason_code). A rejection moves the application to the Archived stage through the workflow, as the app's decision gate does: stage history, the stage's entry automations and application.stage_changed. An advance moves to the next stage the same way. Undo puts it back.
- messageobjectRequired
Responses
Example
curl -X POST "https://app.seekiq.io/api/v1/applications/app_01JB7X4M2Q8Z/decisions" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"outcome": "advance",
"reason": "Strong on customer empathy",
"message": {
"template_id": "otpl_01JB7X4M2Q8Z",
"language": "en"
}
}'Undo a decision inside its undo window (user-attributed key only)
DELETE/decisions/{decision_id}
decisions:writeNeeds a user-attributed keyUntil the decision's undo_until (five minutes after it was made) and while its candidate message has not gone out, undoes the decision: the queued message is cancelled, the candidate goes back to the stage they were in, the decision leaves the list and the undo is audited under the member the key acts for. A decision.undone event follows (and application.stage_changed when the stage moved back). Messages from POST /applications/{application_id}/decisions wait out the undo window before they are sent. What the move's entry automations created (self-schedule invites, entry messages, reviewer requests nobody started) is reversed too; anything created by hand stays. 409 with error.reason undo_window_closed, message_sent, schedule_booked, stage_moved or already_undone when it can no longer be undone; 403 forbidden (reason role) when the member cannot decide on the job.
Parameters
- decision_idIdpathRequired
Responses
- 204
Undone; the message was cancelled
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X DELETE "https://app.seekiq.io/api/v1/decisions/dec_01JB8E3R" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Offers
Offer drafts and approval
List offers
GET/offers
offers:readParameters
- application_idIdquery
draftpending_approvalapprovedsentsigneddeclinedexpiredwithdrawn- limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: Offer[], next_cursor: string | null, has_more: boolean }
A page of offers
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/offers" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Create an offer draft from a letter template
POST/offers
offers:writeAn unknown application answers 404 not_found; an unknown template_id or an expires_on before today answers 400 validation_failed. An application with a live offer answers 409 conflict (reason already_has_offer). A letter with fields SeekIQ does not know answers 422 unprocessable (reason merge_unknown). A user-attributed key answers 403 forbidden when its member cannot work on offers for the job.
Parameters
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- application_idIdRequired
- template_idstring | null
An offer letter template (otpl_), as returned on an Offer. Omit to use the workspace default letter, or the starter letter when the workspace has no default.
- languageLanguage
Letter language. Defaults to the candidate's language.
enbn
Responses
Example
curl -X POST "https://app.seekiq.io/api/v1/offers" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"application_id": "app_01JB7X4M2Q8Z",
"terms": {
"salary": {
"amount": 1,
"currency": "BDT"
},
"expires_on": "2026-11-30",
"title": "Customer support lead",
"period": "hour",
"start_date": "2026-11-30"
}
}'Get an offer
GET/offers/{offer_id}
offers:readParameters
- offer_idIdpathRequired
Responses
Example
curl "https://app.seekiq.io/api/v1/offers/off_01JBAG5T" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Start the approval chain (approving and sending happen in the app)
POST/offers/{offer_id}/submit
offers:writeOnly a draft can be submitted (409 invalid_transition, reason wrong_status). A letter missing a value or holding an unknown field answers 422 unprocessable (reason merge_missing or merge_unknown); an invalid workspace approval chain answers 422 (reason chain_invalid).
Parameters
- offer_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Responses
Example
curl -X POST "https://app.seekiq.io/api/v1/offers/off_01JBAG5T/submit" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Talent pools
Talent pools and membership
List talent pools
GET/pools
pools:readParameters
- limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: TalentPool[], next_cursor: string | null, has_more: boolean }
A page of pools
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/pools" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Create a talent pool
POST/pools
pools:writeParameters
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- namestringRequired
- descriptionstring | null
Responses
- 201TalentPool
Created
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/pools" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Nadia Rahman"
}'List pool members
GET/pools/{pool_id}/members
pools:readParameters
- pool_idIdpathRequired
- limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: PoolMember[], next_cursor: string | null, has_more: boolean }
A page of members
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/pools/pool_01JBBH6V/members" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Add a candidate to a pool
POST/pools/{pool_id}/members
pools:writeAn unknown candidate answers 400 validation_failed; a candidate already in the pool answers 409 conflict.
Parameters
- pool_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- candidate_idIdRequired
Responses
- 201PoolMember
Added
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/pools/pool_01JBBH6V/members" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"candidate_id": "cand_01JB7X4M2Q8Z"
}'Remove a candidate from a pool
DELETE/pools/{pool_id}/members/{candidate_id}
pools:writeParameters
- pool_idIdpathRequired
- candidate_idIdpathRequired
Responses
- 204
Removed
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X DELETE "https://app.seekiq.io/api/v1/pools/pool_01JBBH6V/members/cand_01JB6D2P" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Webhooks
Webhook endpoints and the delivery log
List webhook endpoints
GET/webhooks
webhooks:manageResponses
- 200{ data: WebhookEndpoint[] }
Endpoints
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/webhooks" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Create a webhook endpoint (secret returned once)
POST/webhooks
webhooks:manageA URL that is not public https answers 400 validation_failed on url. The secret is whsec_ plus 32 characters. 503 unavailable when webhooks are not configured on the server.
Parameters
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Request body
- urlstring (uri)Required
A public https URL. The host is resolved on save and before every delivery; any private, loopback, link local, metadata or reserved address is refused (README section 6).
- descriptionstring | null
- activeboolean
Responses
- 201{ id: Id, url: string (uri), events: EventType[], description: string | null, active: boolean, disabled_reason: string | null, created_at: string (date-time), secret: string }
Created
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/webhooks" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/seekiq",
"events": [
"ping"
]
}'Get a webhook endpoint
GET/webhooks/{webhook_id}
webhooks:manageParameters
- webhook_idIdpathRequired
Responses
Endpoint
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Update a webhook endpoint
PATCH/webhooks/{webhook_id}
webhooks:manageParameters
- webhook_idIdpathRequired
Request body
- urlstring (uri)
A public https URL. The host is resolved on save and before every delivery; any private, loopback, link local, metadata or reserved address is refused (README section 6).
- eventsEventType[]
- descriptionstring | null
- activeboolean
Responses
Updated
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X PATCH "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/seekiq",
"events": [
"ping"
],
"description": "Support team in Dhaka"
}'Delete a webhook endpoint
DELETE/webhooks/{webhook_id}
webhooks:manageParameters
- webhook_idIdpathRequired
Responses
- 204
Deleted
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X DELETE "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Rotate the signing secret (old secret also signs for 24h)
POST/webhooks/{webhook_id}/rotate-secret
webhooks:manageParameters
- webhook_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Responses
- 200{ secret: string, previous_expires_at: string (date-time) }
New secret
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W/rotate-secret" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Send a ping event
POST/webhooks/{webhook_id}/test
webhooks:manageParameters
- webhook_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Responses
Queued
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W/test" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Delivery log
GET/webhooks/{webhook_id}/deliveries
webhooks:manageParameters
- webhook_idIdpathRequired
- statusstringquery
succeededfailedpending - limitintegerquery
- cursorstringquery
Opaque cursor from next_cursor. Expires after 24h (400 bad_request, reason cursor_expired); a cursor from another list answers 400 bad_request, reason invalid_cursor.
Responses
- 200{ data: WebhookDelivery[], next_cursor: string | null, has_more: boolean }
A page of deliveries
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W/deliveries" \
-H "Authorization: Bearer $SEEKIQ_API_KEY"Redeliver an event (same event id)
POST/webhooks/{webhook_id}/deliveries/{delivery_id}/redeliver
webhooks:manageAny delivery of the event on this endpoint can be redelivered. The redelivery is one new attempt (attempt 1, a new delivery id) and is not retried automatically.
Parameters
- webhook_idIdpathRequired
- delivery_idIdpathRequired
- Idempotency-Keystring (uuid)header
POST only, scoped to the API key. Replays the stored response for 24h with Idempotent-Replayed true. The same key with a different method, path or body returns 409 idempotency_key_reused; a key whose first request is still running returns 409 conflict; a value that is not a UUID returns 400 bad_request.
Responses
Queued
- ErrorError
Error envelope (400, 401, 403, 404, 409, 413, 422, 429, 5xx)
Example
curl -X POST "https://app.seekiq.io/api/v1/webhooks/whk_01JBCJ7W/deliveries/dlv_01JBDK8X/redeliver" \
-H "Authorization: Bearer $SEEKIQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Schemas
The shapes the endpoints send and receive. A type in an endpoint links here.
Id
Opaque prefixed id (job_, app_, cand_, int_, off_, otpl_, pool_, dec_, whk_, dlv_, evt_, usr_, stg_, org_, key_, doc_, dreq_). Do not parse.
Phone
E.164
Language
English or Bangla, the two values v1 reports today for an interview or offer letter language. More values may be added; accept unknown values.
enbnCandidateLanguage
The candidate's language, for their emails, SMS and candidate pages. Job titles and other text a workspace writes in English and Bangla appear in Bangla for bn and in English for the other languages.
enbnhiurartlesidmsMoney
- amountintegerRequired
Minor units
- currencystringRequired
Error
- errorobjectRequired
Page
- dataany[]Required
- next_cursorstring | nullRequired
- has_morebooleanRequired
Actor
- typestringRequired
userautomationapi_key - idIdRequired
- namestring | null
Evidence
- sourcestringRequired
cvtranscript - quotestringRequired
- answer_idstring | null
- start_msinteger | null
- end_msinteger | null
- cv_lineinteger | null
CvMatch
How well the CV evidences the job's competencies, in the IQ shape. percent is the 0 to 100 CV match the pipeline shows. value is the same number on the 1 to 5 scale every score uses: the percent mapped back onto the competency scale (0 is 1, 100 is 5) and rounded half up, so 0 to 12 is 1, 13 to 37 is 2, 38 to 62 is 3, 63 to 87 is 4 and 88 to 100 is 5; label is that level's name. evidence holds the CV quotes behind it. sufficiency is none when no competency has evidence, sufficient when every one has full evidence and thin otherwise. Null until the CV is read and matched. It sits beside the interview score and is never merged into it.
- valueintegerRequired
- labelstringRequired
- percentintegerRequired
- sufficiencystringRequired
sufficientthinnone - modelstringRequired
- prompt_versionstringRequired
AiValue
IQ shape. No bare numbers.
- valueinteger | nullRequired
Null with sufficiency none (no citation, no score).
- labelstringRequired
- sufficiencystringRequired
sufficientthinnone - modelstringRequired
- prompt_versionstringRequired
JobStatus
draftopenclosedJob
- idIdRequired
- titlestringRequired
- slugstring
- levelJobLevel
internjuniormidseniorleadmanager - integritystring
Integrity checks for the job's interviews and tests. light: no camera, browser signals only; standard (the default): an optional selfie; strict: a selfie and a head-turn check before the interview, photos every 20 seconds and tests in full screen. Set in the app. Checks raise flags for a person to review and never change a score or reject anyone.
lightstandardstrict draftopenclosed- departmentstring | null
- locationstring | null
- jdobject
- careers_urlstring (uri) | null
- deadline_atstring (date-time) | null
The application deadline. A deadline set in the app is a day in the workspace time zone (stored as 23:59 local) and closes as that day ends; one sent here closes at that instant.
- accepting_applicationsboolean
Additive, 2026-10-29. True while the job takes new applications: open, and its deadline has not passed (or the job keeps taking applications after it). When the deadline closes a job, the job stays open for review, interviews and decisions already in flight, the careers pages say "Applications closed" and POST /applications refuses with 422. A later deadline_at reopens it.
- applications_closed_atstring (date-time) | null
Additive, 2026-10-29. When the deadline closed the job to new applications; null while it takes them.
- timezonestring
- created_atstring (date-time)Required
- updated_atstring (date-time)Required
JobLevel
Seniority. Sets interview question difficulty, the scoring anchors, answer time and how deep follow-ups go. When a job is created without one it comes from the title ("Senior ..." is senior); anything without a level word is mid.
internjuniormidseniorleadmanagerJobFields
- titlestring
- levelJobLevel
internjuniormidseniorleadmanager - departmentstring | null
- locationstring | null
- jdobject
- workflow_template_idstring | null
- deadline_atstring (date-time) | null
JobCreate
- titlestringRequired
- levelJobLevel
internjuniormidseniorleadmanager - departmentstring | null
- locationstring | null
- jdobject
- workflow_template_idstring | null
- deadline_atstring (date-time) | null
JobUpdate
StageType
appliedai_screenphoneassessmentpanelofferhiredarchivedStage
- idIdRequired
appliedai_screenphoneassessmentpanelofferhiredarchived- namestringRequired
- orderintegerRequired
- sla_hoursinteger | null
Consent
- ai_screeningbooleanRequired
- nurtureboolean
- text_versionstringRequired
- captured_atstring (date-time)Required
With a Z or an offset.
- captured_bystring
CandidateFields
- namestring
- phonePhone
- emailstring (email) | null
- photo_urlstring (uri) | null
URL of a photo the candidate chose to provide (up to 2000 characters). Stored, not returned on the Candidate. Never used in scoring.
- languageCandidateLanguage
enbnhiurartlesidms - tagsstring[]
CandidateInput
- namestringRequired
- phonePhone
- emailstring (email) | null
- photo_urlstring (uri) | null
URL of a photo the candidate chose to provide (up to 2000 characters). Stored, not returned on the Candidate. Never used in scoring.
- languageCandidateLanguage
enbnhiurartlesidms - tagsstring[]
CandidateUpdate
- namestring
- phonePhone
- emailstring (email) | null
- photo_urlstring (uri) | null
URL of a photo the candidate chose to provide (up to 2000 characters). Stored, not returned on the Candidate. Never used in scoring.
- languageCandidateLanguage
enbnhiurartlesidms - tagsstring[]
Candidate
- idIdRequired
- namestringRequired
- phonePhone | null
- emailstring (email) | null
- languageCandidateLanguage
enbnhiurartlesidms - tagsstring[]
- consentobject
- application_idsId[]
- created_atstring (date-time)Required
- updated_atstring (date-time)
ApplicationSource
Older applications that came in through a channel no longer offered are reported as sourced.
careers_siteembedapiemail_inboxreferralsourcedjob_boardApplication
- idIdRequired
- job_idIdRequired
- candidate_idIdRequired
- statusstringRequired
activeon_holdrejectedhiredwithdrawn careers_siteembedapiemail_inboxreferralsourcedjob_board- cv_matchCvMatch | null
- awaiting_consentboolean
- answersApplicationAnswer[]
Apply form answers in form order. Files are listed by name; their storage is never exposed.
- screeningScreening
- created_atstring (date-time)Required
- updated_atstring (date-time)Required
ApplicationAnswer
- question_idstringRequired
The form question id, or cover_letter, linkedin or portfolio for those standard questions.
- labelobject | nullRequired
The question in both languages; null for a standard question or one no longer on the form.
- typestringRequired
- valueanyRequired
Text, a number, yes or no, option ids. Files come as name, mime, size and kind.
Screening
IQ checks the recruiter's plain screening rules against the answers and the CV. A verdict only flags and sorts. It never rejects anyone on its own; only a job's autopilot rule that a person switched on may use it.
- statusstring | nullRequired
Null when the form has no screening rules. capped means the workspace used its monthly IQ fair use.
pendingdonecappedunavailable - misses_must_havebooleanRequired
A must-have rule was judged not met; the application sorts lower.
- resultsobject[]Required
ApplicationCreate
- job_idIdRequired
- cv_urlstring (uri) | null
Recorded in the audit log; the CV is not fetched or read yet.
- cv_upload_idstring | null
Recorded in the audit log; the CV is not fetched or read yet.
- sourceApplicationSource
Defaults to api.
careers_siteembedapiemail_inboxreferralsourcedjob_board - answersobject[]
Answers to the job's apply form, checked against each question (an unknown question or a value that does not fit is a validation_failed). A multi choice answer is option ids separated by commas; yes or no is yes or no. File questions cannot be answered here.
Interview
- idIdRequired
- application_idIdRequired
- kindstringRequired
aihuman - stage_idstring | null
- statusstringRequired
invitedscheduledin_progresscompletedabandonedcancelledno_show - languageLanguage
enbn - scheduled_atstring (date-time) | null
- completed_atstring (date-time) | null
- interviewersActor[]
- conferencing_urlstring (uri) | null
HumanFeedback
- stage_idIdRequired
- submitted_atstring (date-time)Required
- recommendationstringRequired
strong_yesyesnostrong_no - ratingsobject[]Required
Scorecard
AI and human sections are separate and never merged into one number.
- application_idIdRequired
- aiobject | nullRequired
Only submitted feedback is returned.
Attempt
- answer_idstringRequired
- input_modestringRequired
voicetext - transcript_statusstringRequired
pendingdonefailedskipped - scoredbooleanRequired
Both scoring passes are stored.
- valueinteger | nullRequired
This attempt alone.
- labelstringRequired
- passesinteger | null[]Required
- agreementstring | nullRequired
agreedisagree
AttemptPair
- redo_idstringRequired
- competencystringRequired
- question_indexintegerRequired
- statestringRequired
requestedreceivedexpiredrevoked - countedstringRequired
originalredo - counted_atstring (date-time) | nullRequired
- received_atstring (date-time) | nullRequired
Null until the new answer is received.
DecisionOutcome
advanceholdrejectDecisionCreate
advanceholdreject- reasonstringRequired
- rejection_reason_codestring | null
For a rejection: one of the job's Archived stage rejection reasons (the workspace's list), required when that list is set (else 422 reason_code). A rejection moves the application to the Archived stage through the workflow, as the app's decision gate does: stage history, the stage's entry automations and application.stage_changed. An advance moves to the next stage the same way. Undo puts it back.
- messageobjectRequired
Decision
- idIdRequired
- application_idIdRequired
advanceholdreject- reasonstringRequired
- via_key_prefixstring | null
- scorecard_versioninteger | null
- message_statusstring
queuedsentnot_sent - created_atstring (date-time)Required
- undo_untilstring (date-time)
Until then DELETE /decisions/{decision_id} can undo it, while the message has not gone out.
OfferStatus
draftpending_approvalapprovedsentsigneddeclinedexpiredwithdrawnPayPeriod
hourmonthyearOfferTerms
- titlestringRequired
Gross pay per period, in minor units (45000 BDT a month is 4500000).
hourmonthyear- start_datestring (date)Required
- expires_onstring (date)Required
The last day the candidate can sign, in the workspace timezone.
- locationstring | null
- employment_typestring | null
- bonusstring | null
- benefitsstring | null
- reports_tostring | null
OfferCreate
- application_idIdRequired
- template_idstring | null
An offer letter template (otpl_), as returned on an Offer. Omit to use the workspace default letter, or the starter letter when the workspace has no default.
- languageLanguage
Letter language. Defaults to the candidate's language.
enbn
OfferApproval
- step_idstringRequired
- approver_rolestring | nullRequired
Set when anyone holding the role can approve the step.
ownerrecruiterhiring_manager The named approver, or who approved or rejected the step. Null while a role step is open.
- decisionstring | nullRequired
approvedrejected - atstring (date-time) | nullRequired
Offer
- idIdRequired
- application_idIdRequired
- candidate_idIdRequired
- job_idIdRequired
- template_idstring | nullRequired
draftpending_approvalapprovedsentsigneddeclinedexpiredwithdrawnenbnThe steps of the newest approval chain, in order. Empty until the offer is submitted.
- pdf_urlstring (uri) | nullRequired
Signed URL of the letter PDF (the signed copy once signed), expires in 60 seconds: download it right away, or read the offer again for a fresh one. Null before the offer is sent.
- sent_atstring (date-time) | nullRequired
- signed_atstring (date-time) | nullRequired
- declined_atstring (date-time) | nullRequired
- decline_reasonstring | nullRequired
compensationother_offerrole_fitlocationtimingpersonalother - created_atstring (date-time)Required
- updated_atstring (date-time)Required
TalentPool
- idIdRequired
- namestringRequired
- descriptionstring | null
- member_countintegerRequired
- created_atstring (date-time)
PoolMember
- candidate_idIdRequired
- added_atstring (date-time)Required
- nurture_consentbooleanRequired
EventType
pingapplication.createdapplication.stage_changedinterview.completedscorecard.readydecision.madedecision.undoneoffer.sentoffer.signedoffer.declineddocument.sentdocument.signeddocument.declinedcandidate.data_requestWebhookEndpointFields
- urlstring (uri)
A public https URL. The host is resolved on save and before every delivery; any private, loopback, link local, metadata or reserved address is refused (README section 6).
- eventsEventType[]
- descriptionstring | null
- activeboolean
WebhookEndpointInput
- urlstring (uri)Required
A public https URL. The host is resolved on save and before every delivery; any private, loopback, link local, metadata or reserved address is refused (README section 6).
- descriptionstring | null
- activeboolean
WebhookEndpointUpdate
- urlstring (uri)
A public https URL. The host is resolved on save and before every delivery; any private, loopback, link local, metadata or reserved address is refused (README section 6).
- eventsEventType[]
- descriptionstring | null
- activeboolean
WebhookEndpoint
- idIdRequired
- urlstring (uri)Required
- descriptionstring | null
- activebooleanRequired
- disabled_reasonstring | null
- created_atstring (date-time)Required
WebhookDelivery
- idIdRequired
- event_idIdRequired
pingapplication.createdapplication.stage_changedinterview.completedscorecard.readydecision.madedecision.undoneoffer.sentoffer.signedoffer.declineddocument.sentdocument.signeddocument.declinedcandidate.data_request- attemptintegerRequired
- statusstringRequired
pendingsucceededfailed - response_statusinteger | null
- latency_msinteger | null
- response_excerptstring | null
- next_retry_atstring (date-time) | null
- created_atstring (date-time)
EventEnvelope
- idIdRequired
pingapplication.createdapplication.stage_changedinterview.completedscorecard.readydecision.madedecision.undoneoffer.sentoffer.signedoffer.declineddocument.sentdocument.signeddocument.declinedcandidate.data_request- api_version"v1"Required
- created_atstring (date-time)Required
- org_idIdRequired
- dataobjectRequired
PingData
- messagestringRequired
ApplicationCreatedData
- application_idIdRequired
- job_idIdRequired
- candidate_idIdRequired
careers_siteembedapiemail_inboxreferralsourcedjob_board- originstring | nullRequired
Host origin for embed applications
The apply form answers, as on the Application.
StageChangedData
- application_idIdRequired
- job_idIdRequired
- reasonstring | nullRequired
InterviewCompletedData
- interview_idIdRequired
- application_idIdRequired
- kindstringRequired
Always ai today; human interviews are scheduled meetings with feedback, not sessions.
aihuman - completed_atstring (date-time)Required
ScorecardReadyData
- application_idIdRequired
- scorecard_versionintegerRequired
- open_flagsintegerRequired
DecisionMadeData
- decision_idIdRequired
- application_idIdRequired
advanceholdreject
DecisionUndoneData
- decision_idIdRequired
- application_idIdRequired
advanceholdreject
OfferEventData
- offer_idIdRequired
- application_idIdRequired
- candidate_idIdRequired
draftpending_approvalapprovedsentsigneddeclinedexpiredwithdrawn- document_sha256string | null
sha256 of the offer letter PDF as sent (offer.sent and offer.signed)
- signed_sha256string
sha256 of the signed copy (offer.signed)
- expires_onstring (date)
Last day the offer can be signed (offer.sent)
- reasonstring
The candidate's decline reason code (offer.declined)
DocumentEventData
- document_idIdRequired
- kindstringRequired
offeremployment_agreementndacontractor_agreementpolicyother - titlestringRequired
- statusstringRequired
sentcompleteddeclinedvoidedexpired - candidate_idId | nullRequired
- application_idId | nullRequired
- offer_idId | nullRequired
- original_sha256string | nullRequired
sha256 of the PDF as sent
- party_rolestring
The party that signed or declined (document.signed and document.declined)
candidatecompanywitness - completeboolean
True once every party has signed (document.signed)
- signed_sha256string
sha256 of the copy this signature produced, each copy with its own fingerprint (document.signed)
- final_sha256string | null
sha256 of the final copy with every signature and the certificate once complete, else null (document.signed)
DataRequestData
- request_idIdRequired
- candidate_idIdRequired
- kindstringRequired
accessdeletehuman_reviewhuman_interview - due_atstring (date-time)Required