Industry Insights

How to Integrate Your ATS With a Mobile-First Application Flow

· 5 min read

Connecting an applicant tracking system to a mobile-first application flow is two separate integrations, not one. Jobs have to travel out of the ATS into the channels where candidates actually are, and completed applications have to travel back into the ATS as real candidate records. Most teams build the first half well and improvise the second half, which is why recruiters end up copying leads out of a spreadsheet at 8am.

This guide covers the patterns that work, the tradeoffs between feeds, webhooks and direct API calls, what the major ATS platforms actually support, and the mapping and privacy decisions that decide whether the integration survives contact with high volume hiring.

What is the right architecture for ATS to mobile integration?

Use a feed for outbound job data and an authenticated API push for inbound applications, with a webhook or queue in between to absorb failures.

That combination wins because the two directions have opposite requirements. Outbound job data is low volume, tolerant of a few minutes of latency, and needs to be readable by many downstream systems at once. Inbound application data is spiky, time sensitive, and can only go to one place. Trying to use a single mechanism for both is the most common design mistake in recruitment integrations.

Should you use a feed, a webhook, or a direct API call?

Pattern

Best for

Latency

Failure mode

XML or JSON feed

Publishing open roles outward

Minutes to hours

Stale jobs stay live until next fetch

Webhook

Reacting to events like a new application

Seconds to minutes

Silent loss if your endpoint is down

Direct API call

Writing candidate records into the ATS

Immediate

Rate limits and partial writes

A feed is a single URL that lists every open role in a structured format. It is pull based, so the consuming system decides how often to refresh. This is why feeds are the default for job distribution: one artifact serves every ad platform, career site and aggregator without you building a separate connection for each.

A webhook is push based. Your endpoint receives a small payload the moment something happens. Meta's lead ads webhook, for example, fires a leadgen event carrying leadgen_id, page_id, form_id, adgroup_id, ad_id and created_time, and you then call the Graph API with that leadgen_id to retrieve the actual field_data. Meta notes that real time pings occur with a delay of up to a few minutes, so a webhook is fast but not instantaneous.

A direct API call is what finally creates the candidate in the ATS. This is the step that needs the most defensive engineering, because it is the only one where a failure loses a real applicant.

How should you structure the outbound job feed?

Keep the feed the single source of truth for what is open, and let job status drive ad status automatically.

Three rules matter more than the format you choose:

A role that closes in the ATS must disappear from the feed on the next refresh. Google's job posting guidance is explicit that jobs no longer open for applications must be expired by setting validThrough to a date in the past, removing the page so it returns a 404 or 410, or removing the JobPosting structured data from the page. The same discipline applies to paid distribution. Spend against a filled role is pure waste.

The feed needs a stable unique identifier per role that never gets reused. This is what lets downstream systems match an application back to a requisition without guessing on job title, which breaks the moment you open three warehouse operative roles in two cities.

Include the fields the destination actually needs. For search visibility, Google requires datePosted in ISO 8601 format, description in HTML, hiringOrganization, jobLocation and title, and requires validThrough for any posting that has an expiration date. For social advertising, you also need location granularity, employment type, and enough description text to generate creative from.

How do you push a mobile application back into the ATS?

Write to the ATS through a server side service, never directly from the client.

The flow looks like this. The candidate completes a short mobile form. The form posts to your own endpoint. That endpoint validates the payload, writes it to a queue, and returns success to the candidate immediately. A worker then reads from the queue and calls the ATS API. If the ATS call fails, the job stays on the queue and retries with backoff.

The queue is the part teams skip and later regret. Without it, an ATS rate limit or a two minute outage during a Monday morning traffic spike drops applications on the floor with no record that they existed.

Field mapping is where the detail lives. At minimum you need first name, last name, email, phone, the requisition identifier, the source, and the answers to any knockout questions. Map knockout answers into structured ATS fields rather than dumping them into a free text note, because a note cannot be filtered and a recruiter cannot build a view from it.

How do you stop duplicate candidate records?

Deduplicate on email address before the write, and make the write itself idempotent.

Candidates apply twice. They apply on Instagram in the evening and again on the career site the next morning, and they use the same email both times. If your integration creates two records, your recruiters lose trust in the pipeline within a week.

Two defenses work together. Before creating a candidate, search the ATS for the email address and attach a new application to the existing candidate if one is found. Second, store your own idempotency key, typically a hash of the form submission identifier, so a retry after a timeout does not create a second record when the first write actually succeeded but the response was lost.

Rate limits shape how aggressively you can do this. Greenhouse limits Harvest API requests to the amount specified in the returned X-RateLimit-Limit header per 10 seconds, returns HTTP 429 when you exceed it, and provides X-RateLimit-Reset and Retry-After headers telling you when to retry. Lever enforces a default of 10 requests per second per API key, with bursts up to 20 requests per second depending on server load. Honor those headers rather than guessing at a sleep interval.

