# AI Apply
Source: https://docs.kombo.dev/ai-apply
Learn how you can use AI Apply to apply to any public job posting.
## 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.
## 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](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyCareerSites) endpoint, or in the dashboard.
### Parsing a Job Posting
Job posting parsing is asynchronous:
1. **Submit job URL**: [POST Job Postings](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyPostings) 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](https://api.kombo.dev/docs/#/AI%20Apply/GetAiApplyPostings)
**Learn about AI Apply webhooks:**
View our dedicated [AI Apply Webhooks](/ai-apply-webhooks) page for more information on which webhooks are emitted and how to handle them.
Reach out if a job posting fails to parse successfully. We'll investigate and try 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.
#### Specifying Job Location
When submitting a job posting for parsing, you can optionally include location details such as the country and postal code.
Providing accurate location data ensures that applications submitted through AI Apply use the intended geolocation context. This can help avoid issues with geofencing or region-based restrictions during the submission process.
If your job postings target specific locations, we recommend always including this information to maximize successful application delivery.
**Examples**
For jobs in the US, specifying the postal code ensures state-level geofencing is properly circumvented:
```json theme={null}
{
"career_site_id": "7pLGzNQ2yECSjFZHgDA6APAu",
"url": "https://www.mybestjobs.com/job/0622",
"location": {
"country": "US",
"postal_code": "94116"
}
}
```
For jobs outside of the US, specifying the country itself is usually sufficient:
```json theme={null}
{
"career_site_id": "FZYx8SKoVQG2Ksvpe5xFp49S",
"url": "https://www.mybestjobs.com/job/5102",
"location": {
"country": "DE"
}
}
```
### Bulk Imports
If you need to import large volumes of job postings at once, or receive data from third-party providers like recruiting agencies, use Job Feeds. Job Feeds automatically handle creating, updating, and archiving job postings based on your data.
See [Job Feeds and Bulk Imports](/ai-apply-job-feeds) for details.
### Sending Applications
Application submission is asynchronous:
1. **Get form & token**: [POST Inquiries](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyPostingsPostingIdInquire) returns the live application form and a one-time submission token. The submission token can be used for one application, and is valid for 2 days
2. **Submit application**: [POST Apply](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyApply) 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.
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](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyApply) 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](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyApply) endpoint are expected in the following format:
```json theme={null}
{
"submission_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"candidate_email": "john.doe@gmail.com",
"query_params": {
"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 type | type | Example |
| -------------- | --------- | ------------------------------------------------------------------------------------------- |
| TEXT | string | "John Doe" |
| SINGLE\_SELECT | string | "BsnL4pAhNQc26uSc4JopTP3P" (Selected option ID) |
| MULTI\_SELECT | string\[] | \["7VMWn39TqeHRT3nW12AXMD9V", "3Mctc15bypfL44i4KgcVrp6s"] (Selected option IDs) |
| DATE | string | "2021-12-31T23:59:59.000Z" (ISO 8601 date) |
| NUMBER | number | 42 |
| BOOLEAN | boolean | true |
| FILE | object | `{ "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
```json theme={null}
[
{
"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:
Fields required for creating and managing user accounts, including login credentials and contact information for account access
| Key | Label | Expected Type |
| ------- | ----- | ------------- |
| `EMAIL` | Email | TEXT |
Fields related to where the candidate currently lives, including full addresses, individual address components, and residence type information
| Key | Label | Expected Type | Options |
| ----------------------- | --------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RESIDENCE_TYPE` | Residence Type | ENUM | `HOME`, `WORK`, `MAILING` |
| `RESIDENCE_FULL_STRING` | Full Residence | TEXT | |
| `RESIDENCE_COUNTRY` | Country | ENUM | `AD`, `AE`, `AF`, `AG`, `AI`, `AL`, `AM`, `AO`, `AQ`, `AR`, `AS`, `AT`, `AU`, `AW`, `AX`, `AZ`, `BA`, `BB`, `BD`, `BE`, `BF`, `BG`, `BH`, `BI`, `BJ`, `BL`, `BM`, `BN`, `BO`, `BQ`, `BR`, `BS`, `BT`, `BV`, `BW`, `BY`, `BZ`, `CA`, `CC`, `CD`, `CF`, `CG`, `CH`, `CI`, `CK`, `CL`, `CM`, `CN`, `CO`, `CR`, `CU`, `CV`, `CW`, `CX`, `CY`, `CZ`, `DE`, `DJ`, `DK`, `DM`, `DO`, `DZ`, `EC`, `EE`, `EG`, `EH`, `ER`, `ES`, `ET`, `FI`, `FJ`, `FK`, `FM`, `FO`, `FR`, `GA`, `GB`, `GD`, `GE`, `GF`, `GG`, `GH`, `GI`, `GL`, `GM`, `GN`, `GP`, `GQ`, `GR`, `GS`, `GT`, `GU`, `GW`, `GY`, `HK`, `HM`, `HN`, `HR`, `HT`, `HU`, `ID`, `IE`, `IL`, `IM`, `IN`, `IO`, `IQ`, `IR`, `IS`, `IT`, `JE`, `JM`, `JO`, `JP`, `KE`, `KG`, `KH`, `KI`, `KM`, `KN`, `KP`, `KR`, `KW`, `KY`, `KZ`, `LA`, `LB`, `LC`, `LI`, `LK`, `LR`, `LS`, `LT`, `LU`, `LV`, `LY`, `MA`, `MC`, `MD`, `ME`, `MF`, `MG`, `MH`, `MK`, `ML`, `MM`, `MN`, `MO`, `MP`, `MQ`, `MR`, `MS`, `MT`, `MU`, `MV`, `MW`, `MX`, `MY`, `MZ`, `NA`, `NC`, `NE`, `NF`, `NG`, `NI`, `NL`, `NO`, `NP`, `NR`, `NU`, `NZ`, `OM`, `PA`, `PE`, `PF`, `PG`, `PH`, `PK`, `PL`, `PM`, `PN`, `PR`, `PS`, `PT`, `PW`, `PY`, `QA`, `RE`, `RO`, `RS`, `RU`, `RW`, `SA`, `SB`, `SC`, `SD`, `SE`, `SG`, `SH`, `SI`, `SJ`, `SK`, `SL`, `SM`, `SN`, `SO`, `SR`, `SS`, `ST`, `SV`, `SX`, `SY`, `SZ`, `TC`, `TD`, `TF`, `TG`, `TH`, `TJ`, `TK`, `TL`, `TM`, `TN`, `TO`, `TR`, `TT`, `TV`, `TW`, `TZ`, `UA`, `UG`, `UM`, `US`, `UY`, `UZ`, `VA`, `VC`, `VE`, `VG`, `VI`, `VN`, `VU`, `WF`, `WS`, `YE`, `YT`, `ZA`, `ZM`, `ZW` |
| `RESIDENCE_CITY` | City | TEXT | |
| `RESIDENCE_STATE` | State/Province/Region | TEXT | |
| `RESIDENCE_LINE_1` | Residence Line 1 | TEXT | |
| `RESIDENCE_LINE_2` | Residence Line 2 | TEXT | |
| `RESIDENCE_ZIP_CODE` | Postal Code | TEXT | |
Fields that require explicit consent or agreement from the candidate, including terms of service, privacy policies, and data usage permissions
| Key | Label | Expected Type |
| ------------------------ | ---------------------- | ------------- |
| `APPLICANT_POOL_CONSENT` | Candidate Pool Consent | BOOLEAN |
| `TERMS_AND_CONDITIONS` | Terms and Conditions | BOOLEAN |
Fields containing basic personal details about the candidate, including names, gender, availability, and personal documents like resumes
| Key | Label | Expected Type | Options |
| --------------------- | ------------------- | ------------- | ----------------------------------------------- |
| `FIRST_NAME` | First Name | TEXT | |
| `LAST_NAME` | Last Name | TEXT | |
| `FULL_NAME` | Full Name | TEXT | |
| `GENDER` | Gender | ENUM | `MALE`, `FEMALE`, `NON_BINARY`, `NOT_SPECIFIED` |
| `EXPECTED_START_DATE` | Expected Start Date | DATE | |
| `RESUME` | Resume | FILE | |
| `BIRTH_DATE` | Birth Date | DATE | |
Fields related to phone numbers and telephonic contact information, including phone types, country codes, national numbers, and extensions.
Keyed fields expect different formats:
* `FULL_PHONE_NUMBER`: E.164 format
* `PHONE_NATIONAL_NUMBER`: national phone number format (e.g. 123 456 7890)
| Key | Label | Expected Type | Options |
| ----------------------- | --------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PHONE_NUMBER_TYPE` | Phone Number Type | ENUM | `MOBILE`, `LANDLINE`, `WORK`, `HOME` |
| `FULL_PHONE_NUMBER` | Full Phone Number | TEXT | |
| `PHONE_COUNTRY_CODE` | Phone Country Code | ENUM | `AD`, `AE`, `AF`, `AG`, `AI`, `AL`, `AM`, `AO`, `AQ`, `AR`, `AS`, `AT`, `AU`, `AW`, `AX`, `AZ`, `BA`, `BB`, `BD`, `BE`, `BF`, `BG`, `BH`, `BI`, `BJ`, `BL`, `BM`, `BN`, `BO`, `BQ`, `BR`, `BS`, `BT`, `BV`, `BW`, `BY`, `BZ`, `CA`, `CC`, `CD`, `CF`, `CG`, `CH`, `CI`, `CK`, `CL`, `CM`, `CN`, `CO`, `CR`, `CU`, `CV`, `CW`, `CX`, `CY`, `CZ`, `DE`, `DJ`, `DK`, `DM`, `DO`, `DZ`, `EC`, `EE`, `EG`, `EH`, `ER`, `ES`, `ET`, `FI`, `FJ`, `FK`, `FM`, `FO`, `FR`, `GA`, `GB`, `GD`, `GE`, `GF`, `GG`, `GH`, `GI`, `GL`, `GM`, `GN`, `GP`, `GQ`, `GR`, `GS`, `GT`, `GU`, `GW`, `GY`, `HK`, `HM`, `HN`, `HR`, `HT`, `HU`, `ID`, `IE`, `IL`, `IM`, `IN`, `IO`, `IQ`, `IR`, `IS`, `IT`, `JE`, `JM`, `JO`, `JP`, `KE`, `KG`, `KH`, `KI`, `KM`, `KN`, `KP`, `KR`, `KW`, `KY`, `KZ`, `LA`, `LB`, `LC`, `LI`, `LK`, `LR`, `LS`, `LT`, `LU`, `LV`, `LY`, `MA`, `MC`, `MD`, `ME`, `MF`, `MG`, `MH`, `MK`, `ML`, `MM`, `MN`, `MO`, `MP`, `MQ`, `MR`, `MS`, `MT`, `MU`, `MV`, `MW`, `MX`, `MY`, `MZ`, `NA`, `NC`, `NE`, `NF`, `NG`, `NI`, `NL`, `NO`, `NP`, `NR`, `NU`, `NZ`, `OM`, `PA`, `PE`, `PF`, `PG`, `PH`, `PK`, `PL`, `PM`, `PN`, `PR`, `PS`, `PT`, `PW`, `PY`, `QA`, `RE`, `RO`, `RS`, `RU`, `RW`, `SA`, `SB`, `SC`, `SD`, `SE`, `SG`, `SH`, `SI`, `SJ`, `SK`, `SL`, `SM`, `SN`, `SO`, `SR`, `SS`, `ST`, `SV`, `SX`, `SY`, `SZ`, `TC`, `TD`, `TF`, `TG`, `TH`, `TJ`, `TK`, `TL`, `TM`, `TN`, `TO`, `TR`, `TT`, `TV`, `TW`, `TZ`, `UA`, `UG`, `UM`, `US`, `UY`, `UZ`, `VA`, `VC`, `VE`, `VG`, `VI`, `VN`, `VU`, `WF`, `WS`, `YE`, `YT`, `ZA`, `ZM`, `ZW` |
| `PHONE_NATIONAL_NUMBER` | Phone National Number | TEXT | |
| `PHONE_EXTENSION` | Phone Extension | TEXT | |
### 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](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyApply) endpoint:
```json theme={null}
// BOOLEAN
{
"block_type": "QUESTION",
"question_id": "has_degree",
"label": "Do you have a college degree?",
"question_type": "BOOLEAN"
},
{
"block_type": "QUESTION",
"question_id": "degree_details",
"label": "What degree do you have?",
"question_type": "TEXT",
"display_when": {
"question_id": "has_degree",
"answer_equals": true // Shows when candidate answers "yes"
}
}
// SINGLE_SELECT
{
"block_type": "QUESTION",
"question_id": "work_location",
"label": "Preferred work location?",
"question_type": "SINGLE_SELECT",
"options": [
{ "id": "remote_id", "label": "Remote" },
{ "id": "office_id", "label": "Office" }
]
},
{
"block_type": "QUESTION",
"question_id": "timezone",
"label": "Your timezone?",
"question_type": "TEXT",
"display_when": {
"question_id": "work_location",
"answer_equals": "remote_id" // Shows only for remote workers
}
}
// MULTI_SELECT
// For `MULTI_SELECT` questions, the condition is met if the candidate's answer
// includes **ANY** of the option IDs specified in `answer_equals`. For example,
// if `answer_equals: ["A", "B"]` and the candidate selects `["B", "C"]`, the
// condition is satisfied because option "B" is present in both.
{
"block_type": "QUESTION",
"question_id": "skills",
"label": "Your skills?",
"question_type": "MULTI_SELECT",
"options": [
{ "id": "python", "label": "Python" },
{ "id": "javascript", "label": "JavaScript" },
{ "id": "rust", "label": "Rust" }
]
},
{
"block_type": "QUESTION",
"question_id": "web_experience",
"label": "Web development experience?",
"question_type": "TEXT",
"display_when": {
"question_id": "skills",
"answer_equals": ["python", "javascript"] // Shows if either selected
}
}
```
# AI Apply: Candidate Account Creation
Source: https://docs.kombo.dev/ai-apply-candidate-account-creation
How our system handles cases when we need to create a candidate account for a job posting.
## Overview
Some job postings require candidates to have an account before they can apply. AI Apply handles this automatically by creating candidate accounts behind the scenes, ensuring applications are submitted successfully without requiring any additional steps from the candidate.
### Account Creation Process
For each application, AI Apply creates a new candidate account in the ATS. This approach ensures that if a candidate applies to multiple job postings from the same employer, each application has its own account and submissions remain independent.
### Email Forwarding
Each application generates a unique email address for the candidate. All emails sent to this address are automatically forwarded to the candidate's actual email address, ensuring they receive all communications from the employer.
### Account Access
After an application is submitted, Kombo sends a confirmation email to the candidate's email address with instructions on how to access their account, including a password reset link.
Kombo doesn't store candidate account passwords. If a candidate wishes to log in directly to their account (for example, their Workday account), they can do so by using the "Reset Password" feature on the Workday login page.
# AI Apply: Job feeds and bulk imports
Source: https://docs.kombo.dev/ai-apply-job-feeds
Learn how you can import high volumes of job postings into AI Apply using Job feeds.
## Overview
General considerations for job postings (query parameters, location, etc.)
still apply. See the [AI Apply documentation](/ai-apply#parsing-a-job-posting)
for details.
Depending on the number of job postings you want to import into AI Apply, adding them one by one can take a long time.
Additionally, you will have to continually keep job postings in AI Apply up to date, archiving and updating them as required.
With job feeds and bulk imports, we will handle this for you! You can import a large number of postings at once and continually send updates to us as you receive them from your providers.
Creating, archiving, and updating job postings are automatically taken care of.
## Job feeds
Bulk imports are managed through Job Feeds. Each job feed represents a self-contained list of jobs from a single source, for example, a Recruiting agency.
Before you can send data for a job feed, you need to create it in the Kombo Dashboard.
Choose clear, descriptive names for Job Feeds. Whenever possible, use the data
source name so you can easily track the origin of imported job postings later.
## How bulk imports work
Each import you send to us includes a newline-separated list of JSON records as a request body. Each record maps to a job posting in AI Apply.
```json theme={null}
{ "url": "https://careers.acme.com/job/1", "career_site_label": "ACME Corp" }
{ "url": "https://careers.acme.com/job/2", "career_site_label": "ACME Corp", "job_code": "ENG-123" }
{ "url": "https://careers.acme.com/job/3", "career_site_label": "ACME Corp", "location": { "country": "US", "postal_code": "94115" } }
```
If any record is invalid or ill-formatted, the import process will be aborted.
You can resume the import at any time after fixing the faulty record by simply re-submitting the request.
The following logic is used to generate career sites, job postings, and job posting statuses from your data:
* Career sites are auto-generated for each unique `career_site_label`.
* Job postings are identified by `url`, `career_site_label`, and `job_code` (same combination means same posting).
* Existing postings are updated; new ones are created and queued for parsing.
* Missing postings are archived automatically (parsed data is preserved for re-import).
**Note:** Job postings imported through different job feeds are always treated
as distinct!
You can find the endpoint in our API documentation: [POST Bulk Import](https://api.kombo.dev/docs/#/AI%20Apply/postAiApplyJobFeedsBulkImport)
# AI Apply: Unified API
Source: https://docs.kombo.dev/ai-apply-unified-api
Learn about the alternate way of using AI Apply, compatible with Kombo's Unified API.
**Deprecation Notice**
The AI Apply Unified API endpoints are no longer actively supported. We recommend migrating to the [standard AI Apply API](/ai-apply) for all new and existing integrations.
## Overview
Whereas the default AI Apply API is a block-based format designed to render
sections and structure as they appear in the remote job posting, the alternate
Unified API variant matches Kombo's core philosophy of hiding standard fields
and allowing you to provide them via standardized API fields on top of the
screening question answers.
## Why use this API?
For existing Kombo customers, this is the fastest way to test AI Apply. Your
existing screening question rendering and submission logic will work without
modification, as the API response schema is identical.
Make sure to understand the differences between the two AI Apply APIs before
choosing one. The default AI Apply API can be found [here](/ai-apply).
## Which API Should You Use?
We recommend the standard [AI Apply API](/ai-apply) for new integrations—it
preserves sections and context, helping candidates better understand questions.
Both APIs support pre-filling data via unified keys.
Use this Unified API variant primarily if you're an existing Kombo customer wanting
compatibility with your current integration. Note that filtering standard fields may
result in a list of screening questions that miss context (e.g. the standard
`FIRST_NAME` and `LAST_NAME` fields are filtered out, leaving an ambiguous middle
name question which is not unified).
## How It Works
Fields that would usually be tagged by `unified_key` in the standard API
(e.g. `FIRST_NAME`) are filtered out and instead provided via the `candidate`
object (e.g. `candidate.first_name`).
Currently, the following fields are filtered out by default:
* **Name fields** (`FIRST_NAME`, `LAST_NAME`, `FULL_NAME`) → Provided via
`candidate.first_name` and `candidate.last_name`
* **Email** (`EMAIL`) → Provided via `candidate.email_address`
* **Phone** (`PHONE_*` fields) → Provided via `candidate.phone_number` as international format
* **Resume** (`RESUME`) → Provided via `attachments` with type `CV`
When you fetch jobs, these fields are automatically removed from the screening
questions.
The filtered fields are configurable to suit your product's need. E.g. if you
only collect first name and last name, you can configure the API to only
filter out the `FIRST_NAME`, `LAST_NAME`, `FULL_NAME` fields, while the
remaining fields are provided via the `screening_question_answers` field.
Reach out to us for setting this up.
## API Endpoints
### Get Jobs
Use the [GET jobs](https://api.kombo.dev/docs/#/AI%20Apply/GetAiApplyUnifiedApiJobs)
to retrieve an array of jobs and their screening questions (with unified fields
filtered out as described above).
### Create Applications
Submit applications using the [POST applications](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyUnifiedApiJobsJobIdApplications)
endpoint. The filtered fields must be provided via the `candidate`/`attachments`
object as described above, with remaining screening questions in the
`screening_question_answers` array.
#### Query Parameters
Unique to AI Apply, you may want to include query parameters in your request
which get used when opening the job posting URL and submitting the application.
For example, you may want to specify a specific user ID to be used for tracking
purposes.
These can be specified in the top-level `query_params` property of the
application submission object. This property is unique to the AI Apply Unified
API, and not available in our core Unified API.
Please make sure to read through our general AI Apply query parameters
documentation to understand which parameters should be added during the [parse
process](/ai-apply#adding-query-parameters), and which parameters should be
added during the [application
process](/ai-apply#query-parameters-in-applications).
#### Example Submission
```json theme={null}
{
"candidate": {
"first_name": "John", // Used for fields of type `FIRST_NAME`, `FULL_NAME`
"last_name": "Doe", // Used for fields of type `LAST_NAME`, `FULL_NAME`
"email_address": "john.doe@example.com", // Used for fields of type `EMAIL`
"phone_number": "+12345678900" // Used for fields of type `PHONE_*`
},
"query_params": {
"user_id": "8e05b4e5-c586-4d42-8606-b45febad3af3"
},
"attachments": [
{
"data_url": "https://example.com/resume.pdf", // Used for fields of type `RESUME`
"name": "John Doe's Resume",
"type": "CV"
}
],
// Screening questions are provided as-usual for any non-filtered fields
"screening_question_answers": [
{
"question_id": "1",
"answer": "I've been working as a software engineer for the past 10 years."
},
{
"question_id": "2",
"answer": "I am allowed to work in the US."
}
]
}
```
## Ready to start using AI Apply?
Getting started with AI Apply is straightforward. Here's what you need to do:
1. **Parse your job postings**: Send the URLs of jobs you want to enable AI Apply for to the [parse job postings endpoint](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyPostings).
2. **Retrieve screening questions**: Continue using the standard [Unified API get jobs endpoint](/ats/v1/get-jobs) in addition to the [AI Apply-compatible get jobs endpoint](https://api.kombo.dev/docs/#/AI%20Apply/GetAiApplyUnifiedApiJobs) to retrieve the jobs from both APIs.
3. **Submit applications**: For jobs that you have parsed via AI Apply, use the [AI Apply-compatible create application endpoint](https://api.kombo.dev/docs/#/AI%20Apply/PostAiApplyUnifiedApiJobsJobIdApplications) instead of the standard [create application endpoint](/ats/v1/post-jobs-job-id-applications).
# AI Apply: Webhooks
Source: https://docs.kombo.dev/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.
**First time implementing Kombo webhooks?**
View our general [Webhooks guide](/hris/guides/webhooks) for more information on delivery, signature validation, and other generic behaviors.
## 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 |
If a parse attempt fails but a previous successful revision still exists, the
posting remains `APPLYABLE`.
### 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.
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.
## 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 |
**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.
### 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"
}
}
```
# Available Assessment Connectors
Source: https://docs.kombo.dev/assessment/connectors
Browse all available Assessment connectors integrated with Kombo
Through Kombo's Unified Assessment API, you can integrate with 19+ Assessment systems.
Please note that this page only lists connectors for Kombo's **Assessment API**. You can also browse our [HRIS connectors](/hris/connectors) and [ATS connectors](/ats/connectors) and [LMS connectors](/lms/connectors).
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
Assessment connector
## Missing something?
We're always expanding our offering of integrations, so if there's a solution that's missing, [let's talk](https://www.kombo.dev/demo)! If you're an existing Kombo customer, please [reach out to support](mailto:support@kombo.dev).
# Ashby Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/ashby
Ashby connector for Kombo's Assessment API
This connector requires a partnership with Ashby. Please contact us to get access.
The Ashby Assessment integration allows you to sync Assessment data between Ashby and your application through Kombo's unified API. The tool slug for this connector is `ashby`.
## Guides and Resources
Step-by-step instructions to connect your Ashby account to Kombo.
Additional documentation and guides for Ashby.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| API Passthrough | |
| Scope Testing | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Ashby
For **Ashby**, we also offer the following other connector variants:
Ashby for the ATS category
# Avature Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/avature
Avature connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.
The Avature Assessment integration allows you to sync Assessment data between Avature and your application through Kombo's unified API. The tool slug for this connector is `avature`.
## Supported Features & Coverage
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| name | |
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
## Integration Variants
**Current connector:** Avature
For **Avature**, we also offer the following other connector variants:
Avature for the ATS category
# Bullhorn Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/bullhorn
Bullhorn connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.
The Bullhorn Assessment integration allows you to sync Assessment data between Bullhorn and your application through Kombo's unified API. The tool slug for this connector is `bullhorn`.
## Guides and Resources
Step-by-step instructions to connect your Bullhorn account to Kombo.
Additional documentation and guides for Bullhorn.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| OAuth | |
| API Passthrough | |
| End User Flow | |
| Manual Trigger | |
## Integration Variants
**Current connector:** Bullhorn
For **Bullhorn**, we also offer the following other connector variants:
Bullhorn for the ATS category
# Eightfold Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/eightfold
Eightfold connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.
The Eightfold Assessment integration allows you to sync Assessment data between Eightfold and your application through Kombo's unified API. The tool slug for this connector is `eightfold`.
## Guides and Resources
Step-by-step instructions to connect your Eightfold account to Kombo.
Additional documentation and guides for Eightfold.
## Supported Features & Coverage
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| name | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| ------------- | ----- |
| Scope Testing | |
| End User Flow | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Eightfold
For **Eightfold**, we also offer the following other connector variants:
Eightfold for the ATS category
# Greenhouse Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/greenhouse
Greenhouse connector for Kombo's Assessment API
This connector requires a partnership with Greenhouse. Please contact us to get access.
The Greenhouse Assessment integration allows you to sync Assessment data between Greenhouse and your application through Kombo's unified API. The tool slug for this connector is `greenhouse`.
## Guides and Resources
Step-by-step instructions to connect your Greenhouse account to Kombo.
Additional documentation and guides for Greenhouse.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
Greenhouse will only display the result of an assessment order' *"result URL"* once the assessment has been completed. This means you may not update an order with the `status` of `OPEN` in Greenhouse. Greenhouse requires the `result_url` to be a valid, publicly accessible link when updating an assessment result. If the URL is invalid or unreachable (for example, localhost or a private network address), Greenhouse will not display any result information provided via the **"Update order result"** [endpoint](`docs.kombo.dev/assessment/v1/put-orders-assessment-order-id-result`).
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| API Passthrough | |
| Scope Testing | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Greenhouse
For **Greenhouse**, we also offer the following other connector variants:
Greenhouse (V1) for the ATS category
# iCIMS Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/icims
iCIMS connector for Kombo's Assessment API
This connector is in closed beta. Please contact us to get access.
The iCIMS Assessment integration allows you to sync Assessment data between iCIMS and your application through Kombo's unified API. The tool slug for this connector is `icims`.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| score | |
| Feature | Notes |
| --------------- | ----- |
| OAuth | |
| API Passthrough | |
| End User Flow | |
| Bulk Invite | |
## Integration Variants
**Current connector:** iCIMS
For **iCIMS**, we also offer the following other connector variants:
iCIMS for the ATS category
# JazzHR Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/jazzhr
JazzHR connector for Kombo's Assessment API
This connector is in closed beta. Please contact us to get access.This connector requires a partnership with JazzHR. Please contact us to get access.
The JazzHR Assessment integration allows you to sync Assessment data between JazzHR and your application through Kombo's unified API. The tool slug for this connector is `jazzhr`.
## Guides and Resources
Step-by-step instructions to connect your JazzHR account to Kombo.
Additional documentation and guides for JazzHR.
## Supported Features & Coverage
| Field | Notes |
| ----------- | ----- |
| first\_name | |
| last\_name | |
| email | |
Results description which are too long(>50 characters after having applied our formatting) will be truncated. This is due to a limitation in how JazzHR handles the results description.
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| Feature | Notes |
| -------------- | ----- |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** JazzHR
For **JazzHR**, we also offer the following other connector variants:
JazzHR for the ATS category
# Jobvite Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/jobvite
Jobvite connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.
The Jobvite Assessment integration allows you to sync Assessment data between Jobvite and your application through Kombo's unified API. The tool slug for this connector is `jobvite`.
## Guides and Resources
Step-by-step instructions to connect your Jobvite account to Kombo.
Additional documentation and guides for Jobvite.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| API Passthrough | |
| Scope Testing | |
| End User Flow | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Jobvite
For **Jobvite**, we also offer the following other connector variants:
Jobvite for the ATS category
# Jobylon Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/jobylon
Jobylon connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.This connector requires a partnership with Jobylon. Please contact us to get access.
The Jobylon Assessment integration allows you to sync Assessment data between Jobylon and your application through Kombo's unified API. The tool slug for this connector is `jobylon`.
## Guides and Resources
Additional documentation and guides for Jobylon.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| Feature | Notes |
| -------------- | ----- |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Jobylon
For **Jobylon**, we also offer the following other connector variants:
Jobylon for the ATS category
# Lever Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/lever
Lever connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.
The Lever Assessment integration allows you to sync Assessment data between Lever and your application through Kombo's unified API. The tool slug for this connector is `lever`.
## Guides and Resources
Additional documentation and guides for Lever.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| Feature | Notes |
| --------------- | ----- |
| OAuth | |
| API Passthrough | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Lever
For **Lever**, we also offer the following other connector variants:
Lever for the ATS category
# Oracle Recruiting Cloud Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/oraclerecruiting
Oracle Recruiting Cloud connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.
The Oracle Recruiting Cloud Assessment integration allows you to sync Assessment data between Oracle Recruiting Cloud and your application through Kombo's unified API. The tool slug for this connector is `oraclerecruiting`.
## Guides and Resources
Step-by-step instructions to connect your Oracle Recruiting Cloud account to Kombo.
Additional documentation and guides for Oracle Recruiting Cloud.
Additional documentation and guides for Oracle Recruiting Cloud.
## Supported Features & Coverage
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| description | |
| location | |
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| Feature | Notes |
| --------------- | ----- |
| API Passthrough | |
| Scope Testing | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
| Dedicated BCM | |
## Integration Variants
**Current connector:** Oracle Recruiting Cloud
For **Oracle Recruiting Cloud**, we also offer the following other connector variants:
Oracle Recruiting Cloud for the ATS category
# PageUp People Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/pageup
PageUp People connector for Kombo's Assessment API
This connector is in closed beta. Please contact us to get access.
The PageUp People Assessment integration allows you to sync Assessment data between PageUp People and your application through Kombo's unified API. The tool slug for this connector is `pageup`.
## Guides and Resources
Additional documentation and guides for PageUp People.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| name | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| API Passthrough | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** PageUp People
For **PageUp People**, we also offer the following other connector variants:
PageUp People for the ATS category
# Tellent Recruitee Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/recruitee
Tellent Recruitee connector for Kombo's Assessment API
This connector requires a partnership with Tellent Recruitee. Please contact us to get access.
The Tellent Recruitee Assessment integration allows you to sync Assessment data between Tellent Recruitee and your application through Kombo's unified API. The tool slug for this connector is `recruitee`.
## Guides and Resources
Additional documentation and guides for Tellent Recruitee.
## Supported Features & Coverage
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
Recruitee requires the `result_url` to be a valid, publicly accessible link when updating an assessment result. If the URL is invalid or unreachable (for example, localhost or a private network address), Recruitee will reject the request for updating an order's result. Recruitee's API only accepts a single result attachment. This means we will only submit the first attachment and omit the rest when we send back the results.
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| API Passthrough | |
| Scope Testing | |
| End User Flow | |
| Manual Trigger | |
## Integration Variants
**Current connector:** Tellent Recruitee
For **Tellent Recruitee**, we also offer the following other connector variants:
Tellent Recruitee for the ATS category
# Kombo Sandbox Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/sandbox
Kombo Sandbox connector for Kombo's Assessment API
The Kombo Sandbox Assessment integration allows you to sync Assessment data between Kombo Sandbox and your application through Kombo's unified API. The tool slug for this connector is `sandbox`.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
Submitted result attachments are not displayed in the ***"Assessment UI"***.
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
## Integration Variants
**Current connector:** Kombo Sandbox
For **Kombo Sandbox**, we also offer the following other connector variants:
Kombo Sandbox for the ATS category
Kombo Sandbox for the HRIS category
Kombo Sandbox for the LMS category
# SmartRecruiters Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/smartrecruiters
SmartRecruiters connector for Kombo's Assessment API
This connector requires a partnership with SmartRecruiters. Please contact us to get access.
The SmartRecruiters Assessment integration allows you to sync Assessment data between SmartRecruiters and your application through Kombo's unified API. The tool slug for this connector is `smartrecruiters`.
## Guides and Resources
Step-by-step instructions to connect your SmartRecruiters account to Kombo.
Additional documentation and guides for SmartRecruiters.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
SmartRecruiters' API requires a test's score and the test's maximum score to be submitted if you wish to write a score for the assessment order. Therefore, we will not submit a score unless you provide **both** the `score` and `max_score` fields. SmartRecruiters' API expects integer values for the `score` and `max_score` fields. If you are submitting floating-point numbers for those fields, we will round them to their nearest integers.
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| --------------- | ----- |
| OAuth | |
| API Passthrough | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
## Integration Variants
**Current connector:** SmartRecruiters
For **SmartRecruiters**, we also offer the following other connector variants:
SmartRecruiters for the ATS category
# SAP SuccessFactors Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/successfactors
SAP SuccessFactors connector for Kombo's Assessment API
The SAP SuccessFactors Assessment integration allows you to sync Assessment data between SAP SuccessFactors and your application through Kombo's unified API. The tool slug for this connector is `successfactors`.
## Guides and Resources
Step-by-step instructions to connect your SAP SuccessFactors account to Kombo.
Additional documentation and guides for SAP SuccessFactors.
Additional documentation and guides for SAP SuccessFactors.
Additional documentation and guides for SAP SuccessFactors.
Additional documentation and guides for SAP SuccessFactors.
Additional documentation and guides for SAP SuccessFactors.
Additional documentation and guides for SAP SuccessFactors.
## General Notes
* SuccessFactors does not allow us to upload assessment test packages via the API. *(**NOTE**: This is **NOT** an issue if you're using SuccessFactors' Background Check module)*. This means the assessment test packages you have set in Kombo need to be uploaded into the SAP Provisioning environment via a CSV file by your customer. You can find the instructions [here](https://help.kombo.dev/hc/en-us/articles/26435142103057-SAP-SuccessFactors-How-do-I-set-up-assessment-test-packages#Enable%20the%20assessment%20integration:~:text=Enable%20the%20assessment%20integration).
**NOTE**: We have implemented a utility to generate an ***"Import Assessment Vendor Packages"*** template pre-populated with the packages that you have set in Kombo for a given linked account. You can find the utility under the ***"Generate Import Vendor Assessment Packages File Template"*** section in the ***"Settings"*** page of any given SuccessFactors Assessment linked account.
* Unfortunately, SuccessFactors' UI will not display any information of the assessment submitted in their assessment portlet unless the assessment is marked as `COMPLETED`. This means the `result_url` or any attributes will not show up in SuccessFactors' UI if you are updating the orders' result with the `status` of `OPEN`
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| max\_score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| ----------------- | ----- |
| API Passthrough | |
| Additional Scopes | |
| Scope Testing | |
| End User Flow | |
| Bulk Invite | |
| Dedicated BCM | |
## Integration Variants
**Current connector:** SAP SuccessFactors
For **SAP SuccessFactors**, we also offer the following other connector variants:
SAP SuccessFactors for the ATS category
SAP SuccessFactors for the HRIS category
SAP SuccessFactors for the LMS category
# Teamtailor Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/teamtailor
Teamtailor connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.This connector requires a partnership with Teamtailor. Please contact us to get access.
The Teamtailor Assessment integration allows you to sync Assessment data between Teamtailor and your application through Kombo's unified API. The tool slug for this connector is `teamtailor`.
## Guides and Resources
Step-by-step instructions to connect your Teamtailor account to Kombo.
Additional documentation and guides for Teamtailor.
Additional documentation and guides for Teamtailor.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
Teamtailor's grading system scales from 0 to 100.
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| ------------- | ----- |
| End User Flow | |
| Bulk Invite | |
## Integration Variants
**Current connector:** Teamtailor
For **Teamtailor**, we also offer the following other connector variants:
Teamtailor for the ATS category
# UKG Pro Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/ukgpro
UKG Pro connector for Kombo's Assessment API
This connector is in open beta. You can freely enable it in your account.This connector requires a partnership with UKG Pro. Please contact us to get access.
The UKG Pro Assessment integration allows you to sync Assessment data between UKG Pro and your application through Kombo's unified API. The tool slug for this connector is `ukgpro`.
## Guides and Resources
Step-by-step instructions to connect your UKG Pro account to Kombo.
Additional documentation and guides for UKG Pro.
Additional documentation and guides for UKG Pro.
## General Notes
* UKG Pro only supports inline assessment flow. Please refer to Kombo's [documentation](https://docs.kombo.dev/assessment/features/inline-assessment) on how to handle inline assessments.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
UKG Pro only accepts assessment `score`s in the inclusive range of `0` to `100`. Please ensure the `score` you pass is within the required range.
| Input Field | Notes |
| --------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| Feature | Notes |
| --------------- | ------------------------------------------------------------------------------------------------------------------ |
| Scope Testing | |
| Per Model Tests | |
| End User Flow | |
| Bulk Invite | UKG Pro only support inline assessment. This means the candidates will be assessed during the application process. |
| Dedicated BCM | |
## Integration Variants
**Current connector:** UKG Pro
For **UKG Pro**, we also offer the following other connector variants:
UKG Pro for the ATS category
UKG Pro for the HRIS category
# Workday Assessment Integration
Source: https://docs.kombo.dev/assessment/connectors/workday
Workday connector for Kombo's Assessment API
The Workday Assessment integration allows you to sync Assessment data between Workday and your application through Kombo's unified API. The tool slug for this connector is `workday`.
## Guides and Resources
Step-by-step instructions to connect your Workday account to Kombo.
Additional documentation and guides for Workday.
Additional documentation and guides for Workday.
Additional documentation and guides for Workday.
## General Notes
* Workday's Assessment module does not allow us to upload assessment test packages via the API *(**NOTE**: This is **NOT** an issue if you're using Workday's Background Check module)*. This means the assessment test packages you have set in Kombo need to be manually entered into Workday by your customer. You can find the instructions [here](https://help.kombo.dev/hc/en-us/articles/19259541378193).
**NOTE**: Once you have set packages for a given linked account in Kombo for a given Workday Assessment linked account, you can generate a CSV that contains a list of packages with their Test Name and Reference ID Value. You can then give the generated file to your customer to help them set up the Assessment tests within their Workday instance. You can find the utility under the ***"Generate Available Packages List"*** section in the ***"Settings"*** page of any given Workday Assessment linked account.
## Supported Features & Coverage
| Field | Notes |
| ------------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| phone\_number | |
| Field | Notes |
| ---------- | ----- |
| remote\_id | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| name | |
| job\_code | |
| description | |
| location | |
| Field | Notes |
| ----------- | ----- |
| remote\_id | |
| first\_name | |
| last\_name | |
| email | |
| Input Field | Notes |
| ------------------------- | ----- |
| assessment\_order\_id | |
| status | |
| result\_url | |
| completed\_at | |
| score | |
| attachments.name | |
| attachments.content\_type | |
| attachments.data\_url | |
| attachments.data | |
| Feature | Notes |
| ----------------- | ----- |
| API Passthrough | |
| Additional Scopes | |
| Scope Testing | |
| End User Flow | |
| Manual Trigger | |
| Bulk Invite | |
| Dedicated BCM | |
## Integration Variants
**Current connector:** Workday
For **Workday**, we also offer the following other connector variants:
Workday for the ATS category
Workday for the HRIS category
Workday for the LMS category
# FAQ
Source: https://docs.kombo.dev/assessment/faq
Frequently Asked Questions
#### Do I have to wait for the first sync to complete?
Yes, during the first sync, customers will need to wait for the process to complete before accessing the latest data. The duration of the first sync depends on the amount of data being synchronized and the efficiency of the data transfer process. Kombo's system will handle the sync and can notify you when it's finished via a webhook.
#### How long does the first sync take?
The duration of the first sync can vary based on factors such as the volume of data (which is influenced by [your scopes](./features/scopes)), network conditions, and the bulk export capabilities of the target system's API.
Generally, you can expect initial syncs to take **just a few minutes** for most integrations. A major exception to this are syncs involving large amounts of historical data. If you, for example, connect a large ATS instance with hundreds of thousands of applications, an initial sync might take **up to several hours** depending on the system.
In these cases, we'd recommend thinking about whether you can reduce the data points you're syncing and [adapting your scope config](./features/scopes). As a job board, you might, for example, only need to [access the applications that you created](/ats/features/application-status-tracking#syncing-only-created-candidates).
#### What should I show my customers during the first sync?
During the very first sync, you should display an informative message to users about the ongoing data update and reassure them that the app is actively fetching and updating data with a loading state or progress indicator.
#### What happens when I change my Kombo scope configuration?
The [Kombo scope configuration](./features/scopes) lets you control the data you read from your customers' systems and communicate this information when they are setting up their integrations.
But once the connection is established, your customer will **not** be forced to accept new changes you made to the scope config. That's because changes to the scope config will often be made for purely technical reasons, like enabling a single new field we expose. In these cases, we don't want to force hundreds of end customers to reconnect their systems.
Thus, when planning to make significant changes to your Kombo scopes, you should communicate this with your customers in advance and give them enough time to react.
**Important note:** Most systems allow specifying specific permissions on the API credentials. If the API credentials don't grant permissions to a specific data point, changing the Kombo scope config can't expose any more data (but it will often make Kombo syncs fail because of authorization errors). In that case, you will actually have to ask your customer to enable the missing permissions on their API credentials to allow you reading those data points.
#### What time zone and format does Kombo use for times and dates?
We return times and dates in the UTC time zone and in the standard UTC format (ISO 8601).
# Assessment UI
Source: https://docs.kombo.dev/assessment/features/assessment-ui
View assessment packages and orders from the Kombo dashboard.
## Overview
The Assessment UI is a visual interface in the Kombo dashboard that allows you to view assessment packages, track orders, and inspect order details for your assessment integrations.
This makes it easy to debug issues, monitor assessment order statuses, and
verify that your integration is working correctly.
## Features
Below are the key features available in the Assessment UI.
The Assessment UI displays all assessment packages for an integration in a
sidebar. Clicking on a package will reveal its orders organised by their
`status`.
Clicking an order opens a sliding drawer that contains the order's details
including the data points contained in the order, the coverage status of the
models and their data points, and the order's result.
Each order displays an activity timeline showing all interactions (create
and update events). Each activity entry will link you to Kombo's
[Logs](/assessment/features/logs) page.
Interaction logs are only stored for 30 days.
## Where to Find the Assessment UI
The Assessment UI is located within individual integration pages in the Kombo
dashboard:
1. **Go to Integrations**: Navigate to the [Integrations page](https://app.kombo.dev/integrations) in your dashboard.
2. **Select an Integration**: Click on any connected assessment integration.
3. **Access Assessment UI**: Click the ***"Assessment UI"*** tab in the integration interface.
# Sandbox Integration
The sandbox integration is built on top of the Assessment UI, and it aims to speed up your development by testing Kombo’s Assessment API end-to-end without needing access to a real ATS.
Use the Assessment Sandbox as your primary development environment to iterate
quickly and test the full lifecycle: creating packages, receiving orders via
webhooks, and submitting results.
### Development Flow
In the Kombo dashboard's [Configuration
page](https://app.kombo.dev/configuration/webhooks), create an [Assessment
Order Received](/assessment/guides/webhooks#assessment-order-received)
webhook configuration.
Go to the [Kombo dashboard](https://app.kombo.dev/) (development
environment), create a new integration, and select the Assessment Sandbox.
Click the ***"Add Package"*** button to open the package creation form.
You can also create packages programmatically via the [Set
Packages](/assessment/v1/put-packages) endpoint. This is useful when you
want to automate your test setup.
Select a package, and click the ***"Create Order"*** button to open the
order form.
Creating an order triggers the [Assessment Order
Received](/assessment/guides/webhooks#assessment-order-received) webhook,
which you should have configured in the dashboard. This is the same webhook
you will receive from a real ATS integration, so you can develop your
webhook handler against it with confidence.
Once an order is triggered through the UI, your application should receive
the new order webhook, process the order, and call the [Update Order
Result](/assessment/v1/put-orders-assessment-order-id-result) endpoint to
submit the result.
After the result is submitted, open the order's details drawer to verify the
result looks correct.
# Audit Logs
Source: https://docs.kombo.dev/assessment/features/audit-logs
Audit sensitive changes to your Kombo environment.
## Use Case
Audit logs are essential for maintaining compliance and security within your
organization. They provide a detailed record of actions taken within your
Kombo environment, helping you track changes, identify unusual activity,
and ensure accountability.
## Accessing Audit Logs
You can access audit logs through the
[Audit Logs section in the Dashboard](https://app.kombo.dev/audit-logs).
Logs are environment-specific, so make sure to select the appropriate environment.
The dashboard allows you to query logs using the provided filter functionality.
## Limitations
Audit logs are available only on and above the scale plan and are retained for
one year, with retention periods of up to three years available on higher plans.
Custom retention policies and automated access to logs are
available on larger plans. If you require these customizations,
please contact Customer Success for assistance.
# Custom Fields
Source: https://docs.kombo.dev/assessment/features/custom-fields
Learn how to extend Kombo's unified data models with additional fields.
## What are Kombo custom fields?
Kombo's unified models cover the fields that are standard across HR, ATS, and other business systems. When your product needs additional read-side data, custom fields let you extend those models with your own stable field keys.
For example, you might add `t_shirt_size` to employees, `benefit_eligibility` to employments, or `source_campaign` to applications. Once a custom field is configured and mapped, Kombo returns it in the `custom_fields` object of the relevant API response.
This makes custom fields a good fit whenever you need a data point that is not part of Kombo's standard unified model, but you still want to read it in an integration-agnostic way.
Custom fields are for **reading** additional data from connected systems.
Looking to **write** extra data when creating candidates or applications? See
[Remote Fields](/extending-the-model#remote-fields). For a full comparison of
all extension mechanisms, see [Extending the Model](/extending-the-model).
## How mappings work
A Kombo custom field is the target field that appears in your API response. A field from the connected system is the source field that provides the value for a specific integration.
The source field can be anything Kombo can discover from the connected system: a standard field in that system, a niche provider-specific field, or a custom field that your customer created in their HR or ATS tool.
For example:
* A Personio employee attribute called **"Favorite Color"** can be mapped to your Kombo custom field `favorite_color`.
* A provider-specific employee field for cost center, employment type, or benefit eligibility can be mapped to a Kombo custom field if your product needs that value and Kombo's standard model does not expose it exactly the way you need.
* Different customers can use different field names, such as **"Favorite Color"** and **"Favourite Colour"**, while your API integration always reads the same Kombo key.
## Setting up custom fields in Kombo
### Create the Kombo custom field
Open [the Dashboard](https://app.kombo.dev/) and click on **Configuration** in the sidebar, then on the **Custom Fields** tab.
Find the relevant data model on the page. In this example, we want to add a field to employees, so click **Add custom field** in the **Employees** section.
Enter the field key that should appear in the API response. Let's call it `favorite_color`. The field key you choose here becomes the key in the `custom_fields` object of every mapped record.
### Prepare the field in the connected system
Sometimes the field you want to map already exists in the connected system. In other cases, your customer may first need to create or expose it there.
Let's take Personio as an example where the source field is a custom attribute in the HR system.
Under **Settings > Employee Information**, you can add new attributes or entire sections to employee profiles. We will add a new attribute called **"Favorite Color"** to the **"Public Profile"** section.
If we now go to the profile of an employee, we can see the new field. Let's set a value for it.
In the case of Personio, we need to let the API key know that we want to expose the new attribute. Go to **Settings > API Credentials**, click on the API key you used to connect to Kombo, then open the **"Readable employee attributes"** section and select the field.
Don't forget to click **save**.
### Map fields manually
To map a field manually, open the overview for the integration. Kombo discovers available fields during syncs, so run a sync first if the field is new or has not appeared yet.
After the sync is finished, open the custom field dropdown for the relevant model and select the field from the connected system that should fill your Kombo custom field.
Don't forget to click **Save changes** to save your changes. After creating the mapping, the next sync will read the source value and return it under your Kombo custom field key.
### Map fields based on live data
For supported integrations, the custom field dropdown also includes a recommended option to **Identify field using live data** (see screenshot above). Click **Open Custom Field Explorer** to search the connected system directly and find the field based on real records.
This is useful when the field name is unclear, or when you know an example value but not the exact field key. For example, you can search for an employee with the value **"Large"** to find the field that stores T-shirt size, then map that field to your Kombo custom field.
If the Explorer is not available for an integration yet, use the regular dropdown mapping flow described above.
### Add automatic mapping rules
On the custom field detail page, you can see how many integrations use the field and which **automatic mapping rules** are defined for it.
Automatic mapping rules tell Kombo which fields of new integrations should automatically be mapped to this Kombo custom field. Each rule matches against a field key or label and can optionally be scoped to a connector. You can add as many rules as you need.
Click **Add rule** to create a new automatic mapping rule.
In the dialog, choose whether the rule should apply to one connector or every integration in the category. Then choose whether Kombo should match against the remote field's key or label, and enter the value to match.
Whenever a sync discovers a field in an integration whose key or label matches one of your rules, its value is automatically mapped to your Kombo custom field. Going back to the Personio example: if you had set up a rule for **"Favorite Color"** scoped to Personio, the next Personio sync would have automatically mapped the value to `favorite_color`.
## Self-Serve Custom Field Configuration
To simplify the mapping process, you can allow your customers to map fields themselves using our self-serve **Setup Flow**. This is especially useful when your customer knows best which field in their system contains the value your Kombo custom field should receive.
Custom fields can be mapped as part of the connection, reducing the need for manual setup.
[Learn more about enabling self-serve field mapping here.](./setup-flow/introduction)
## Accessing custom fields in the API
Each model that supports custom fields has a `custom_fields` attribute. This attribute is a JSON object containing all mapped Kombo custom fields for that record.
When you query the API, you receive mapped custom field values in the `custom_fields` attribute. In this example, we query the [GET /employees](/hris/v1/get-employees) endpoint.
The value of a custom field mirrors what is returned by the underlying API. It is not always a string; it can also be a number, boolean, object, or array.
```json {7-17} theme={null}
{
"status": "success",
"data": {
"results": [
{
...
"custom_fields": {
"favorite_color": "blue",
"manager": {
"name": "Frank"
},
"reports": [
{
"name": "Tom"
}
]
}
}
]
}
}
```
# Deletion Policy
Source: https://docs.kombo.dev/assessment/features/deletion-policy
Understand how Kombo deletes data.
## General
Kombo prioritizes privacy and security by cleaning up any data that is no longer
used. We do that by following the deletion policies below. Kombo will not store
any sensitive data for longer than needed.
## Integration Data
### Case: an entry is not found anymore
When Kombo can't find an entry during a sync, we will mark it with
`remote_deleted_at` and 14 days later set all the fields to `null`.
### Case: an integration has been deleted
Kombo will delete all the data of an integration **14 days** after the integration
was deleted via API or UI.
### Case: scope config changed
**Field is turned off:** While running the next sync, Kombo will overwrite
the turned-off field for all entries with the value `null`.
**Model is turned off:** When a model gets turned off, Kombo will mark all entries with `remote_deleted_at`
and delete the entries after **14 days**.
***
## Logs
Kombo will delete statistics about syncs and write actions after **60 days**.
On all plans but the enterprise plan, Kombo will delete request data in the logs,
including the request and the response after **30 days**.
# Inline Assessment
Source: https://docs.kombo.dev/assessment/features/inline-assessment
How to handle inline assessment webhooks
In an inline assessment flow, the candidate will be assessed immediately after applying to a job via a career page. The ATS expects a URL to your platform so that the candidate can be redirected to your product to take the test.
### Reacting to new inline assessment orders
Unlike the default assessment flow, we will send out an `inline-assessment:order-received` webhook when we receive an order. The webhook will contain the following payload:
```json inline-assessment:order-received theme={null}
{
"id": "8KNLzKfRXjJ3Xjfaz5FkgdPA",
"type": "inline-assessment:order-received",
"data": {
"id": "B5KQKhAgTv6ZwzrfAbqbhipd",
"integration_id": "workday:CBNMt7dSNCzBdnRTx87dev4E",
"package_id": "typescript_test",
"status": "OPEN",
"candidate": {
"remote_id": "12345",
"email": "john.doe@gmail.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+1 123 456 7890"
},
"application": {
"remote_id": "54321"
},
"job": {
"remote_id": "67890",
"name": "Bottle Opener",
"job_code": "BO-2024-01",
"description": "
We are looking for a skilled and energetic individual to join our team as the chief bottle open officer. This unique role requires precision, attention to detail, and the ability to handle a high volume of beverage bottles in a fast-paced environment. The ideal candidate will ensure bottles are opened swiftly and safely while maintaining hygiene standards.
",
"location": {
"street_1": "Lohmühlenstraße 65",
"city": "Berlin",
"state": "Berlin",
"zip_code": "12435",
"country": "DE",
"raw": "Berlin, Germany"
},
"hiring_team": [
{
"first_name": "Jane",
"last_name": "Doe",
"remote_id": "78901",
"email": "jane.doe@gmail.com",
"hiring_team_roles": ["RECRUITER"]
}
]
}
}
}
```
It is required that you respond with a body that contains a link to your platform where the candidate will be assessed:
```json theme={null}
{
"assessment_url": "https://app.acme.com/assessment/:test_id"
}
```
Most ATSs will terminate their request for an assessment after 15 to 30
seconds, this means you should respond to us as soon as possible to ensure the
order is created successfully.
# Integration Fields
Source: https://docs.kombo.dev/assessment/features/integration-fields
Learn how to use integration fields to read additional data properties from your customer's systems.
The Integration Fields API was built for a very specific niche use case. This
is likely not what you want to use. See [Custom Fields](./custom-fields)
instead.
## What is an integration field
An integration field is a field returned from the raw response of the remote system.
## Setting up integration fields in Kombo
Before we set up the integration field in Kombo, let's talk about how you will receive the data.
Each model that supports integration fields has an `integration_fields` attribute. This attribute is an Array of JSON objects that contains all selected integration fields. We will discuss how to select integration fields in a [later step](#selecting-an-integration-field).
### View available integration fields
To list which integration fields are available for a specific integration, you should use our [GET integration-fields](../v1/get-integrations-integration-id-integration-fields) endpoint.
Example response:
```JSON theme={null}
{
"status": "success",
"data": {
"results": [
{
"id": "123AbcDEFG4hijK5Lmn67OPq",
"key": "dynamic_5487319",
"model": "hris_employees",
"type": "CUSTOM",
"label": "Name of health insurance",
"is_passthrough_enabled": false
},
...
]
},
"next_cursor": null
}
```
If your array is empty or does not contain the values that you are looking for, double check if "integration fields" is enabled for the specific model in your [scope config](https://app.kombo.dev/scope-config).
Please note that this endpoint is paginated, featuring a default page size of
250 and a maximum page size of 2000 (specified via the `page_size` parameter).
### Selecting an integration field
To select an integration field to be passed through, use the [PATCH integration-fields](../v1/patch-integrations-integration-id-integration-fields-integration-field-id) endpoint.
An example payload would look like this:
```JSON theme={null}
{
"enable_passthrough": true
}
```
Example response:
```JSON theme={null}
{
"status": "success",
"data": {
"id": "123AbcDEFG4hijK5Lmn67OPq",
"key": "dynamic_5487319",
"model": "hris_employees",
"type": "CUSTOM",
"label": "Name of health insurance",
"is_passthrough_enabled": true
}
}
```
After successfully enabling passthrough on an integration field, the **next sync** will collect the values for the selected field and save them. These values then become part of our API response as follows:
## Getting integration fields as part of the API response
When you query the API, you will receive any selected integration fields in the `integration_fields` attribute. In this case, we query the [GET /employees](/hris/v1/get-employees) endpoint.
The value of an integration field mirrors what is returned by the underlying API (i.e. it's not always a `string` but can be a `number` or even an `object` too).
```JSON theme={null}
{
"status": "success",
"data": {
"results": [
{
"first_name": "Frank",
...,
"integration_fields": [
{
"id": "123AbcDEFG4hijK5Lmn67OPq",
"key": "dynamic_5487319",
"type": "CUSTOM",
"value": "National Health",
"label": "Name of health insurance"
}
],
...
}
]
}
}
```
# Issue types
Source: https://docs.kombo.dev/assessment/features/issue-types
All customer-visible issue types Kombo can raise, and when they are created and resolved.
Kombo [raises an issue](./issues) when a condition is true and resolves it when that condition clears. This page lists every customer-visible type. Internal-only types are not included.
`issue.type` on the [`issue-status-changed`](../guides/webhooks#issue-status-changed) webhook is the identifier shown under each heading. We add types over time, so your handler should treat `issue.type` as an open set and not fail on unknown values.
## Authentication failed
Type: `integration.authentication_failed`
Raised when Kombo cannot authenticate with the connected tool. That happens when a sync's connection test fails with an authentication error, or when a scheduled OAuth credential refresh fails because the credentials are invalid. Rate limits during a sync do not raise this issue.
Resolved when a later sync successfully tests the connection, or when OAuth credentials refresh successfully.
## Action failing
Type: `integration.action_failing`
Raised when at least 50% of the finished calls for a specific action on an integration have failed in the last 24 hours, and there have been at least 5 finished calls in that window. Kombo checks this after each action call.
Resolved when a later check finds fewer than 5 finished calls in the window, or a failure rate below 50%. If the action is not called again, the issue also resolves 24 hours after it was last raised.
## Incoming webhooks failing
Type: `integration.incoming_webhook_failing`
Raised when at least 50% of the incoming webhooks for an integration have failed in the last 6 hours, and there have been at least 5 incoming webhooks in that window. Kombo checks this after it receives a webhook from the tool.
Resolved when at least 5 incoming webhooks in the last 6 hours have a failure rate below 50%. It stays open if webhooks stop, or if fewer than 5 have arrived in the window.
# Issues
Source: https://docs.kombo.dev/assessment/features/issues
See which integrations need attention, and how long the problem has been going on.
When an integration starts failing, you want to know about it before your customer does. Issues put those problems on the dashboard as soon as Kombo observes them, so you can act before the end customer complains.
The integrations list shows an issue count on any integration that currently has an open issue. Hover the count to see the title and how long Kombo has been observing it.
Open the integration to read what is wrong and what to do next.
## What an issue is
Kombo's issues track a problem of an integration over time. Kombo raises them when a condition is true (for example, authentication is failing) and keeps it open while that condition is still observed. When the condition clears, the issue resolves on its own.
Each issue tells you:
* what is broken
* how to investigate or fix it
* when Kombo first observed it, and when it last saw it again
See [all issue types](./issue-types) for when each one is raised and resolved. More types will follow.
## What to do when you see one
1. Open the integration from the list.
2. Read the issue. Follow the linked [logs](./logs) if you need the underlying requests.
3. If credentials are invalid, [reconnect the integration](../guides/connect/reconnection).
The [integration state](../guides/integration-states) on the same page is the current snapshot (`Active`, `Sync failing`, `Authentication failing`). The issue is the durable record that the problem is still happening, and for how long.
You can snooze an issue to hide it in the Kombo dashboard for a while. Snoozing only affects the UI. The issue stays open, Kombo keeps observing it, and it does not send an [`issue-status-changed`](../guides/webhooks#issue-status-changed) webhook.
Subscribe to that webhook to get raised and resolved events as they happen. Slack notifications will follow.
When each issue type is raised and resolved.
Inspect the requests behind a failing sync or action.
Restore credentials when authentication has failed.
Read the current operational status of an integration.
Get raised and resolved issue events as they happen.
# Komboman
Source: https://docs.kombo.dev/assessment/features/komboman
Test and troubleshoot both Kombo API and passthrough API calls with our built-in API client.
## Overview
Komboman is a powerful API testing tool built directly into the Kombo dashboard that allows you to test, explore, and troubleshoot both Kombo's unified API endpoints and integration-specific passthrough API calls. It provides a convenient way to interact with APIs without requiring you to provide any authentication credentials.
## Key Benefits
* **Test Kombo API Endpoints**: Validate Kombo's unified API responses and test data models directly
* **Test Passthrough Functionality**: Quickly verify the functionality of integration-specific API endpoints
* **Troubleshoot Data Quality Issues**: Identify and resolve data format or content issues directly
* **Self-Service Debugging**: Diagnose and resolve API issues independently
* **Request History**: Save and revisit previous API requests for reference and troubleshooting
* **Simplified Authentication**: No need to manage API keys or tokens separately - we handle the authentication
## Supported API Types
### Kombo API
Test Kombo's unified API endpoints directly from the dashboard, including all HRIS, ATS, and general endpoints like `/hris/employees`, `/ats/jobs`, `/ats/applications`, `/integrations/{integration_id}`, etc. Automatic authentication and audit logging are included.
### Passthrough APIs
Test integration-specific APIs for connected tools to access native functionality not covered by unified endpoints and debug integration-specific issues.
## How It Works
Komboman provides an intuitive interface for working with both API types:
1. **Select API Type**: Choose between "kombo" (unified API) or integration-specific passthrough APIs
2. **Configure Request**: Set the HTTP method, path, query parameters, and body for your request
3. **Send and View Responses**: Instantly see the API response, including status codes and data
4. **Save Request History**: Automatically save your requests for future reference
## Where to Find Komboman
Komboman is located within individual integration pages in the Kombo dashboard:
1. **Go to Integrations**: Navigate to the [Integrations page](https://app.kombo.dev/integrations) in your dashboard
2. **Select an Integration**: Click on any connected integration from your list
3. **Access Komboman**: Click the "Komboman" tab in the integration interface
## Getting Started
To use Komboman:
1. Select the desired API from the dropdown:
* **"kombo"** - Test Kombo's unified API endpoints for the selected integration.
* **Integration-specific APIs** - Test passthrough functionality
2. Configure your request with the appropriate method, path, and payload
3. Send your request and analyze the response
### Testing Kombo API Endpoints
When testing Kombo API endpoints, select "kombo" from the API dropdown and enter the endpoint path (e.g., `/employees`, `/jobs`, `/applications`). Refere to our API reference for all available endpoints. All requests are automatically authenticated and audit logged.
### Testing Passthrough APIs
When testing integration-specific passthrough APIs, select the appropriate passthrough API from the dropdown and configure the request according to the integration's native API documentation which is linked on the selected API.
Komboman works directly with our [Passthrough API](./passthrough-api), which enables you to interact with the native APIs of specific integrations while we handle the authentication.
## Access Permissions
Komboman is available to:
* **Production Environment**: Users with admin role
* **Development Environment**: Users with admin or developer role
# Logs
Source: https://docs.kombo.dev/assessment/features/logs
Learn how Kombo's logs allow you to monitor and troubleshoot your integrations.
## Overview
Our logs enable you to dig deeper into what is happening behind your integrations. Depending on the type of interaction, different logs are available.
You can find the logs in the [sidebar of the Kombo dashboard](https://app.kombo.dev/logs).
### Available Log types
| Log Type | Description | Features |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| **Sync** | Created for each recurring sync of an integration | [Sync Metrics](#sync-metrics), [Request Logs](#request-logs) |
| **Connection Flow** | Created for each connection flow interaction | [Event Logs](#connection-flow-event-logs), [Request Logs](#request-logs) |
| **Action** | Created whenever Kombo receives an API request which triggers Kombo to make external API requests to a tool. E.g. [create application](/ats/v1/post-jobs-job-id-applications) | [Request Logs](#request-logs) |
| **Passthrough** | Created for each [passthrough](./passthrough-api) request made | [Request Logs](#request-logs) |
| **Incoming Webhook** | Created whenever a tool sends an API request to Kombo | [Request Logs](#request-logs) |
### Filters
Use filters to narrow your search and find exactly what you're searching for.
We additionally make sure to link back to any logs from relevant dashboard pages. For example, you can instantly query an integration's logs by clicking "logs" on the integration's details page.
## Request Logs
Request logs help you see any API requests that Kombo is making to the integrated tool, and debug any issues. If an integration is having issues, request logs let you deep dive into understanding which endpoints are causing problems, such as finding requests returning `403` status codes for missing permissions.
### Viewing Details
Click on a row to view details of the API request. Kombo will redact any sensitive data.
You can view the response of the request by clicking on **Open response**.
### Retention
By default, Kombo stores logs for 30 days. Longer retentions are available upon request on the enterprise plan.
## Connection Flow Event Logs
We store any decisive events that happen throughout the connection flow to enable you to understand exactly what your customer is experiencing. This visibility lets you detect what is preventing your customers from connecting their tool, and ultimately reach out to them with the right help to complete the integration.
View your current connection flow logs in the [Kombo dashboard](https://app.kombo.dev/logs?kind=CONNECTION_FLOW).
### Identifying User Sessions
The logs are grouped by user sessions, with a 'broken' line indicating a break between two sessions. Viewing sessions allows you to gain insights on when a user exited and/or re-entered the connection flow.
## Sync Metrics
The sync metrics tab allows you to gain insights into which data was read and whether any issues occurred. Use this to quickly verify that the expected data is being synced without having to make any API calls.
# Passthrough API
Source: https://docs.kombo.dev/assessment/features/passthrough-api
Implement any edge case feature with our passthrough API.
## Overview
The Passthrough API lets you call the native API of any connected integration directly, while Kombo handles authentication for you. This bridges the gap between the unified API and integration-specific requirements — you get the consistency of Kombo's auth layer with the flexibility of the underlying tool's full API surface.
## When to Use It
Use the Passthrough API when you need integration-specific data or actions that the unified API does not cover. Common examples:
* Reading provider-specific resources (e.g., HiBob work history, Workday compensation plans)
* Calling write endpoints that Kombo doesn't offer as a unified action
* Accessing tool-specific configuration (e.g., ATS picklists, custom templates)
For reading additional fields on standard models, prefer [custom
fields](./custom-fields) — they're simpler and work across integrations.
[Integration fields](./integration-fields) cover a narrow niche and are rarely
the right choice. The Passthrough API is best for accessing entirely different
endpoints or performing writes that aren't part of the unified API.
## How It Works
1. **Authentication**: Authenticate with your Kombo API key as usual. Kombo forwards the request with the correct tool-specific credentials.
2. **Choose the API**: Find the API identifier for your integration in the [passthrough endpoint reference](../v1/post-passthrough-tool-api).
3. **Build your request**: Specify the HTTP method, endpoint path, headers, query parameters, and request body — exactly as the tool's native API expects.
## The `api_options` Parameter
Most integrations don't require `api_options` — simply set the `path` and Kombo routes to the right API.
However, some integrations have multiple underlying APIs or services that share the same authentication but use different base URLs or protocols. For these, `api_options` tells Kombo which specific service to target.
Integrations that use `api_options` document the required fields directly on their passthrough endpoint specification. Common examples:
* **Workday REST**: requires `service_name` (e.g., `"staffing"`, `"compensation"`) and optionally `version` to select the correct REST service
* **Workday SOAP**: requires `service_name` (e.g., `"Staffing"`, `"Recruiting"`) and optionally `service_version` to target the right SOAP service
* **SOAP-based tools** (Nmbrs, HR Office, Taleo): require `service_name` or `operation_name` to route to the correct SOAP service
If an integration doesn't document `api_options`, you don't need to provide it.
## Testing with Komboman
Use [Komboman](./komboman), the built-in API client in the Kombo dashboard, to test passthrough calls interactively. It handles authentication automatically and saves request history, making it easy to experiment with native API endpoints.
Find the full passthrough endpoint specification [here](../v1/post-passthrough-tool-api).
# Remapping array fields
Source: https://docs.kombo.dev/assessment/features/remapping/array-remapping
Learn how to use the remapping feature to adjust Kombo array fields based on fields in your customer's systems.
## Remapping an array field
Array fields in the Kombo data model can have multiple entries per entity. For example our HRIS employee can have multiple `bank_accounts` and an ATS candidate can have multiple `email_addresses`.
These fields will offer two mapping modes: `Replace` and `Append`
This will decide wether you would like to persist the Kombo default mappings in
the array or replace the array entirely.
After deciding on the mapping mode you can start adding entries to the array. Please note that all required fields for an entry need to be mapped.
For `bank_accounts` you need to select an account type before the fields show up. You can mix multiple types in the array.
## Fallbacks
Fallbacks are not available for these fields. Instead you can add multiple values to the array. If any required field (marked with red asterix) of single entry is missing, the entry will not be added to the array.
# Remapping date fields
Source: https://docs.kombo.dev/assessment/features/remapping/date-remapping
Learn how to use the remapping feature to adjust Kombo date fields based on fields in your customer's systems.
## Remapping a date field
1. Select the source field of the date. It can bei either a string or number.
2. Pick a date format from our presets or choose `Custom format`.
3. (optional) If you have custom field examples enabled we will display a validation section below. Adjust the format until the dates are parsed as desired.
4. Press the `Save configuration` button on the bottom right.
# Remapping enum fields
Source: https://docs.kombo.dev/assessment/features/remapping/enum-remapping
Learn how to use the remapping feature to adjust Kombo enum fields based on fields in your customer's systems.
## Remapping an enum field
1. Select the source field to map the enum from.
2. Define a default value. This will be the result in case the value is not mapped or null. If you want to use `fallbacks` make sure to select `None (null)` here.
3. Define an enum map. For this you first input the source string on the left. Then click the `Add mapping` button.
After adding the source string, select one of the Kombo enum values.
# Introduction
Source: https://docs.kombo.dev/assessment/features/remapping/introduction
Learn how to use the remapping feature to adjust Kombo default fields based on fields in your customer's systems.
## Prerequisits
The remapping UI is located on each individual integration right next to the "Custom Field Mappings" tab.
1. Your scope config for the integration will need either `custom_fields` or `integration_fields` **enabled for each model** you wish to remapp.
2. The initial sync has **finished successfully** and the integration is **not in QA mode**.
3. (optional) To improve your mapping experience we recommend enabling custom field examples for new integrations. The setting can be found under `Configuration` in the left sidebar.
We offer different user interfaces to accomedate the complexity that comes with each specific field:
1. [Simple string/number/boolean fields](./simple-remapping)
2. [Enum fields](./enum-remapping)
3. [Date fields](./date-remapping)
4. [Address fields](./struct-remapping)
5. [Reference fields](./reference-remapping)
6. [Array fields](./array-remapping)
Additionally, you can use the [Kombo Default Fallback](./kombo-default-fallback) to include Kombo's standard mapping logic as a priority in your fallback chain — available for simple, enum, and date fields.
# Kombo default fallback
Source: https://docs.kombo.dev/assessment/features/remapping/kombo-default-fallback
Learn how to use Kombo's standard mapping logic as a fallback priority in your remapping configuration, giving you full control over the mapping order.
## What is the Kombo Default Fallback?
When you [override a field mapping](./introduction), you replace Kombo's built-in mapping logic with your own custom configuration. This is powerful, but sometimes you don't want to *replace* Kombo's logic entirely — you want to **combine** your custom mapping with Kombo's standard logic in a specific priority order.
The **Kombo Default Fallback** lets you insert Kombo's standard mapping logic as one of the priorities in your fallback chain. This means you can:
* Use a custom integration field as the primary source, and **fall back to Kombo's default** if that field is empty
* Use Kombo's default mapping as the **primary value**, but override it with a custom field when Kombo's value is empty
* Place Kombo's default logic **between** two custom field sources in a multi-level fallback chain
The Kombo Default Fallback is available for **simple** (string, number,
boolean), **enum**, and **date** field remappings. It is not available for
address, reference, or array field types.
## When should you use it?
Consider using the Kombo Default Fallback when:
* **Kombo's default mapping works well in most cases**, but a small number of your customer's records store the value in a different field. You can set Kombo's default as Priority 1 and your custom field as a fallback.
* **A custom field is your preferred source**, but it isn't always populated. By adding Kombo's default as a fallback, you ensure no data is lost when the custom field is empty.
* **You want to experiment with a custom mapping** without losing the safety net of Kombo's proven default logic. If your custom source produces `null`, Kombo's standard mapping takes over automatically.
## How it works
The remapping engine evaluates your fallback chain **from top to bottom** (Priority 1 first, then Priority 2, and so on). For each record (employee, candidate, job, etc.), it checks each priority in order and **stops as soon as a valid, non-empty value is found**.
When the engine reaches a "Default Kombo value" entry in the chain, it uses the value that Kombo's standard mapping logic would have produced for that field — exactly as if no remapping had been configured.
### Example: Custom field with Kombo default as safety net
Suppose you want to map the `first_name` field from a custom integration field called `preferred_name`, but not every record has a preferred name set.
| Priority | Source | Behavior |
| -------- | ------------------------------------ | ---------------------------------------------------------------------------------- |
| 1 | `preferred_name` (integration field) | Used when the field has a value |
| 2 | Default Kombo value | Falls back to Kombo's standard `first_name` mapping when `preferred_name` is empty |
**Result**: Records with a `preferred_name` get that value. Records without it seamlessly fall back to whatever Kombo would have mapped by default.
### Example: Kombo default with a custom override
You trust Kombo's mapping for most records, but for a few edge cases you know a specific integration field has better data.
| Priority | Source | Behavior |
| -------- | ---------------------------------- | ------------------------------------------------------ |
| 1 | Default Kombo value | Used when Kombo's standard mapping produces a value |
| 2 | `backup_field` (integration field) | Only used when Kombo's default mapping produces `null` |
**Result**: Kombo's default logic runs first. Only when it returns nothing does the system check `backup_field`.
## Adding a Kombo Default Fallback
1. Open the remapping modal for the field you want to configure (see [simple](./simple-remapping), [enum](./enum-remapping), or [date](./date-remapping) remapping for details on how to open the modal).
2. At the bottom of the modal, click the **Fallback to Kombo's mapping** button.
3. A new priority entry will appear showing **"Default Kombo value"** with the description *"Uses Kombo's standard mapping logic for this field."*
4. You can **reorder** priorities by removing and re-adding entries. The Kombo Default Fallback can be placed at any position in the fallback chain — it does not have to be last.
5. Click **Save** to apply the configuration. Remember that **a sync is required** for saved changes to take effect.
## Combining with other fallbacks
You can freely mix Kombo Default entries with custom integration field entries. For example, a three-level fallback chain for an enum field might look like:
| Priority | Source |
| -------- | ----------------------------------------------------------- |
| 1 | `custom_status_field` (integration field) with enum mapping |
| 2 | Default Kombo value |
| 3 | `legacy_status_field` (integration field) with enum mapping |
The engine will try `custom_status_field` first. If it's empty, it falls back to Kombo's default enum mapping. If even that produces `null`, it tries `legacy_status_field` as a last resort.
If the **only** entry in your fallback chain is a Kombo Default, the
configuration is equivalent to having no remapping at all. In this case, the
system will automatically clear the remapping configuration when you save.
## Supported field types
| Field type | Kombo Default Fallback supported |
| ------------------------------------------------------ | -------------------------------- |
| [Simple](./simple-remapping) (string, number, boolean) | Yes |
| [Enum](./enum-remapping) | Yes |
| [Date](./date-remapping) | Yes |
| [Address](./struct-remapping) | No |
| [Reference](./reference-remapping) | No |
| [Array](./array-remapping) | No |
# Remapping reference fields
Source: https://docs.kombo.dev/assessment/features/remapping/reference-remapping
Learn how to use the remapping feature to adjust Kombo reference fields based on fields in your customer's systems.
## Remapping an reference field
Reference fields are fields that reference related entities. For example our employee model has three reference fields: manager\_id, legal\_entity\_id and work\_location.
These fields can offer up to two mapping types.
## Refernce existing record
1. When choosing `Refernce existing record` the model will be linked to an already existing record.
2. You will need to select a field that contains the same remote id as the model you wish to reference.
If the referenced record does not exist, it will be created but all other
fields except the id will be `null`.
## Create new record with mapped data
1. When choosing `Create new record with mapped data` the model will be linked to a new record. You will be able to create a new work location, legal entity, etc.
2. Fill the the remote id with the unique identifier you want to use for the new record.
3. Then fill the rest of the properties.
You will be able to receive the new record on both the `/employees` endpoint, as well as the relations own endpoint (`/work-locations`, `/legal-entities`).
Note: This option is not available for all reference fields.
# Remapping simple fields
Source: https://docs.kombo.dev/assessment/features/remapping/simple-remapping
Learn how to use the remapping feature to adjust simple Kombo default fields based on fields in your customer's systems.
## Remapping a simple string/number/boolean field
To start the remapping process open the remapping UI and click on the `Override default Kombo value` button of the field you want to remapp.
A new popup will
appear allowing you to configure the remapping for the individual field.
Under `Priority 1` you can select the source field you would like to use for the
remapping. You can search in the selection box, see the example values and even
use our custom field explorer feature.
After selecting the field, you can press the `Save` button to save the
configuration.
If this is your first remapping, a popup will appear, which reminds you that **a
sync is required** for the saved changes to show their effect.
## Fallbacks
In case the selected field is removed (`undefined`), `null` or changes it's structure (`string` => `array`), the remapping will result in `null` as output.
For these cases it makes sense to define one or multiple fallback values, when configuring a remapping. You can do so by clicking the `Add fallback` button in the configuration UI.
We will execute the remapping top to bottom. This means the remapping stops for
each the entity (employee, candidate, job...) has soon as valid value is found.
You can also use the **Fallback to Kombo's mapping** button to include Kombo's standard mapping logic as one of the priorities in your fallback chain. This is useful when your custom field is not always populated and you want to fall back to what Kombo would have mapped by default. Learn more in the [Kombo Default Fallback](./kombo-default-fallback) guide.
# Remapping address fields
Source: https://docs.kombo.dev/assessment/features/remapping/struct-remapping
Learn how to use the remapping feature to adjust Kombo address fields based on fields in your customer's systems.
## Remapping an address field
1. An address in Kombo consists out of multiple fields. Select an integration field for each field you wish to fill. Unfilled will result in `null` for the respective property.
2. You might need to scroll to see all available fields.
Note: English country names will get automatically resolved to the ISO 3166-1 alpha-2 country code.
## Fallbacks
Fallbacks are only executed if **all fields** in the priority above are missing (`undefined`), `null` or empty (`''`).
# Extend write endpoints
Source: https://docs.kombo.dev/assessment/features/remote-fields
Learn how Kombo allows you to write additional, otherwise unsupported fields with unified write actions.
## Overview
Kombo supports a feature called **Remote Fields** for many write endpoints. This
feature solves a similar problem as the [passthrough API](./passthrough-api) while still allowing you
to use the unified Kombo API.
## How does it help you
While we always try to solve even niche use cases with our unified API, there are cases
where an integration requires particular data (for example, because your customer
uses required custom fields or customizes their system a lot). In these cases, the
remote fields feature allows you to pass this data to the connected system.
Remote fields also allow you to customize specific endpoints even more, as it
would be out of scope for the unified model.
If you need to read additional data from connected systems instead, use
[custom fields](./custom-fields).
## How to use it
Write actions that support this feature support have a property called `remote_fields`
on the root level request body. This object follows a record structure where the
key is the name of the tool (e.g., `greenhouse`), and the value is an object
highly specific to the tool. On a high level, most available fields are documented in the endpoint specification.
A good example of a write endpoint supporting this feature is [the ATS API endpoint to create a new application](/ats/v1/post-jobs-job-id-applications) (search for 'remote fields').
### Example
A SuccessFactors instance requires the nationality of applicants as an attribute.
`nationality` isn't an attribute that is ordinarily supported by our
'Create application' endpoint. Because application creation generally works the
same otherwise, you can use `remote_fields` to extend the requests that we send
to SuccessFactors with the `nationality` field.
### Remote fields in practice
You will likely find out about any required remote fields during testing.
You may try to submit a dummy candidate, however, you receive an error message like the
following:
```
{'status': 'error', 'error': {'message': {'remote_http_status': 500, 'remote_error': {'error': {'code': 'COE_GENERAL_SERVER_FAILURE', 'message': {'lang': 'en-US', 'value': '[COE0019]Unexpected error occurred: custNationality required for external candidate, custFutSponsor required for external candidate as per field override, for templateId 579 , with the index 0'}}}}}}
```
For example, for the above error message, you would then need to add the following fields to your create candidate call for the parameter `remote_fields`:
```
{
"successfactors": {
"Candidate": {
"custNationality": "some-nationality",
"custFutSponsor": "some-sponsor"
}
}
}
```
You can then use an iterative process based on the error messages
("trial-and-error") to tell whether you are now submitting the correct remote fields.
### Help
Don't hesitate to contact us if you have any questions about this feature
or you need help with a specific use case.
# Scopes
Source: https://docs.kombo.dev/assessment/features/scopes
Scopes allow you to customize what data is being synced by Kombo.
By default, Kombo syncs all available data from connected systems. This can be
pretty convenient for exploring what's available during development, but as soon
as you take Kombo into production, you'll likely want to restrict what data is
extracted and stored for privacy and security reasons.
For this purpose, Kombo provides what we call "Scopes." These allow you to
configure precisely which models and data points are being extracted and stored.
Scopes can, for example, be used to anonymize data by removing all personal
identifiable information from the data we store.
## Configuring scopes
To get started configuring scopes, log into the
[Kombo Dashboard](https://app.kombo.dev) and open the "Scope Config" page. It
should look something like this:
### Configure scope config
When editing your scope configs or creating a new one, a page similar to this
one will open:
All of Kombo's Data Models are listed here, and you can disable, enable or
mark an entire Data Model as optional.
We do not sync data from disabled data models. Optional Data Models aren't
synced if your customer opts out of having the field exposed. Enabled
models are always synced.
We recommend turning all Data Models off that you are not interested in. For example,
if you want to sync employee, employment and organization data
but are not interested in absences, turning off the absence type, absences and
time off balance Data Models is recommended. This will simplify the setup for your customer, improve sync times, and
not expose any data that does not need to be exposed.
### Configuring fields
If you only want to turn off individual model fields, you can expand
each model in the edit page. You will now see all the fields it supports:
For example, if you don't want to sync sensitive data like SSNs or Tax IDs,
you can turn them off here. Similarly, if you would like to read
personal identifiable information but it is not required for your use-case,
consider marking the field as optional. This will give your customers the choice
of whether they want to expose it or not.
## Building trust with your customers
Some of the systems we help you integrate contain very sensitive data (like
personal addresses or tax IDs of employees). That's why
communicating which data points you access and which you don't is critical to
building trust and eradicating concerns during the sales process.
To help you with this, we're exposing your scope config to the end user as part
of our connection flow:
This way, your customers can see exactly which data points you're accessing.
# Setup Flow
Source: https://docs.kombo.dev/assessment/features/setup-flow/introduction
Let your customers configure their integration end-to-end.
The [Connection Flow](/kombo-connect) lets your customers authenticate and
validate their credentials. The Setup Flow covers everything that comes after:
any additional configuration the integration needs before it can sync the right
data. It is presented to your customers as a self-serve UI inside the Kombo
Connect SDK, so they can complete it without you building anything yourself.
## What appears in the Setup Flow
Each integration decides which steps it actually needs. The most common ones
are:
* **[Field mapping](../custom-fields#self-serve-custom-field-configuration)**,
where customers connect your custom fields to fields in their tool. Available
for any category as long as you've defined custom fields.
* **[Employee filtering](/hris/features/filtering/introduction)**, where HRIS
customers choose which employees Kombo should sync.
* **Tool-specific steps**, surfaced automatically by some connectors (for
example Greenhouse, Teamtailor, or SCIM) to handle one-time configuration that
the tool itself requires, like activating webhooks or providing additional
credentials.
Steps only show up when they are relevant. If a customer connects a tool that
does not support filtering, the filtering step is hidden even when the feature
is enabled on the integration.
## Enabling Setup Flow steps
Field mapping and employee filtering are opt-in per integration. Tool-specific
steps require no configuration on your side, they appear automatically when
needed.
### When creating a new integration
In the Dashboard, open the [Integrations
page](https://app.kombo.dev/integrations) and toggle the steps you want at the
bottom of the create-link form.
You can do the same via the API by setting `enable_field_mapping` and/or
`enable_filtering` (HRIS only) to `true` on the [Create Connection Link
endpoint](../../v1/post-connect-create-link).
### For an existing integration
Open the integration in the Dashboard and use the toggles in the **Integration
Settings** tab.
## Showing the Setup Flow to your customers
Setup Flow steps run automatically as part of the [Connection
Flow](/kombo-connect) the first time a customer connects a tool, so the
embedded flow you already have in place will pick them up without any changes.
To send customers back into the Setup Flow later, for example to update field
mappings or change which employees are synced, create a setup link with the
[Create Setup Flow link
endpoint](../../v1/post-integrations-integration-id-setup-link) and pass it to
`showKomboConnect` from the [Kombo Connect
SDK](../../guides/connect/embedded-flow#opening-the-flow), the same way you do
with a connection link.
You can also generate a setup link from the Integration Details page in the
Dashboard if you'd rather not wire up the API yourself.
# Overview
Source: https://docs.kombo.dev/assessment/getting-started
Let's get you up and running with our API!
This guide assumes you already have a Kombo account. If that's not the case,
visit [our website](https://www.kombo.dev/) to learn more and get access.
# Getting started
There are a few simple steps that you should follow to get started with our API.
1. [Get access to a sandbox integration](./getting-started/sandbox-integrations)
2. [Create an integration](./getting-started/create-integrations)
3. [Call our API](./getting-started/authentication)
4. [Querying the API](./getting-started/querying-api)
5. [Fetching Data](./getting-started/fetching-data)
# Authentication
Source: https://docs.kombo.dev/assessment/getting-started/authentication
Learn how to authenticate with the Kombo API and manage API keys securely.
## Authentication
You need to get an API key from the Kombo dashboard to call our API.
You can create one on the [Secrets page](https://app.kombo.dev/secrets).
You might have multiple environments in your Kombo account. Each API key is
specific to an environment.
This will allow you to call some general endpoints that are not
integration-specific. For example, try calling the following test API key endpoint:
```bash theme={null}
curl --request GET \
--url https://api.kombo.dev/v1/check-api-key \
--header 'Authorization: Bearer '
```
## Calling Integration Endpoints
To call integration-specific endpoints, you need the integration ID. An integration ID identifies a specific
instance of a tool connected to Kombo. If you haven't created an integration yet,
read the [creating integrations guide](./create-integrations).
Get the integration ID from the details of integration on the [integrations dashboard page](https://app.kombo.dev/integrations).
Pass the integration ID with the `X-Integration-Id` header in your API requests. For example:
```bash theme={null}
curl --request GET \
--url https://api.kombo.dev/v1/hris/employees \
--header 'Authorization: Bearer ' \
--header 'X-Integration-Id: '
```
Find out more about the integration-specific endpoints for
[HRIS](/hris/getting-started) or [ATS](/ats/getting-started)
## API Key Security
Kombo provides several features to help you manage API keys securely.
### Key Scoping
Each API key is scoped to a single [environment](../guides/environments) (Production or Development). Keys created in Production cannot access Development data and vice versa. The key prefix reflects the environment: `ks_prod_...` for production, `ks_dev_...` for development.
### Expiration
When creating an API key, you can set an optional expiration date. Once expired, any request using the key will return an authentication error. To rotate keys without downtime, you must overlap the old and new keys: create a new key, migrate all of your services to use it, and only then let the old key expire (or revoke it).
### IP Allowlisting
You can restrict each API key to a set of IP addresses or CIDR ranges. When an allowlist is configured, requests from non-listed IPs are rejected. An empty allowlist (the default) permits any IP. You can update the allowlist at any time without recreating the key.
### Revocation
API keys can be individually disabled from the dashboard. Disabling a key takes effect immediately — all subsequent requests using that key will fail. Disabled keys cannot be re-enabled; create a new key instead.
### Audit Trail
All key operations — creation, disabling, and IP allowlist changes — are recorded in the [audit log](../features/audit-logs).
# Creating Integrations
Source: https://docs.kombo.dev/assessment/getting-started/create-integrations
Learn how to connect tools to Kombo.
This guide assumes you already have a Kombo account. If that's not the case,
visit [our website](https://www.kombo.dev/) to learn more and get access.
## Ways of Creating Integrations
There are three ways of creating integrations in Kombo:
1. **For you in development**: Use the Kombo Dashboard and enter the integration credentials yourself.
This is the easiest way to get started if you want to test out Kombo.
2. **For customers with a magic link**: Create a magic link and send that to your customer to create the integration.
This is the simplest way to launch integrations for selected customers (for example, as a POC).
3. **For customers with Kombo embedded**: Embedding Kombo into your application and allowing the customer to create the integration there.
This will give your customer the best experience and is generally recommended when rolling out Kombo to your customers.
If you are testing Kombo or developing the integration to us, make sure to
select the development environment in the top left corner.
This will not count against your billing and will have useful features like saving
the credentials that you entered and filled out some fields by default.
# Creating Integrations in the Dashboard
Recommended for development purposes.
Go to the [dashboard integrations page](https://app.kombo.dev/integrations) and
click on the "Create Integration" button. Select `Create the integration yourself`.
Select a category and continue (if you use the development environment,
the organization and email will be auto-filled). Select a tool that you have
access to and enter the credentials. The flow will explain, in most cases, what
you need to do to get the credentials out of the tool.
# Creating a magic link
Use this to get started immediately with a selected customer.
Open the [dashboard integrations page](https://app.kombo.dev/integrations) and
click on the "Create Integration" button. Select *Let your customer create the integration*.
Select the category and fill out the organization name and email address.
This data is only for you to identify who created the integration and will be used
as a label in the dashboard.
Features that you can use with the embedded flow are:
* Pre-defining a tool
* Defining a language
# Embedding Kombo into your Application
This is only necessary if you want to allow your customer to create
integrations completely on their own.
Embedding Kombo in your application requires implementing the Kombo API into your product.
Embedding Kombo allows you to provide a better experience to your customers and customize the
connection flow the most.
Features that you can use with the embedded flow are:
* Pre-defining a tool
* Defining a language
* Specifying the `remote_environment` (for using sandbox credentials with some tools)
* Using a scope config template
* Setting the `origin_id` (id of the customer in your system)
Read more about embedding Kombo into your application
[here](../guides/connect/embedded-flow).
# Querying the API
Source: https://docs.kombo.dev/assessment/getting-started/querying-api
Learn how to filter and paginate the Kombo `GET` endpoints. This will help you implement incremental fetching and more.
## SDKs
You can use our officially supported SDKs to interact with our API. For more information, see the [Libraries and SDKs](/libraries-and-sdks) section.
## General Response Format
All *GET* endpoints of Kombo follow the same principle. All of them return a list
of results and a next cursor. All results follow the same basic structure with the
following properties:
* `id`: An ID generated by Kombo, also referred to throughout the documentation as "Kombo ID".
* `remote_id`: The ID of the object in the remote system. This can be null for some objects.
* `changed_at`: Part of Kombo's change tracking — this is the timestamp of the last change that was detected by Kombo.
* `remote_deleted_at`: Part of Kombo's change tracking — this is the timestamp where the object was not found anymore in the remote system.
*Other properties are model-specific.*
### A note on Kombo IDs and their uniqueness
We generate the Kombo ID by referencing the remote ID and the integration ID.
This results in the following statements being true:
* A Kombo ID is unique across all integrations for *the same model*.
* This is because we reference the integration ID itself when generating the Kombo ID.
* A Kombo ID is *not* unique across different models for the same integration.
* This will occur for remote systems that follow a sequential ID pattern. For example, both the first employee and department have the ID `1`. As the integration ID is the same, so will the Kombo ID.
## Pagination
Each request returns either a value on the `next` field or `null`. The
value will be a cursor which you can use to get the next page of results. Use
the `cursor` query parameter to request the next page. (Please note that you
still need to add the relevant filters while paginating.)
In addition, you can use the `page_size` parameter to specify the number of results per page.
```bash theme={null}
curl --request GET \
--url 'https://api.kombo.dev/v1/hris/employees?cursor=eyJwYWdlIjoxMiwibm90ZSI6InRoaXMgaXMganVzdCBhbiBleGFtcGxlIGFuZCBub3QgcmVwcmVzZW50YXRpdmUgZm9yIGEgcmVhbCBjdXJzb3IhIn0&page_size=100' \
--header 'Authorization: Bearer '
```
## Filtering
All models provide the same filters in addition to some model-specific filters.
The following filters apply to all models:
* `updated_after`: Only return objects where the `changed_at` value is after
the given timestamp. This can be used to fetch data incrementally.
This filter also includes all expanded relations — so if only they have
changed (but none of the primary attributes of the object), this will still
count as the object having changed and it will still be returned.
* `include_deleted`: By default, all values with a `remote_deleted_at` value are
not returned. If you want to include them, set this to `true`. This is helpful
if you want to remove them from your database.
* `ids`: List of comma-separated ids. Only return objects with these IDs.
* `remote_ids`: List of comma-separated remote ids. Only return objects with
these remote IDs.
## Error Codes
When the Kombo API encounters an error, it returns a structured error response with a specific `code` for programmatic handling.
For a complete list of error codes and detailed explanations see the [Error Handling guide](/guides/errors).
```json theme={null}
{
"status": "error",
"error": {
"code": "REMOTE.INPUT_INVALID",
"title": "The remote system returned validation errors.",
"message": "Candidate field 'email' must be a valid email address for Greenhouse"
}
}
```
## Rate limiting
The rate limiter restricts the number of API requests you can send to Kombo. Currently, we permit 300 requests over 60 seconds **per environment** (i.e., PROD or DEV environment). After the time window has passed, the limit is reset. If you need a higher quota, reach out to the Kombo team.
Independent of this cap, [concurrency limiting](../guides/concurrency-limiting) limits how many unified actions can run at the same time per integration.
This information is exposed as headers on the response of every authenticated API request:
| Header | Sample Value | Description |
| ------------------- | ------------ | ----------------------------------------------------- |
| ratelimit-limit | 300 | The maximum number of requests permitted |
| ratelimit-remaining | 298 | The remaining number of requests permitted |
| ratelimit-reset | 57 | The remaining seconds until the rate limiter is reset |
When exceeded, you will receive a failed response with the [error `code`](/guides/errors) of `PLATFORM.RATE_LIMIT_EXCEEDED`:
```json theme={null}
{
"status": "error",
"error": {
"code": "PLATFORM.RATE_LIMIT_EXCEEDED",
"title": "Rate limit exceeded.",
"message": "Maximum requests are 300 every 60 seconds. Try again in 57 seconds.",
"log_url": null
}
}
```
### Concurrency limiting
In addition to rate limiting, Kombo applies [concurrency limiting](../guides/concurrency-limiting) to unified actions. While rate limiting caps total requests over a time window, concurrency limiting caps simultaneous in-flight unified actions per integration to prevent backpressure buildup on downstream tools. Endpoints for reading synced model data are not affected by concurrency limiting.
### Handling 429 responses
Both rate limiting and concurrency limiting return HTTP `429`, but they have different error codes and require different responses:
* **`PLATFORM.RATE_LIMIT_EXCEEDED`** -- You've sent too many requests in the current time window. This applies to all endpoints. Wait for `ratelimit-reset` seconds or retry with exponential backoff.
* **`PLATFORM.CONCURRENCY_LIMIT_EXCEEDED`** -- Too many unified actions are in flight for this integration. The underlying tool can't keep up. Retry the failed request after a short backoff (e.g., 1s, 2s, 4s). You likely still have rate limit quota remaining, so waiting for `ratelimit-reset` is unnecessary. See the [concurrency limiting guide](../guides/concurrency-limiting) for details.
# Remote Data
Source: https://docs.kombo.dev/assessment/getting-started/remote-data
Learn how to use remote data to access any available field.
Remote data is a feature exposing the raw, unchanged data
that we receive from the APIs, allowing you to read data that might
not be available in our unified API model.
It is disabled by default because it has compliance implications
(we need to store all data we receive, not just the data points selected in the
scope configs) and because you will need to write parsing logic for each
integration/tool.
It is mainly used to read data that might not be available in our unified Data Models.
Some customers are for example interested in some specific government-issued
company IDs, which are currently not part of our Data Model, but can be extracted
from these raw responses. An example response might be:
```json theme={null}
{
"status": "success",
"data": {
"next": "eyJwYWdlIjoxMiwibm90ZSI6InRoaXMgaXMganVzdCBhbiBleGFtcGxlIGFuZCBub3QgcmVwcmVzZW50YXRpdmUgZm9yIGEgcmVhbCBjdXJzb3IhIn0=",
"results": [
{
"first_name": "John",
"last_name": "Doe",
...
"remote_data": {
"EmployeeData": {
"Names": {
"FirstName": "John",
"LastName": "Doe"
},
"Company": {
"GovernmentID": "123456789"
}
}
}
}
]
}
}
```
`remote_data` gives you the raw API response from the connected system. If you
need **structured** extra fields for reading, see [Custom
Fields](../features/custom-fields). If you need to **write** additional data
when creating records, see [Remote
Fields](/extending-the-model#remote-fields).
## When to use remote data
Remote data should be used when our unified Data Model does not offer specific
fields that you are interested in. Note that we do not unify remote data, so the
data structure might differ between tools and might even differ between
individual integrations of the same tool.
## When not to use remote data
Remote data might potentially expose sensitive data, even if your customers
opt out of it. We might, for example, always receive personally identifiable
information (e.g. emails, names and addresses). If your customers opt out of
these data fields, we will discard this data and never store it.
If remote data is active, however, we will expose the raw responses and therefore
information that should optimally not be stored.
We also offer [custom fields](../features/custom-fields), which are a more versatile and compliant variant
of remote data.
## How to use remote data
Remote data can be enabled on a per-model basis in the scope config. To enable
it, please contact us.
# Sandbox Integrations
Source: https://docs.kombo.dev/assessment/getting-started/sandbox-integrations
Learn how to access tools you can connect to Kombo for development purposes.
If you wish to get started as quickly as possible, use our built-in **Sandbox Integration (HRIS/ATS/LMS)**.
You can find it in the **"Integrations"** section in the Kombo dashboard. The sandbox integration
is only available in your [development environment](../guides/environments#development).
Connect the built-in sandbox to start exploring the API right away — no
credentials required.
### What the sandbox covers
The sandbox requires **no credentials** and can be set up in minutes. It
provides a representative dataset that covers common edge cases you'll encounter
in production — including active, terminated, and pending employees, multiple
currencies, and various bank account formats.
**Read data** — the sandbox includes data for all major models:
* **HRIS**: Employees, employments, groups, locations, legal entities, absences,
absence types, time-off balances, timesheets, performance reviews, skills,
and employee skill proficiency ratings
* **ATS**: Candidates, applications, jobs, job posts, stages, offers,
interviews, rejection reasons, users
* **LMS**: Users, courses, skills, providers, progress records
**Write actions** — all major write operations work against the sandbox:
* **HRIS**: Create employees, create/delete absences, upsert employee skill
proficiency ratings
* **ATS**: Create candidates (with applications), move applications to stages,
add attachments, add/remove tags, add notes
* **LMS**: Enroll users, mark completions, create and manage courses
The sandbox dataset is **deterministic** — syncs always return the same base
data, making it well-suited for automated testing with stable assertions.
Records created through write actions persist in Kombo's database and appear in
subsequent API calls, but don't modify the base dataset.
### Third-party sandboxes
Some tools also offer free demo accounts that you can use to test out Kombo.
We recommend the following tools, as they provide great coverage and are broadly used:
* When testing HRIS integrations, we recommend using [Personio](https://www.personio.com/free-trial/).
* When testing ATS integrations, we recommend using [Recruitee](https://auth.recruitee.com/sign-up). If you want to gain access to a sandbox instead of using the free trial, please fill out [this form](https://www.tellent.com/technology-partner-application). In the section “Please describe the use case for this integration on a high-level”, mention “Referred by Kombo”.
Additionally, here are some more tools that offer free trials or test accounts: [BambooHR (HRIS)](https://www.bamboohr.com/signup/), [Sage HR (HRIS/ATS)](https://sage.hr/register), [Deel (HRIS)](https://app.deel.com/signup), [CharlieHR (HRIS)](https://www.charliehr.com/join), [Planday (HRIS)](https://www.planday.com/signup/), [Factorial (HRIS)](https://factorialhr.com/get-started), [Humaans (HRIS)](https://app.humaans.io/signup), [BreezyHR (ATS)](https://breezy.hr/signup), [Jazzhr (ATS)](https://info.jazzhr.com/free-trial.html), [Join (ATS)](https://join.com/auth/signup/recruiter), [Teamtailor (ATS)](https://tt.teamtailor.com/users/new?locale=en), [Workable (ATS)](https://www.workable.com/free-trial)
### Enterprise tools
Enterprise tools like Workday, SAP SuccessFactors, or SmartRecruiters usually
don't offer free sandbox access. However, for customers on the enterprise plan,
we offer joint testing sessions with these enterprise tools.
# Concurrency Limiting
Source: https://docs.kombo.dev/assessment/guides/concurrency-limiting
Concurrency limiting caps simultaneous in-flight unified actions per integration, giving you fast feedback instead of slow timeouts.
## What is concurrency limiting?
When you invoke unified actions in Kombo (e.g., creating a candidate, moving
an application, reading attachments), each call is forwarded to the underlying HR or ATS tool.
These tools have their own rate limits, which are often significantly lower than
what Kombo allows.
If many unified actions run in parallel, they all compete for limited
downstream throughput. Completion times grow, your HTTP clients may hit
timeouts while work is still in flight, and retries can overlap with operations
that are still running.
Concurrency limiting solves this by capping how many unified actions
can be processed simultaneously per integration. When the cap is
reached, additional requests are immediately rejected with a `429` status code.
This gives you a fast, clear signal to retry with backoff instead of stacking
unbounded in-flight work that might eventually time out on your side.
Concurrency limiting only applies to unified actions (calls that run work
against the underlying tool). Model endpoints for reading synced data are not
affected.
## How it differs from rate limiting
For Kombo-wide request volume over time, see [Rate limiting](../getting-started/querying-api#rate-limiting).
| | Rate Limiting | Concurrency Limiting |
| ------------------ | ------------------------------ | ------------------------------------- |
| **What it caps** | Total requests per time window | Simultaneous in-flight requests |
| **Scope** | All API requests | Unified actions only |
| **When it resets** | After the time window elapses | As in-flight requests complete |
| **Error code** | `PLATFORM.RATE_LIMIT_EXCEEDED` | `PLATFORM.CONCURRENCY_LIMIT_EXCEEDED` |
Both return HTTP `429`, but with different error codes and headers.
## Response headers
When concurrency limiting is active, every unified action response includes two headers:
| Header | Example | Description |
| ----------------------- | ------- | --------------------------------------------------------------------------------------- |
| `Concurrency-Limit` | `30` | The maximum number of concurrent in-flight unified actions allowed for this integration |
| `Concurrency-Remaining` | `12` | How many additional concurrent unified actions can be accepted right now |
The limit may vary per integration. Sensitive integrations (e.g.,
reverse-engineered APIs) may have significantly lower limits. Use the response
headers to discover the actual limit rather than assuming a specific number. The
default limit is 30.
These headers appear on both successful responses and `429` rejections, so you can monitor utilization proactively.
## Handling concurrency limit errors
When you exceed the concurrency limit, you receive a `429` response with the error code `PLATFORM.CONCURRENCY_LIMIT_EXCEEDED`. The response includes both concurrency and rate limit headers:
```
HTTP/1.1 429
concurrency-limit: 30
concurrency-remaining: 0
ratelimit-limit: 1000
ratelimit-remaining: 834
ratelimit-reset: 44
```
```json theme={null}
{
"status": "error",
"error": {
"code": "PLATFORM.CONCURRENCY_LIMIT_EXCEEDED",
"title": "Concurrency limit exceeded.",
"message": "Maximum concurrent action requests per integration is 30. Currently 30 in flight."
}
}
```
Notice how the rate limit headers show remaining quota (`ratelimit-remaining: 834`) while the concurrency headers show no remaining slots (`concurrency-remaining: 0`). This tells you:
* The underlying tool is at capacity for this integration, not Kombo itself.
* You still have rate limit quota, so waiting for `ratelimit-reset` is unnecessary.
* Slots free up quickly as in-flight requests complete, so a short retry is effective.
### How to retry
For `PLATFORM.CONCURRENCY_LIMIT_EXCEEDED`, retrying the same request is
expected and does not run the unified action twice. Kombo rejects the call
before the unified action runs (no concurrency slot was acquired). That differs
from failures where the outcome is unclear, e.g., a timeout after a write may
still have succeeded, so retries need extra care.
1. Retry the failed request with exponential backoff: start with a short delay (e.g., 1s) and increase on repeated `429`s (2s, 4s, 8s, ...).
2. Optionally, throttle proactively: check `Concurrency-Remaining` on successful responses to slow down before hitting the limit.
## What this means for your integration
Concurrency limiting does not cap steady-state throughput below what the
downstream tool can sustain. The integrated system still bounds how fast work
completes. The limit turns that constraint into immediate `429` responses
instead of long waits and unbounded in-flight unified actions.
# Embedded flow
Source: https://docs.kombo.dev/assessment/guides/connect/embedded-flow
Embed Kombo Connect into your app for the most seamless experience.
If you've gone through the general [Kombo Connect](./introduction) documentation,
you'll know there are
[different ways of using the flow](./introduction#getting-started). Our embedded flow
provides the most seamless experience to your customers but also involves some
engineering on your side. In this guide, we'll go over what that means exactly.
## Implementing the flow
The embedded flow requires you to:
* Add an **endpoint** to your back-end for initiating the flow
* Add a **button** to your frontend to show the flow to your user using the SDK
* React to a flow being completed through the "activation token" returned by the SDK or by listening to a webhook
Let's go over each of these steps in detail.
### Adding the endpoints
Both endpoints are mostly just wrappers around endpoints of the Kombo API and
mainly exist for security reasons (so that malicious actors can't set up
arbitrary integrations in your Kombo environment).
#### Initiating the flow
The first one initializes the flow by calling the Kombo API and returns a link
that we then use in the frontend:
```js Node.js (Express + Axios) theme={null}
app.post('/integrations/kombo/init', async (req, res) => {
// TODO: Get user details from your database
const user = await getUser()
const response = await axios.post(
'https://api.kombo.dev/v1/connect/create-link',
{
end_user_email: user.email,
end_user_organization_name: user.company.name,
end_user_origin_id: user.company.id,
integration_category: 'HRIS',
},
{
headers: {
authorization: `Bearer ${KOMBO_API_KEY}`,
},
},
)
res.send({ link: response.data.data.link })
})
```
The `end_user_*` fields identify which of your customers an integration belongs to:
* **`end_user_email`** (required): Contact email for this end user. Used as a label in the dashboard and included in webhooks.
* **`end_user_organization_name`** (required): Company name. Used as a label in the dashboard and included in webhooks.
* **`end_user_origin_id`** (optional): Your internal ID for this customer. Echoed back in webhooks and API responses so you can map integrations to your own records.
These fields are metadata — they do not affect integration identity. Changing the email or organization name in a subsequent `create-link` call with the same `end_user_origin_id` does **not** update an existing integration; it creates a new flow link.
Kombo does **not** deduplicate integrations based on these fields. Each
completed flow creates a new integration. You are responsible for preventing
customers from connecting the same tool twice. Use the [reconnection
link](../../v1/post-integrations-integration-id-relink) if a customer needs to
update their credentials for an existing integration.
#### Reacting to the flow being completed
After your user completes the flow, you can retrieve the integration details and store them in your database for future use. There are two ways to achieve this:
1. By using the ["Get integration by token" endpoint](../../v1/get-connect-integration-by-token-token)
2. By listening to the `integration-created` webhook
**Option 1: Using the endpoint**
The activation token is returned from the frontend after the user completes the integration flow. You can use this token to retrieve the integration details via the ["Get integration by token" endpoint](../../v1/get-connect-integration-by-token-token) and store them in your database.
Here's how you might implement the activation endpoint:
```js Node.js (Express + Axios) theme={null}
app.post('/integrations/kombo/activate', async (req, res) => {
const response = await axios.get(
`https://api.kombo.dev/v1/connect/integration-by-token/${req.body.token}`,
{
headers: {
authorization: `Bearer ${KOMBO_API_KEY}`,
},
},
)
const integrationId = response.data.data.id
// TODO: Store the integration ID in your database
res.sendStatus(200)
})
```
**Option 2: Listening to the `integration-created` Webhook**
Alternatively, you can set up a webhook endpoint on your backend to listen for the `integration-created` event that Kombo sends when a new integration is created. This webhook contains the integration ID and other relevant details, allowing you to associate the integration with your user in your database.
Here's how you might set up the webhook endpoint:
```js Node.js (Express) theme={null}
app.post('/webhooks/kombo/integration-created', async (req, res) => {
const integration = req.body.data
// TODO: Verify the webhook signature for security purposes
// TODO: Store the integration ID in your database
res.sendStatus(200)
})
```
* Make sure to [verify the webhook signature](../../guides/webhooks#validate-the-data) to ensure that the request comes from Kombo.
* Make sure to set up the webhook in the [dashboard](https://app.kombo.dev/configuration/webhooks).
### Adding the button
For now, we're all set on the back-end side, so let's switch to the front-end:
Here we'll have to add a button that lets your users start the flow. Most of our
customers already have an "Integrations" page within their product's settings.
If you do, too, then that's the perfect place to add the button.
How exactly you're going to do this will depend on your tech stack, but it's
probably going to look something like this:
```jsx React theme={null}
```
```jsx Vue.js theme={null}
```
```html HTML theme={null}
```
Right now, we require you to specify the integration category when
initializing the flow, so you'll likely want to label your button accordingly
(e.g., "Connect HRIS" or "Connect ATS").
When a user clicks on the button, two things need to happen:
* An integration link has to be retrieved through your endpoint
* The embedded flow has to be started
#### Getting a link
Here's what the first part might look like:
```js JavaScript theme={null}
async function getKomboConnectLink() {
// Note: The URL below points to *your* API and could be different
const response = await fetch('/integrations/kombo/init')
const data = await response.json()
return data.link
}
```
#### Opening the flow
Now it's time to actually show the flow to the user. This can be through
[the @kombo-api/connect JavaScript library](https://www.npmjs.com/package/@kombo-api/connect).
It's tiny (about 50 lines of JavaScript as of now) and basically just
initializes an `