Skip to content

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
Teamtailor + HireLayer
  1. 1A candidate appliesTeamtailorYour service lists new job applications every few minutes with filter[created-at][from], since Teamtailor reserves webhooks for Tech Partner integrations.
  2. 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.
  3. 3Score against the jobHireLayerHireLayer Match compares the resume with the job’s criteria and returns a score and an explanation per criterion.
  4. 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. 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. 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. 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. 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 fieldTeamtailor APINote
score + summary + evaluated_criteriaPOST /v1/notes (note, candidate, user)Shown as a comment
scorePOST /v1/custom-field-values (owner: candidates)One custom field for the score
score ≥ your thresholdtags (PATCH /v1/candidates/{id})Send the current tags too
skills[].skill_titletags (PATCH /v1/candidates/{id})No native skills field
work_experiences[0].job_title + company_nameCustom field valuesNo native work history
educations[]Custom field value or noteNo native education field
info_candidate.linkedin_urllinkedin-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.

teamtailor-poll.tstypescript
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.

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.