Webhooks logo

Deliver job applications to your hiring service

Every application is posted as JSON to your applicant tracking service, which validates the fields before it creates a candidate.

When this happens

New submission on your job application form

Do this

POST the applicant JSON to your hiring microservice, which parses the fields and creates a candidate record

One-directional. A submission triggers the action — nothing is written back into your form.

Companies that built their own applicant tracking usually did it because an off-the-shelf one did not fit how they hire. The gap that leaves is intake: applications land in a form and someone has to move them into the service. This flow closes it by posting each application as JSON the moment it is submitted.

The service stays the authority on what a complete application is. It validates the required fields, creates the candidate record, and rejects an incomplete payload with a non-2xx so the delivery is recorded as failed rather than half-accepted.

Setting it up

  1. 1

    Publish one application form per opening, or keep Position Applied For a select whose options match the requisition names your service already knows.

  2. 2

    Expose a POST route on your hiring service — /webhooks/applications — that accepts a JSON body and is reachable from the public internet.

  3. 3

    Enable the outgoing webhook in the form's settings, paste the route URL, and save the form.

  4. 4

    Send a test application and log the body, noting the exact keys for Position Applied For, Available Start Date and Cover Letter.

  5. 5

    Validate before you create anything: require Email Address and Position Applied For, and return a 4xx when either is missing so the delivery is recorded as failed.

  6. 6

    Resolve Position Applied For to a requisition id inside the service, and reject a value that matches no open requisition rather than creating an orphan candidate.

  7. 7

    Parse Available Start Date into a real date type at the boundary, so a recruiter can sort a shortlist by availability instead of reading strings.

  8. 8

    Create the candidate with Work Experience and Cover Letter stored as text, then return 2xx once the record has an id.

What maps where

Using the Job Application Form as the starting point. These are its real fields — swap in your own and the mapping works the same way.

Form fieldWebhooks
Full Namecandidate name on the new record
Email Addresscandidate email, the deduplication key in your service
Position Applied Forrequisition the candidate is attached to
Available Start Datestart date on the candidate, parsed to a date type
Work Experienceexperience section of the candidate record
Cover Lettercover letter text stored with the application

Variations worth knowing

Reject incomplete applications loudly

Return a 422 naming the field that was missing rather than a bare 400. The delivery is recorded as failed either way, but your own logs keep the reason, and a run of the same missing field usually means the question is worded badly rather than that applicants are careless.

Screen on employment type before the record exists

When a requisition is full-time only, branch on Employment Type in the handler and write the mismatches to a separate table instead of the candidate pipeline. Nobody is dropped, and the recruiter's queue stays the set of people who could actually take the job as it is written.

If something isn't arriving

Candidates arrive attached to the wrong requisition.

Position Applied For arrives as the text of a select, so a renamed option no longer matches the requisition it used to. Key the lookup on a stable id you keep in the option label, and fail the request when nothing matches rather than falling back to a default requisition.

Applications submitted overnight never appear.

Check whether your service sleeps or scales to zero. A route that is unreachable when the POST arrives cannot record anything, and you should not assume a failed delivery will replay itself. Keep the endpoint warm, or put a small always-on receiver in front that writes the body down and hands it on.

Frequently asked questions

Can I use one form for several openings?

Yes, if Position Applied For is a select whose options map to your requisitions. One form keeps the endpoint simple; separate forms per opening give you separate webhook URLs, which is easier when different teams own different services.

Does the applicant see anything my service returns?

No. The POST goes one way and only the HTTP status comes back, so nothing your service produces is written into the form or shown to the applicant. Send the acknowledgement email from your hiring service once the candidate record exists.

How do I stop duplicate applications from the same person?

Deduplicate in your service on Email Address plus the requisition. The form does not know what your database already holds, so it cannot block a second submission — a unique constraint on that pair, with an update on conflict, keeps the pipeline clean.

Related automations

Build the form first

The automation needs somewhere to fire from. Publish a form, connect it once, and every submission from then on runs this flow.

Start free