Skip to content
Recruit Swipe

Docs / For ATS engineering teams

The adapter model

For ATS and job board engineering teams — the interface every provider implements, where the code runs, and how capabilities gate what the product offers.

This page is for engineers at an ATS or job board evaluating what integrating with us actually involves on your side. The short version: one adapter, all traffic server-side, and capabilities declared rather than assumed.

One interface per provider

Every source implements the same TypeScript interface:

Connection lifecycle — begin authentication, complete authentication, test the connection.

Reads — list open requisitions, list candidates for a requisition, get one candidate. All paginated, all normalised into our internal shapes at the boundary.

Capabilities — what this provider can do, plus the stage list, tag list, and where available the email template list. These drive what the product offers.

Writes — advance stage, reject, add tag, send message, add note. All optional. A provider that does not support one simply does not implement it, and the app never offers it.

Every write input carries the requisition id alongside the candidate id, because several providers cannot disambiguate which application of a multi-job candidate an action refers to without it.

Where the code runs

The adapter that the mobile app holds contains capabilities and metadata only. The actual HTTP client for each provider runs server-side, in an edge function, and that is the only place a credential is ever in plaintext.

Practically this means:

  • Credentials sit in an encrypted vault, decrypted per call after an ownership check, under the recruiter’s own authenticated session.
  • Nothing about your API is reachable from a user’s device.
  • Rate limiting, backoff, retry, and logging live in one shared transport rather than being reimplemented per provider.
  • We can fix an integration for every customer at once without waiting on an app store review.

Capability gating

If we cannot verify how an operation works against your API, we report it as unsupported. The action does not appear in the configuration UI, and if a stored configuration references it, the executor records it as skipped with a stated reason.

This is why several of our integrations list writes that are deliberately not offered — Ashby’s reject, Teamtailor’s notes and tags, Manatal’s stage change. Those are not gaps in the adapter, they are gaps in what we could confirm without a sandbox.

Adding a provider

A new provider is one adapter file for capabilities and metadata, one server-side client module, a registration line, and an entry in the connect screen. Nothing else in the app changes. When your API is documented and self-serve, that is a day of work.

What we would ask you for

A sandbox tenant, and answers to the specific endpoint questions our adapter could not resolve from the public docs. See partnering with us.