What do the major ATS platforms support?

Greenhouse. The Harvest API uses Basic Authentication over HTTPS, with your API token as the username and a blank password. It exposes endpoints for jobs, job posts, candidates and applications, including POST to add a candidate. Pagination defaults to 100 records per page with a maximum per_page of 500, using RFC 5988 Link headers.

Lever. The Data API supports both API key Basic Auth for internal workflows and OAuth for partner integrations. Its webhook events include applicationCreated, candidateHired, candidateStageChange, candidateArchiveChange, candidateDeleted, interviewCreated, interviewUpdated, interviewDeleted, contactCreated and contactUpdated.

Workday. REST requests use OAuth 2.0, where you register an API client in Workday and grant scopes such as Recruiting, Candidate Engagement and Pre-Hire Process, then obtain access tokens. SOAP requests are authenticated with an Integration System User account using WS-Security headers. Expect the Workday side to require coordination with an internal administrator, since scopes and security groups are configured in the tenant rather than by the integrating vendor.

The practical takeaway is that authentication is the schedule risk, not the code. Budget for the access request, not the endpoint call.

What are the privacy requirements?

Decide your lawful basis before you write a line of code, because it changes the data model.

Greenhouse, for example, offers legitimate interest or contract as the default, where candidates are not prompted specifically to provide data consent, and explicit consent as the stricter option, where a candidate has to individually agree to the specific use of their data. Under explicit consent, if a candidate does not provide consent within a set time frame, their data is flagged for deletion.

That difference has direct engineering consequences. If you operate on explicit consent, the consent event and its timestamp are part of the payload you push into the ATS, not an afterthought stored in the ad platform. Lead form ads on social platforms collect personal data at the point of the ad, which means the consent language sits in the form itself and the record of it has to travel with the candidate. Anything else leaves you unable to demonstrate lawful processing when asked.

Keep personally identifiable information off client side analytics, transmit it only server to server, and log integration errors without logging the candidate payload.

How fast does the mobile side need to be?

Fast enough that speed is not the reason people leave. Google's guidance for a good user experience is a Largest Contentful Paint of 2.5 seconds or less, measured at the 75th percentile of page loads, segmented across mobile and desktop.

That threshold is worth treating as a hard requirement on a recruitment form. Traffic arriving from a social feed is on mobile data, often mid scroll, with no prior intent. Every field you add and every redirect between the ad and the form costs completions. The technically elegant integration that adds an interstitial redirect will lose to the crude one that does not.

Implementation checklist

  1. Confirm the ATS authentication method and request credentials first.

  2. Publish a job feed with stable unique identifiers and automatic expiry.

  3. Build a server side ingestion endpoint that responds before the ATS write.

  4. Put a queue with retry and backoff between ingestion and the ATS.

  5. Map knockout answers to structured ATS fields, not free text notes.

  6. Deduplicate on email and use an idempotency key on writes.

  7. Honor rate limit headers rather than fixed sleeps.

  8. Carry consent state and timestamp into the ATS record.

  9. Alert on failed writes and on a feed that has not refreshed.

  10. Test with a real requisition end to end before launch, including a rejection path.

Frequently asked questions

Do I need an API integration, or is an XML feed enough?
A feed alone is enough only if candidates finish their application inside the ATS itself. The moment applications are captured outside the ATS, on a social lead form or a standalone mobile flow, you need a write path back in.

How often should the job feed refresh?
Frequently enough that a filled role stops receiving spend the same day. Many distribution systems fetch on a schedule you do not control, so the safer design is a feed that is always current rather than one you regenerate nightly.

Should applications go into the ATS immediately or after screening?
Screen first when volume is high. Sending every raw application into the ATS shifts the filtering work onto recruiters, which is the cost the integration was supposed to remove. Knockout logic at the point of application keeps unqualified volume out of the pipeline entirely.

What happens if the ATS is down when someone applies?
Nothing visible to the candidate, if you built the queue. The application is accepted, held, and written when the ATS recovers. Without a queue, the applicant sees an error and does not come back.

Who owns this integration internally?
In practice it sits between talent acquisition operations and IT, which is why it stalls. Name one owner on the TA side who can make mapping decisions, and one technical contact who can grant ATS credentials, before the project starts.

Never miss a post

Ready to write your own results?

Tell us what you need to hire and we'll show you what Wonderkind can do for your roles.

No credit card required

wonderkindInterview-ready candidates, delivered into your ATS.
Get startedBook a demoTry for freeSign inTrust centreStatus