Create application - Kombo

Create a candidate for the application

When using Kombo’s “create application” endpoint you don’t have to worry about creating a candidate for the application, we take care you of these possible cases:

  • there is no candidate in the system → we will create it for you
  • there already is a candidate in the system → we will just attach the application to the new candidate

Set the source of the application

When creating an application you want to let your customers know that this application is coming from you. Otherwise, they won’t have a clue how many of their hires were because of your candidates and therefore your created value.

Our “create application” endpoint will automatically set the source of the candidate for you on every created application (see more here)

🦉 Most ATS set the source on the candidate level (not the application level). If you are creating an application for a candidate that has existed in the system before, we won’t override the source.

We will by default use the name of your environment (if your env is called “Example Customer (Prod)” the source will show up as “Example Customer”. If you want to change this name, please reach out to us.

Some ATS will require the user to configure the source in their ATS settings. In those cases, we will ask your customer to do so as part of connecting their ATS and provide additional help in our help center.

How to capture the source of candidates in an ATS – Kombo

Upload attachments with the application

You can upload any number of attachments to an application via the attachments array in the request body. The first CV in the attachments will be treated as the resume of the candidate when the tool allows previewing a resume.

There are two ways to submit the document that will be uploaded:

  • as a base64 string: you can encode the attachment and put it into the attachments.[*].data field. This will cause your requests and logs to be quite large, though.
  • via a download URL (recommended): if you don’t want to work with large base64 strings, you can provide a download URL to the attachments.[*].data_url field.

Those two ways are mutually exclusive. You can’t submit both data and data_url at the same time.

We recommend that the summed up size of all attachments that are submitted with an application should be below 10 MB, as this is within the file size limits of most ATS.

♻️ What happens if there is an invalid attachment submitted?

If the attachment is rejected by the ATS, we will retry creating the application without the attachment. If the request then succeeds, the application will be created without the attachment and you will receive a successful response that has one record per failed attachment in the warnings array

{
  "status": "success",
  "data": ...,
  "warnings": [
    {
      "message": "string"
    }
  ]
}

Retry behavior

We have implemented retry logic on our side with each underlying tool (e.g Personio, SmartRecruiters, etc). That means we’ll retry errors with status code 429, any 5xx error and if we get no response at all from the tool.

Therefore, please only retry requests if you get a 429 error because of our rate limiting OR 5xx error from Kombo because that means our system wasn’t able to resolve the issue on its own because there was downtime or an unexpected error.

Write answers to screening questions

If you want to submit the answer to a screening question to the ATS you have to first read the questions that are asked per job. You will get this info by having the “Read screening questions” scope enabled in your scope config.

You will then get the questions along with possible answers delivered on each job:

{
  "status": "success",
  "data": {
    "next": "eyJwYWdlIjoxMiwibm90ZSI6InRoaXMgaXMganVzdCBhbiBleGFtcGxlIGFuZCBub3QgcmVwcmVzZW50YXRpdmUgZm9yIGEgcmVhbCBjdXJzb3IhIn0=",
    "results": [
      {
        "id": "26vafvWSRmbhNcxJYqjCzuJg",
        "remote_id": "32",
        "name": "Backend Engineer",
        ...
        "screening_questions": [
          {
            "id": "26vafvWSRmbhNcxJYqjCzuJg",
            "remote_id": "48b4d36a-1d4b-4c50-ada7-9519078e65b4",
            "title": "Which is your primary programming language?",
            "description": "Please enter the language you are most comfortable with.",
            "format": {
              "display_type": "SINGLE_LINE",
              "max_length": null,
              "type": "TEXT"
            },
            "index": 0,
            "required": true
          }
        ]
      }
    ]
  }
}

Screening Question Formats

Please find a description below of the type as well as an example of each:

When creating the application you can pass them by providing a record for each question in the screening_question_answers array, like so:

{
  ...
  "screening_question_answers": [
    {
      // For a text question
      "question_id": "26vafvWSRmbhNcxJYqjCzuJg",
      "answer": "TypeScript"
    },
    {
      // For a single-select question
      "question_id" :"WA6SZ7R7YSo2C3WDLE5zmAJ",
      "answer": "3WA6SZ7R7YSo2C3WDLE5zmAJ", // ID of the answer-option
    },
    {
      // For a multi-select question
      "question_id" :"WA6SZ7R7YSo2C3WDLE5zmAJ",
      "answer": [
        "3WA6SZ7R7YSo2C3WDLE5zmAJ", // IDs of the answer-options
        "21KvMGS9Yhsbbsxfwqyb5dkF"
      ]
    }
  ]
}

Be aware that some ATS have required screening questions (screening_questions[*].required == true) and force you to submit an answer if you want to create an application. We let you know about some of the workarounds in our guide on customer-specific edge cases.

Handle ATS-specific limitations

Some ATS don’t support certain features such as screening questions. You get this information via the coverage grid or the “get tools” endpoint that will show you the supported data models, write actions and features via the coverage object:

{
  "status": "success",
  "data": {
    "tools": [
      {
        "id": "workday",
        "label": "Workday",
        "assets": {
          "logo_url": "https://storage.googleapis.com/kombo-assets/integrations/workday/logo.svg",
          "icon_url": "https://storage.googleapis.com/kombo-assets/integrations/workday/icon.svg",
          "icon_black_url": "https://storage.googleapis.com/kombo-assets/integrations/workday/icon-black.svg"
        },
        "coverage": {
          "read_models": [
            {
              "id": "ats_jobs",
              "label": "Jobs"
            },
            {
              "id": "ats_applications",
              "label": "Applications"
            },
            {
              "id": "ats_candidates",
              "label": "Candidates"
            }
          ],
          "write_actions": [
            {
              "id": "ats_create_candidate",
              "label": "Create candidate"
            }
          ],
          "features": [
            {
              "id": "automatic_source_writing",
              "label": "Automatic Source Writing"
            },
            {
              "id": "ats_sync_only_created_applications",
              "label": "Sync Only Created Applications"
            },
            {
              "id": "ats_create_candidate_full_attachments_retry",
              "label": "Create Candidate Full Attachment Retry"
            }
          ]
        }
      }
    ]
  }
}

You can build logic both in your frontend and your backend based on this endpoint.

Required fields

Before you go live with your first customer, there are a few things to look out for to make the connection go as smoothly as possible.

Handling required screening questions

As mentioned in the “screening questions” section when creating applications, some ATS force you to submit the answer to a given question and will reject any applications that don’t have answers attached.

This won’t be a problem with a lot of questions but some will have the required: true boolean set, so watch out for those.

{
  "status": "success",
  "data": {
    "next": "eyJwYWdlIjoxMiwibm90ZSI6InRoaXMgaXMganVzdCBhbiBleGFtcGxlIGFuZCBub3QgcmVwcmVzZW50YXRpdmUgZm9yIGEgcmVhbCBjdXJzb3IhIn0=",
    "results": [
      {
        "id": "26vafvWSRmbhNcxJYqjCzuJg",
        "remote_id": "32",
        "name": "Backend Engineer",
        ...
        "screening_questions": [
          {
            "id": "26vafvWSRmbhNcxJYqjCzuJg",
            "remote_id": "48b4d36a-1d4b-4c50-ada7-9519078e65b4",
            "title": "Which is your primary programming language?",
            ...
            "required": true
          }
        ]
      }
    ]
  }
}

Here are our suggestions to handle this:

  • Collect the answers: You can implement a frontend component that dynamically renders a form based on the Kombo API response. The candidate can then submit the actual answers to screening questions and you can submit them to the ATS.

    While this would sure be the cleanest solution, some of our customers don’t want to implement this because it violates their idea of a one-click-apply solution or takes too much engineering capacity.

  • Ask the customer to remove questions: if you don’t want to collect the answers to screening questions, you could ask your customer to remove these questions.

  • Clearly submit non-data: For most fields (except for dropdowns, numbers, and booleans) you can “auto-fill” some data that will make it clear to your customer that this is not an actual response from the candidate. For example, submitting an empty string or “-” for text fields, submitting a date that is very clearly in the past, etc.

    ✋ Be wary with this approach: your customer explicitly sets those questions to be required and might not appreciate you working around their requirement.

  • Implement customer-specific logic: A less scalable way is to implement custom logic for each customer that either hard-codes data points or dynamically maps them based on other data of the candidate. This approach is sometimes the most pragmatic solution if you have a low number of customers that require screening questions, however, it’s not very scalable with a large number of customers in production.

    • Agree on preset answers: When onboarding a customer you can share the problem of required screening questions with them and agree together on a number of fixed answers for all/the most common screening questions.

Dealing with required custom fields

Kombo has the option to process SuccessFactors required custom fields as screening questions, so that they can form part of your application form. Please reach out to Kombo to enable this feature.