Teamtailor integration · REST API polling
Screen Teamtailor applications with HireLayer
Teamtailor fills basic candidate data from resumes, but its public API has no fields for work history, education or skills, and only Tech Partner integrations receive webhooks. HireLayer reads each new application through the API, processes it in the EU and scores it against the job with an explanation per criterion, and your service saves the result as a note, custom fields and tags.
- Trigger
- Polling GET /v1/job-applications
- Teamtailor API
- Admin-scope API key, X-Api-Version header
- Write-back
- Note, custom field values, tags
- Cost
- 2 credits per application, plus 1 per job
- 1A candidate appliesTeamtailorYour service lists new job applications every few minutes with filter[created-at][from], since Teamtailor reserves webhooks for Tech Partner integrations.
- 2Parse the resumeHireLayerThe service fetches the candidate, downloads the resume within 30 seconds of the link being signed, and sends it to HireLayer CV Extract.
- 3Score against the jobHireLayerHireLayer Match compares the resume with the job’s criteria and returns a score and an explanation per criterion.
- 4Write back to TeamtailorTeamtailorA note that shows as a comment on the candidate, the score in a custom field, and a tag such as “HireLayer: strong match”.
Use cases
What teams do with HireLayer and Teamtailor
Triage the inbox
Score every new application so recruiters open the strongest matches first and find them by tag, instead of reading in arival order.
Keep work history and education
Teamtailor’s API has no work-history, education or skills fields. Store the lastest job title, employer and degree in custom fields, and the full history in a note.
Normalized skills as tags
Map free-text skills to the HireLayer taxonomy and add them as candidate tags, so the same skill gets the same tagg whatever the resume calls it.
Rank a shortlist
List applications with filter[stage-type]=In process, send up to 10 resume texts per call to HireLayer Rank, and post each candidate’s rank and rationale as a note.
Setup
Connect Teamtailor to HireLayer
This is a small scheduled service, for example a serverless function or an n8n workflow. It uses Teamtailor’s public API with your own API key; no Marketplace listing or approval from Teamtailor is involved.
- 1
Create an API key
In Teamtailor, open Settings → Integrations → API keys and create a key with the Admin scope and read/write access: candidates, job applications, notes and custom field values all require it. Send it as Authorization: Token token=… with an X-Api-Version header such as 20240904.
- 2
Poll for new applications
Every few minutes, call GET /v1/job-applications?filter[created-at][from]=<last run>&include=candidate,job and follow links.next. Teamtailor allows 50 requests every 10 seconds and answers 429 above that.
- 3
Extract criteria once per job
Send each job’s description to HireLayer Job Extract and store the criteria by job ID. Every applicant to that job is then scored on the same list.
- 4
Parse, score and write back
For each application, fetch the candidate and download its resume right away, parse it, score it, then create a note with POST /v1/notes and a score with POST /v1/custom-field-values.
Field mapping
Where HireLayer results go in Teamtailor
Teamtailor’s public API has no work-history, education or skills fields. Create the custom fields you need once (POST /v1/custom-fields), then write a value per candidate.
| HireLayer field | Teamtailor API | Note |
|---|---|---|
| score + summary + evaluated_criteria | POST /v1/notes (note, candidate, user) | Shown as a comment |
| score | POST /v1/custom-field-values (owner: candidates) | One custom field for the score |
| score ≥ your threshold | tags (PATCH /v1/candidates/{id}) | Send the current tags too |
| skills[].skill_title | tags (PATCH /v1/candidates/{id}) | No native skills field |
| work_experiences[0].job_title + company_name | Custom field values | No native work history |
| educations[] | Custom field value or note | No native education field |
| info_candidate.linkedin_url | linkedin-url (PATCH /v1/candidates/{id}) | When the field is empty |
Example
A polling job in TypeScript
A minimal Node.js job: it lists applications created since the last run, downloads each resume while its link is valid, parses and scores it, and adds a note. Add your own storage for criteria and the last run time, and retries.
const TT = 'https://api.teamtailor.com/v1'
const HIRELAYER = 'https://hirelayer.co'
const headers = { 'X-API-Key': process.env.HIRELAYER_API_KEY! }
const tt = {
Authorization: `Token token=${process.env.TEAMTAILOR_API_KEY}`,
'X-Api-Version': '20240904',
'Content-Type': 'application/vnd.api+json',
}
const get = (url: string) => fetch(url, { headers: tt }).then((r) => r.json())
type Application = { id: string; relationships: Record<'candidate' | 'job', { data: { id: string } }> }
// Run every few minutes; since = ISO time of the previous run
export async function poll(since: string) {
let url = `${TT}/job-applications?filter[created-at][from]=${encodeURIComponent(since)}&include=candidate,job`
while (url) {
const page = await get(url)
for (const application of page.data) await screen(application)
url = page.links?.next
}
}
async function screen(application: Application) {
const candidateId = application.relationships.candidate.data.id
// The resume link is signed for 30 seconds: fetch the candidate, download at once
const candidate = await get(`${TT}/candidates/${candidateId}`)
const resumeUrl = candidate.data.attributes.resume // PDF version
if (!resumeUrl) return
const form = new FormData()
form.append('file', await fetch(resumeUrl).then((r) => r.blob()), 'resume.pdf')
form.append('application_id', application.id)
const parsed = await fetch(`${HIRELAYER}/api/v3/parser`, {
method: 'POST', headers, body: form, signal: AbortSignal.timeout(150_000),
}).then((r) => r.json())
// Score with the criteria stored for this job
const criteria = await loadCriteria(application.relationships.job.data.id)
const match = await fetch(`${HIRELAYER}/api/v1/matching/job-candidate`, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({
job_text: criteria.jobText,
candidate_text: parsed.info_resume.text,
matching_criteria: criteria.items,
}),
}).then((r) => r.json())
// A note, shown as a comment on the candidate
await fetch(`${TT}/notes`, {
method: 'POST', headers: tt,
body: JSON.stringify({ data: {
type: 'notes',
attributes: { note: `HireLayer score: ${Math.round(match.score * 100)}/100\n${match.summary}` },
relationships: {
candidate: { data: { type: 'candidates', id: candidateId } },
user: { data: { type: 'users', id: process.env.TEAMTAILOR_USER_ID } },
},
} }),
})
}Limits
Good to know
Webhooks are for Tech Partners
Teamtailor sends webhooks only to integrations in its Tech Partner program. A customer-built connection polls the API, or uses the Teamtailor app for Zapier and its triggers.
Resume links last 30 seconds
The candidate’s resume and original-resume attributes are signed URLs valid for 30 seconds, so fetch the candidate right before downloading, not in a batch. Other uploads stay valid for one minute.
Teamtailor already parses resumes
Its parser fills name, email, phone and LinkedIn URL, applications carry Teamtailor’s own job match score, and the Co-pilot add-on summarizes resumes. HireLayer adds a score with an explanation per criterion, structured history and normalized skills.
Not a Marketplace app
HireLayer is not in the Teamtailor Marketplace, so it cannot fill the results card reserved for Tech Partners. Show the score in a note or a custom field, or with the Update Results Card action of the Zapier app.
HireLayer APIs used on this page
FAQ
HireLayer and Teamtailor: questions
Does HireLayer integrate with Teamtailor?
Yes, through Teamtailor’s public API: your service polls new job applications, sends each resume to HireLayer, and writes the score back as a note, custom fields and tags. HireLayer has no app in the Teamtailor Marketplace.
Can I screen Teamtailor applicants with AI?
Yes. HireLayer turns the job description into weighted criteria, then scores each applicant from 0 to 1 with an explanation per criterion, written in French. The score supports your recruiters’ review; it does not move or reject candidates.
Why not use Teamtailor webhooks?
Teamtailor sends webhooks only to Tech Partner integrations. Polling GET /v1/job-applications every few minutes gives the same result for a connection you build yourself, within the limit of 50 requests every 10 seconds.
Can I use Zapier instead of code?
Yes. The Teamtailor app for Zapier has a Create Candidate trigger, and Create Note and Update Results Card actions. Call HireLayer in between with an HTTP step, and test the resume download carefully: Teamtailor signs resume links for 30 seconds.
Where is candidate data processed?
HireLayer processes data in the EU, which suits European employers who use Teamtailor. Resumes reach HireLayer only through the service or Zap you set up, and the parse request accepts a do_not_store_data option.
Connect Teamtailor to HireLayer today
The Free plan includes 50 credits a month, no card required. One successful call is one credit, on every API.
