Skip to main content

Overview

Every job posting in AI Apply belongs to a career site, and both can be created one at a time through the API instead of through a job feed. This requires you to manage career site creation and updates to job postings as well. What you send: one request per career site, then one request per job posting, each carrying a URL and the career site it belongs to. What you get: the same job postings a bulk import would produce, parsed and ready to receive applications. Everything after creation is identical: you read postings, request the form, and submit applications the same way.
We recommend job feeds instead. Creating postings by hand is more work to build and leaves you without a way to take postings down. See below before you choose this path.

Why we advise against it

  • You own the bookkeeping. Career site labels are not unique, so sending the same label twice creates a second career site rather than returning the first. Job feeds handle this out of the box.
  • You handle duplicates. A job posting is identified by its career site, URL, and job code. Submitting a posting you already created returns an AI_APPLY.JOB_POSTING_ALREADY_EXISTS error. So you need to keep track of what you already sent to AI Apply and what still needs parsing.

How it works

The posting comes back before parsing has finished, with availability set to PENDING. It becomes APPLYABLE once parsing succeeds, and UNAVAILABLE if it fails. We send an AI Apply data-changed webhook when a job posting’s status changes. See Data fetching for the lifecycle and payloads, or poll GET Job Postings if you would rather not receive webhooks.

Creating a career site

A career site groups job postings under one entity. Create one per employer whose jobs you send us. POST Career Sites takes a label and returns the career site:
Store the returned id. You need it for every posting you create, and there is no way to look a career site up by label: GET Career Sites lists them, but nothing stops two of them sharing a label.
Use a label you can trace back to the source, and keep your own mapping from that source to the returned id. Recreating a career site because the mapping was lost splits one employer’s postings across two entities.

Creating a job posting

POST Job Postings queues a posting for parsing:
General considerations for job postings (query parameters, location, etc.) still apply. See the AI Apply documentation for details.
The response is the job posting, with availability set to PENDING until parsing finishes:
Submitting the same career site, URL, and job code again returns an error rather than a second posting:

Keeping state in sync

Postings you create this way are archived in two cases: when we detect that the job has been taken offline, and when someone archives it in the Kombo Dashboard. Neither transition is dispatched from your system, so you learn about it rather than cause it. Keep your copy current by syncing GET Job Postings with updated_after, triggered by the data-changed webhook or on a schedule. The pattern is described in Data fetching. Before you show a job to a candidate, check availability and archived_at on your copy. Anything you no longer offer that is still APPLYABLE on our side is yours to hide. Job feeds remove this reconciliation entirely: one request replaces the whole list and archives whatever you left out.

API reference