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.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_EXISTSerror. 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, withavailability 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: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.
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.
availability set to PENDING until parsing finishes:
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 withupdated_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.