Overview

AI Apply enables you to turn job posting URLs into an API surface for creating applications. Our parser converts any application form into a standardized format that can be programmatically rendered and displayed to candidates. Fields are parsed with all necessary metadata required to render a fully fledged application form. Fields are categorized to enable auto-matching of common fields.
Existing Kombo customer?The Unified API variant of AI Apply works with your current integration, with almost no code changes needed.Reach out to us if you have any questions regarding which API to use.

Flows

Creating a Career Site

The career site entity is a collection of job postings. Create a new career site for each customer that you want to send applications to. Creating a career site can be done via the POST Career Sites endpoint, or in the dashboard.

Parsing a Job Posting

Job posting parsing is asynchronous:
  1. Submit job URL: POST Job Postings endpoint (or via dashboard)
  2. Wait for processing: Default concurrency limit of 5 jobs (reach out if you need higher limits)
  3. Receive webhook: Get notified when parsing completes, or poll via GET Job Postings
Learn about AI Apply webhooks:View our dedicated AI Apply Webhooks page for more information on which webhooks are emitted and how to handle them.
During the alpha, always reach out if a job posting fails to parse successfully. We’ll make sure to fix it as soon as possible.

Adding Query Parameters

Query parameters in the job posting URL affect how the application form is generated and should be handled strategically: Best Practice: Include as many query parameters as possible in the original URL during parsing to maintain form consistency. In rare cases query parameters can affect which fields appear in the application form, so keeping them consistent ensures a stable experience for candidates. For example, ?source=linkedin&utm_campaign=q1 in the parsing URL will:
  • Be preserved throughout the application flow
  • Potentially affect form field visibility or requirements
  • Be combined with any additional parameters added during application submission
In addition, you can add application-specific query parameters (like user tracking IDs) during the /apply call. These will be merged with the original URL parameters.

Sending Applications

Application submission is asynchronous:
  1. Get form & token: POST Inquiries returns the live application form and a one-time submission token. The submission token can be used for one application, and is valid for 12 hours
  2. Submit application: POST Apply with candidate answers (consumes the token if successful)
  3. Receive webhook

QA Mode

Applications that fail during the submission process will not immediately emit a failure webhook.Kombo will QA any failed application and ensure the error does not stem from the submission process. If it does, Kombo will manually submit the application and a success webhook will be emitted.Only after manual QA and confirmation that Kombo has no way of submitting the application, will a failure webhook be emitted.During the alpha phase, you can expect the turnaround time of application QA to be less than 24 hours.

Query Parameters in Applications

When submitting applications via the POST Apply endpoint, you can include additional query parameters using the query_params field. These should be application-specific parameters only (such as user IDs or tracking identifiers). Example use cases for application-time query parameters:
  • User tracking IDs (user_id)
  • Session identifiers
  • A/B test variants
  • Application source attribution (if not already in parsing URL)

Candidate answers

Answers sent with the POST Apply endpoint are expected in the following format:
{
  "submission_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "candidate_email": "john.doe@gmail.com",
  "query_params": {
    "source": "acme",
    "user_id": "8e05b4e5-c586-4d42-8606-b45febad3af3"
  },
  "screening_question_answers": [
    {
      "question_id": "A4zHtGQLF823sNmqy4WxoduFH",
      "answer": "John Doe"
    },
    {
      "question_id": "CDEfHvMGSDnM6pq5HECdE2Kg",
      "answer": "EycufwZHfwcVDmE47X7QN8X2"
    },
    {
      "question_id": "3dT5df2PhyVp7Rze76S5NqrW",
      "answer": {
        "name": "john_doe_resume.pdf",
        "content_type": "application/pdf",
        "data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovT3V0bGluZXMgMiAwIFIKL1BhZ2VzIDMgMCBSCj4+CmVuZG9iag=="
      }
    }
  ]
}
View the below table for an in-depth explanation of each expected input type:
Question typetypeExample
TEXTstring”John Doe”
SINGLE_SELECTstring”BsnL4pAhNQc26uSc4JopTP3P” (Selected option ID)
MULTI_SELECTstring[][“7VMWn39TqeHRT3nW12AXMD9V”, “3Mctc15bypfL44i4KgcVrp6s”] (Selected option IDs)
DATEstring”2021-12-31T23:59:59.000Z” (ISO 8601 date)
NUMBERnumber42
BOOLEANbooleantrue
FILEobject{ "name": "john_doe_resume.pdf", "content_type": "application/pdf", "data": "BASE64..." }

The Application Form

The form uses a block structure with two types:
  • Question Blocks: Individual fields with ID, label, type (TEXT, SINGLE_SELECT, MULTI_SELECT, DATE, NUMBER, BOOLEAN, FILE), and optional conditional display
  • Section Blocks: Containers grouping related questions with a children array

Application Form Example

[
  {
    "block_type": "SECTION",
    "label": "Personal Information",
    "children": [
      {
        "block_type": "QUESTION",
        "question_id": "6VrjehyBk685vubNydiR1hSn",
        "label": "First name",
        "description": null,
        "required": true,
        "question_type": "TEXT",
        "unified_key": "FIRST_NAME",
        "options": null,
        "display_when": null
      }
    ]
  },
  {
    "block_type": "QUESTION",
    "question_id": "EKaumKPGjeA97cb8ystMmkCe",
    "label": "What is your desired working location?",
    "description": "Select your preferred work arrangement",
    "required": true,
    "question_type": "SINGLE_SELECT",
    "unified_key": null,
    "options": [
      {
        "id": "BsnL4pAhNQc26uSc4JopTP3P",
        "label": "Remote",
        "unified_key": null
      },
      {
        "id": "8T4fcKgzLxbKFUo4saXaoMTG",
        "label": "On-site",
        "unified_key": null
      },
      {
        "id": "2cJDK3dq4WNjovohSG7dSpfd",
        "label": "Hybrid",
        "unified_key": null
      }
    ],
    "display_when": null
  },
  {
    "block_type": "QUESTION",
    "question_id": "2H26BKTbDn2ygN2GfEcCsUP8",
    "label": "What timezone are you in?",
    "description": "This helps us schedule meetings at convenient times",
    "required": true,
    "question_type": "TEXT",
    "unified_key": null,
    "options": null,
    // This question will only be displayed if the candidate selected "Remote" in the previous question
    "display_when": {
      "question_id": "EKaumKPGjeA97cb8ystMmkCe",
      "answer_equals": "BsnL4pAhNQc26uSc4JopTP3P"
    }
  }
]

Unified Keys

Standardized identifiers for common fields enable automatic data pre-population:

Conditional Rendering

Displaying Sections Conditionally

Sections should only be displayed when at least one child question’s display_when condition is met The display_when field on a question explains what condition needs to be true for the question to be displayed. Only displayed questions will be validated and must be answered. When display_when is null, the field is not conditional and should always be displayed.

Supported Question Types

Conditional rendering is only supported by the following question types:
  • BOOLEAN - Shows/hides fields based on true/false values
  • SINGLE_SELECT - Shows/hides fields based on selected option ID
  • MULTI_SELECT - Shows/hides fields when ANY of the specified option IDs are selected
The answer_equals property matches the answer format expected in the POST Apply endpoint: