> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kombo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Apply: Webhooks

> Receive high-signal status updates for Job Postings and Applications.

## Overview

AI Apply is asynchronous by design (form parsing and applications are long-running processes that run in the background).

To keep your system in sync without polling, we emit webhooks whenever a resource reaches a meaningful outcome.

<Tip>
  **First time implementing Kombo webhooks?**

  View our general [Webhooks guide](/hris/guides/webhooks) for more information on delivery, signature validation, and other generic behaviors.
</Tip>

## Job Posting Updated Webhook

### Lifecycle

| Status        | Emits webhook? | Description                                                                |
| ------------- | -------------- | -------------------------------------------------------------------------- |
| `PENDING`     | ❌              | Parsing is queued/processing                                               |
| `APPLYABLE`   | ✅              | Kombo has successfully parsed the job posting. You can submit applications |
| `UNAVAILABLE` | ✅              | Parsing the job posting failed                                             |
| `ARCHIVED`    | ✅              | The job was taken offline or manually archived                             |

<Tip>
  If a parse attempt fails but a previous successful revision still exists, the
  posting remains `APPLYABLE`.
</Tip>

### Payload

The payload matches the job posting schema you receive from the [get job posting endpoint](https://api.kombo.dev/docs/#/AI%20Apply/GetAiApplyPostings).

**Examples**

1. A job posting was successfully parsed.

```json theme={null}
{
  "id": "2Cv6VeT4efBfzvQRudprNx5z",
  "type": "ai-apply-job-posting-status-updated",
  "data": {
    "id": "9QGNv3B98kL3hyELE1qsZ86s",
    "career_site": { "id": "Chc4dua5asAQ48KUERDVF1bs", "label": "Acme" },
    "url": "https://careers.acme.com/jobs/fullstack-engineer-ai-infra-14102",
    "job_code": "ACME_13",
    "created_at": "2025-01-01T00:00:00.000Z",
    "updated_at": "2025-03-02T23:12:32.000Z",
    "archived_at": null,
    "archived_reason": null,
    "availability": "APPLYABLE"
  }
}
```

2. A job posting failed to parse.

```json theme={null}
{
  "id": "2Cv6VeT4efBfzvQRudprNx5z",
  "type": "ai-apply-job-posting-status-updated",
  "data": {
    "id": "9QGNv3B98kL3hyELE1qsZ86s",
    "career_site": { "id": "Chc4dua5asAQ48KUERDVF1bs", "label": "Acme" },
    "url": "https://careers.acme.com/jobs/fullstack-engineer-ai-infra-14102",
    "job_code": "ACME_13",
    "created_at": "2025-01-01T00:00:00.000Z",
    "updated_at": "2025-03-02T23:12:32.000Z",
    "archived_at": null,
    "archived_reason": null,
    "availability": "UNAVAILABLE"
  }
}
```

3. A job posting was taken offline.

```json theme={null}
{
  "id": "2Cv6VeT4efBfzvQRudprNx5z",
  "type": "ai-apply-job-posting-status-updated",
  "data": {
    "id": "9QGNv3B98kL3hyELE1qsZ86s",
    "career_site": { "id": "Chc4dua5asAQ48KUERDVF1bs", "label": "Acme" },
    "url": "https://careers.acme.com/jobs/fullstack-engineer-ai-infra-14102",
    "job_code": "ACME_13",
    "created_at": "2025-01-01T00:00:00.000Z",
    "updated_at": "2025-03-02T23:12:32.000Z",
    "archived_at": "2025-03-10T08:15:00.000Z",
    "archived_reason": "JOB_POSTING_TAKEN_OFFLINE",
    "availability": "ARCHIVED"
  }
}
```

### Handling job posting availability changes

A job posting's `availability` field may switch from being non-applyable to applyable, and vice versa.

As soon as this changes, you should update your UI accordingly.

We recommend either hiding the job from the list of jobs you display to candidates or showing the job URL directly for the candidate to apply on the career site.

<Info>
  Most transitions from being applyable to non-applyable are caused by a job
  posting being archived. In rare cases, a job posting's application form may
  change, triggering a re-parse.
</Info>

## Application Updated Webhook

### Lifecycle

| Status      | Emits webhook? | Description                                                                  |
| ----------- | -------------- | ---------------------------------------------------------------------------- |
| `PENDING`   | ❌              | Our automated system is applying or the application is pending manual review |
| `SUBMITTED` | ✅              | The application was successfully submitted                                   |
| `FAILED`    | ✅              | The application was deemed impossible to submit after human review           |

<Note>
  **When can an application be marked as `FAILED`?**

  If the candidate input is fundamentally invalid, and Kombo has no chance to
  submit the application in the candidate's name without the candidate providing
  more information, the application will be marked as failed. In the future, Kombo
  may support flows of following up with the candidate to collect remaining data
  in an automated manner.

  In rare edge cases, when a job is taken offline while an application is
  in-flight, the application will also be marked as failed.
</Note>

### Payload

The payload follows the application schema you receive from the [get application endpoint](https://api.kombo.dev/docs/#/AI%20Apply/GetAiApplyApplications).

**Examples**

1. Application is automatically submitted

```json theme={null}
{
  "id": "2Cv6VeT4efBfzvQRudprNx5z",
  "type": "ai-apply-application-status-updated",
  "data": {
    "id": "ADbmw5XSkeCSE1fAucoxEGnwZ",
    "job_posting_id": "JDn252PEYa4rMhKbJBjtn3ng",
    "status": "SUBMITTED",
    "candidate_email": "candidate@example.com",
    "proxy_email": "candidate@proxied.com",
    "created_at": "2025-01-01T00:00:00.000Z",
    "updated_at": "2025-03-02T23:12:32.000Z"
  }
}
```

2. Application is submitted after Kombo QA

```json theme={null}
{
  "id": "2Cv6VeT4efBfzvQRudprNx5z",
  "type": "ai-apply-application-status-updated",
  "data": {
    "id": "ADbmw5XSkeCSE1fAucoxEGnwZ",
    "job_posting_id": "JDn252PEYa4rMhKbJBjtn3ng",
    "status": "SUBMITTED",
    "candidate_email": "candidate@example.com",
    "proxy_email": null,
    "created_at": "2025-01-01T00:00:00.000Z",
    "updated_at": "2025-03-03T10:41:02.000Z"
  }
}
```

3. Application is marked as failed by Kombo QA (e.g., invalid candidate input)

```json theme={null}
{
  "id": "2Cv6VeT4efBfzvQRudprNx5z",
  "type": "ai-apply-application-status-updated",
  "data": {
    "id": "ADbmw5XSkeCSE1fAucoxEGnwZ",
    "job_posting_id": "JDn252PEYa4rMhKbJBjtn3ng",
    "status": "FAILED",
    "candidate_email": "candidate@example.com",
    "proxy_email": null,
    "created_at": "2025-01-01T00:00:00.000Z",
    "updated_at": "2025-03-10T08:15:00.000Z"
  }
}
```
