Application Delivery
Receive every new application as a JSON POST to your own HTTPS endpoint, including candidate data, screening question answers and attachments.
Overview
Application Delivery sends every new application for your company to an HTTPS endpoint you operate. Use it when your ATS isn't one of Kini's integrations, or when you want applications to go straight into your own system.
As soon as a candidate applies, Kini sends one POST request containing the candidate's details, screening question answers, uploaded files (CV, cover letter, …) and the job they applied for.
Payload
{
"application_id": 452123,
"created_at": "2026-10-26T09:13:58Z",
"channel": "indeed",
"notes": "I can start on short notice.",
"company_id": 123,
"job_id": 12388996,
"external_job_id": "REQ-1604",
"job_title": "Warehouse Associate (m/f/d)",
"candidate": {
"email": "jane.doe@example.com",
"first_name": "Jane",
"last_name": "Doe",
"gender": "FEMALE",
"phone": "+49 170 1234567",
"location": {
"street": "Musterstraße 1",
"postcode": "10115",
"city": "Berlin",
"country": "DE"
}
},
"screening_questions": [
{
"id": "drivers_license",
"question": "Do you have a driver's license?",
"answer_type": "boolean",
"answer": true
},
{
"id": "shifts",
"question": "Which shifts can you work?",
"answer_type": "multiselect",
"answer": ["early", "late"],
"answer_label": ["Early shift", "Late shift"]
},
{
"id": "motivation",
"question": "Why do you want to work with us?",
"answer_type": "textarea",
"answer": "I enjoy working in a team and ..."
}
],
"attachments": [
{
"type": "cv",
"name": "jane-doe-cv.pdf",
"content_type": "application/pdf",
"data": "JVBERi0xLjcKJcfsj6IKNSAwIG9iago8PC9MZW5ndGggNiAwIFI..."
}
]
}
Missing values are sent as null and empty lists as [], so every key is always present. We may add fields over time, so ignore keys you don't recognize; existing fields won't be renamed or removed without notice.
Fields
| Field | Type | Description |
|---|---|---|
application_id | int | Unique Kini ID of the application. Stays the same across retries — use it to detect duplicates. |
created_at | string (ISO 8601) | When Kini received the application (UTC). |
channel | string | Talent channel the application came from, e.g. indeed, stepstone. Can be mapped to your own values on request. |
notes | string | Free-text message or cover letter written by the candidate. |
company_id | int | Unique Kini ID of the company. |
job_id | int | Unique Kini ID of the job the application was submitted for. |
external_job_id | string | Your own ID of the job, if you provided one when creating it in Kini. |
job_title | string | Job title. |
candidate | object | Candidate details, see below. |
screening_questions | array | Answers to the job's screening questions, see below. |
attachments | array | Files uploaded by the candidate, see below. |
The ID fields have the same names as in the Application Sync Status Update webhook.
candidate
| Field | Type | Description |
|---|---|---|
email | string | Email address. Always present. |
first_name | string | First name. Always present. |
last_name | string | Last name. |
gender | enum | MALE, FEMALE, DIVERSE or NOT_SPECIFIED. |
phone | string | Phone number. |
location | object | street, postcode, city, country (ISO 3166-1 alpha-2). |
screening_questions[]
| Field | Type | Description |
|---|---|---|
id | string | ID of the question, as defined on the job. |
question | string | Question text shown to the candidate. |
answer_type | enum | boolean, text, textarea, select or multiselect. |
answer | any | The answer. boolean → true/false, text/textarea → string, select → option value, multiselect → list of option values. |
answer_label | any | Only for select and multiselect: the option label(s) the candidate picked. |
attachments[]
| Field | Type | Description |
|---|---|---|
type | enum | cv, cover-letter, photo or other. |
name | string | File name including extension. |
content_type | string | MIME type, e.g. application/pdf, image/jpeg. |
data | string | File content, Base64-encoded. |
Because files are embedded in the request, a single delivery can reach roughly 30 MB. Check that your endpoint, and any proxy or gateway in front of it, accepts bodies of that size.
Responding to deliveries
Kini waits up to 30 seconds for your response, then decides what happens next based on the HTTP status code you return:
| Your response | Meaning for Kini |
|---|---|
2xx | Delivered. The application's sync_status becomes SUCCESS. |
409 Conflict | You already have this application. Not retried; sync_status becomes EXPECTED_FAILURE with DuplicateApplicationError. |
410 Gone | The job is closed on your side. Not retried; sync_status becomes EXPECTED_FAILURE with JobNotPublishedError. |
408, 429, any 5xx, timeout or connection error | Temporary problem. Kini retries (see below). |
Any other status, including redirects (3xx) | Permanent failure. Not retried. |
To stay within the timeout, persist the payload and return 2xx immediately, then do heavier processing such as CV parsing asynchronously. Kini doesn't follow redirects, so configure the final URL.
Retries and duplicates
Temporary failures are retried with exponential backoff: after about 10, 30, 70 and 150 seconds, for 5 attempts over roughly 3 minutes. If the last attempt fails, the application's sync_status becomes FAILURE, which you can also receive through the Application Sync Status Update webhook. Contact tech@getkini.com to have failed applications redelivered.
Delivery is at least once. If your endpoint stores an application but doesn't respond within 30 seconds, Kini retries and you receive it again. application_id is stable across attempts, so use it to deduplicate and answer repeats with 2xx or 409.
Authentication
During setup, you provide a header name and secret value, for example Authorization: Bearer {token} or X-Api-Key: {key}. Kini stores the secret securely and sends the header with every request; reject requests without it. The endpoint must use HTTPS.
Setup
Application Delivery is configured per company. Send the following to tech@getkini.com:
- The HTTPS URL that should receive applications.
- The header name and secret value Kini should send with each request.
- Optionally, custom names for talent channels.
Before going live, we send a test application to your endpoint.