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.
New submission on your job application form
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
Publish one application form per opening, or keep Position Applied For a select whose options match the requisition names your service already knows.
- 2
Expose a POST route on your hiring service — /webhooks/applications — that accepts a JSON body and is reachable from the public internet.
- 3
Enable the outgoing webhook in the form's settings, paste the route URL, and save the form.
- 4
Send a test application and log the body, noting the exact keys for Position Applied For, Available Start Date and Cover Letter.
- 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
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
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
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 field | Webhooks |
|---|---|
| Full Name | candidate name on the new record |
| Email Address | candidate email, the deduplication key in your service |
| Position Applied For | requisition the candidate is attached to |
| Available Start Date | start date on the candidate, parsed to a date type |
| Work Experience | experience section of the candidate record |
| Cover Letter | cover letter text stored with the application |
Variations worth knowing
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.
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
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.
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
- Fan event sign-ups out to your own services
One POST per RSVP writes the attendee to your database and publishes a message the rest of your services can listen for.
- Push support requests onto your own job queue
Every support submission is posted to an endpoint that enqueues the request and sets its priority from the answer on the form.
- Send custom orders to your fulfilment backend
Each order submission is posted to your orders API, which records the items and starts fulfilment with nothing rekeyed by hand.
- Stream feedback scores into your analytics pipeline
Each NPS response is posted to an ingestion endpoint that normalises the score and streams the record into your warehouse.
- Write new leads straight into your own database
Each lead capture submission reaches your endpoint as JSON and becomes a row in your own leads table, seconds after it is sent.
- Add job applicants to a hiring pipeline
Each application becomes a Candidates record with role, start date and stage, ready to drag through a kanban view.
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