Overview
Jobs represent open positions that candidates can be screened for. You can create jobs, attach interviews and screening questionnaires, assign ATS jobs, and manage job status. Job Families (read-only) provide a taxonomy layer that groups related jobs. Base URL:https://api.prod.qualifi.hr
Authentication: All requests require an x-api-key header.
All responses follow the envelope:
{ "data": { ... }, "meta": { "requestId": "uuid", "timestamp": "ISO-8601" } }.Create Job
Create a new job posting. Endpoint:POST /qsi/gather/jobs
- cURL
- JavaScript
- Python
List Jobs
List jobs with optional filtering and pagination. Endpoint:GET /qsi/gather/jobs
Filter by team UUID
Page number (default: 1)
Items per page (default: 50, max: 100)
Filter by job type
Filter by job status
Filter by department
Filter by location string
Full-text search on job title and description
Pagination: Use
page and pageSize query params. The response includes a pagination object with page, pageSize, total, and totalPages fields.Get Job
Retrieve a single job by ID. Endpoint:GET /qsi/gather/jobs/{id}
UUID of the job
Team UUID (used for access scoping)
jobFamilyIds and knowledgeBaseIds are only returned on the single-get response, not the list endpoint.Update Job
Update job fields (whole-body patch — any subset of optional fields). Endpoint:PATCH /qsi/gather/jobs/{id}
UUID of the job to update
Mutating an ATS-imported job via PATCH returns
409 Conflict. Use the ATS assign endpoint to manage ATS jobs.Archive Job
Archive (soft-delete) a job. The job remains retrievable witharchivedAt set.
Endpoint: DELETE /qsi/gather/jobs/{id}
UUID of the job to archive
Team UUID (used for access scoping)
UUID of the user performing the archive
Unarchive Job
Restore a previously archived job. Endpoint:POST /qsi/gather/jobs/{id}/unarchive
UUID of the job to restore
Attach Interview
Attach an interview to a job. Endpoint:PATCH /qsi/gather/jobs/{id}/interview
UUID of the job
Attach Screening Questionnaire
Attach a screening questionnaire to a job. Endpoint:PATCH /qsi/gather/jobs/{id}/screening-questionnaire
UUID of the job
Assign ATS Job
Assign an ATS job to the current team. Endpoint:POST /qsi/gather/jobs/assign-ats
Unassign Team from Job
Remove the team assignment from a job. Endpoint:DELETE /qsi/gather/jobs/{id}/team-assignment
UUID of the job
Team UUID to unassign
UUID of the user performing the unassignment
JobResponse Field Reference
The following fields may be returned on a job object. Fields marked optional (?) may be absent when not set.
| Field | Type | Description |
|---|---|---|
id | string | UUID of the job |
title | string | Job title |
type | string | Job type. One of requisition, pipeline, template |
status | string | Job status. One of draft, pending_approval, approved, open, on_hold, closed, filled, cancelled, active, paused, archived. Updates are subject to a transition state-machine (an invalid transition returns 400) |
department | string? | Department |
location | string[]? | List of location strings |
workModel | string? | Work model (remote, hybrid, onsite) |
description | string? | Full job description (HTML or plain text) |
descriptionJson | object? | Structured JSON description |
requirements | string? | Requirements text |
requirementsJson | object? | Structured JSON requirements |
shortDescription | string? | Auto-generated brief summary (read-only — not settable via the API) |
tags | string[]? | List of tags |
applyAction | string? | Apply button behavior. One of apply_first, interview_first, chat_to_apply |
organizationId | string | UUID of the owning organization |
teamId | string | UUID of the owning team |
externalId | string? | ID in the external ATS |
externalSlug | string? | Slug in the external ATS |
importSource | string? | Name of the ATS that imported this job |
interviewId | string? | UUID of the attached interview |
meetingId | string? | UUID of the attached meeting |
screeningQuestionnaireId | string? | UUID of the attached screening questionnaire |
assignedRecruiterId | string? | UUID of the assigned recruiter |
createdById | string | UUID of the user who created the job |
createdAt | string | ISO-8601 creation timestamp |
updatedAt | string | ISO-8601 last-updated timestamp |
archivedAt | string? | ISO-8601 archive timestamp; omitted from the response when the job is not archived |
ats | object? | ATS metadata (read-only, see below) |
jobFamilyIds | string[]? | Associated job family UUIDs — single-get only |
knowledgeBaseIds | string[]? | Associated knowledge base UUIDs — single-get only |
ATS Metadata (ats object)
The ats field is read-only and populated from the external ATS. It contains up to 8 sub-fields:
| Field | Type | Description |
|---|---|---|
requisitionId | string? | ATS requisition identifier |
hiringManager | string? | Name or ID of the hiring manager in the ATS |
recruiter | string? | Name or ID of the recruiter in the ATS |
headcount | number? | Target headcount |
salaryRange | object? | { min: number, max: number } |
employmentType | string? | Employment type as reported by the ATS |
openDate | string? | ISO-8601 date the requisition was opened |
closeDate | string? | ISO-8601 date the requisition was closed |
Status Limitation
Status transitions are validated by a state-machine. Updating
status is only permitted along allowed transitions; an invalid transition returns 400 Bad Request with a message of the form Invalid status transition from '...' to '...'. At creation, only draft, pending_approval, and active are accepted — advanced and terminal states (such as open, on_hold, closed, filled, cancelled, paused, archived) are reachable only via subsequent update transitions.API keys cannot approve jobs. On create, setting status: "approved" always returns 403 Forbidden. On update, transitioning a pending_approval job to approved returns 403 Forbidden. Job approvals must be performed through the Humanly dashboard.Error Reference
| Status | Code / Cause | Description |
|---|---|---|
400 | Validation error, disallowed field, or invalid status transition | Request body failed validation, a non-settable field (customFields, crm, ats) was included, or a disallowed status transition was attempted (Invalid status transition from '...' to '...') |
401 | Missing or invalid API key | The x-api-key header is absent, expired, or does not match any team |
403 | Approval not allowed via API, or acting user not a team member | On create, setting status: "approved" always returns 403; on update, transitioning a pending_approval job to approved returns 403. Also returned when the acting userId is not a member of the target team |
404 | Not found / wrong team / unknown user | The job UUID does not exist or does not belong to the authenticated team, or the acting userId does not exist |
409 | ATS-imported job mutation | Attempted to PATCH an ATS-imported job directly; use the ATS assign endpoint instead |
500 | Internal error | An unexpected error occurred while processing the request |
Related Resources
Job Families
Browse the job family taxonomy associated with your jobs
Interviews
Create and manage interviews to attach to jobs

