API & ATS

A private, read-only API that gives your ATS the applications to your company's vacancies. A company admin issues the key on the API & ATS page of your employer workspace, and every request sends it as a Bearer token.

Keys and webhooks are managed by your company admins on the API & ATS page. Open API & ATS

Authentication

One key per company. We store only a hash of it and show it to you once. Each key may make up to 60 requests per minute. Once a key is rotated or revoked, requests with it are rejected immediately.

https://jobico.io/api/v1
curl "https://jobico.io/api/v1/applications?since=2026-10-01T00:00:00Z&limit=50" \
  -H "Authorization: Bearer jk_live_..."

Endpoints

  • GET /api/v1/jobs - your jobs with id, slug, title, status, url and createdAt, so you can match them to the vacancies in your ATS
  • GET /api/v1/applications - applications to your jobs, oldest first. Filters: job (job id), since (ISO date), page and limit (up to 100)
  • GET /api/v1/applications/:id - a single application by its id

Application payload

You only get applications the candidate submitted themselves. Contact details and the CV are included once the candidate has shared their contacts with your company, which every application submitted on Jobico does. CV links are plain file URLs: if the candidate deletes the file, the link stops working, so download the file as soon as you receive it.

{
  "data": [
    {
      "id": "6abc0000000000000000ab12",
      "status": "applied",
      "appliedAt": "2026-10-01T09:12:33.000Z",
      "job": { "id": "6ab1...", "slug": "senior-product-designer", "title": "Senior Product Designer", "url": "https://jobico.io/jobs/senior-product-designer" },
      "candidate": { "name": "Olena Shevchenko", "email": "olena@example.com", "phone": "+380..." },
      "cv": { "url": "https://...vercel-storage.com/cv/.../resume.pdf", "fileName": "resume.pdf" },
      "coverLetter": "...",
      "screeningAnswers": [{ "question": "...", "answer": "..." }],
      "matchScore": 87,
      "url": "https://jobico.io/employer/applications/6abc0000000000000000ab12"
    }
  ],
  "page": 1,
  "limit": 50,
  "total": 1
}

Webhook: application.created

Add an HTTPS endpoint on the API & ATS page and we POST every new application to it. The body carries the event type, a timestamp and the application payload above in the data field.

POST https://ats.example.com/hooks/jobico
content-type: application/json
user-agent: Jobico-Webhooks/1.0
webhook-id: 6abd1111111111111111cd34
webhook-timestamp: 1791021600
webhook-signature: v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=

{ "type": "application.created", "timestamp": "2026-10-03T10:00:00.000Z", "data": { ...application } }

Verifying the signature

Deliveries follow the Standard Webhooks spec and carry three headers: webhook-id, webhook-timestamp and webhook-signature. To check a delivery, join the id, the timestamp and the raw body with dots and sign that string with HMAC-SHA256 using the base64-decoded secret. Any Standard Webhooks library does this for you.

import { createHmac, timingSafeEqual } from 'node:crypto';

const verifyJobicoWebhook = ({ secret, headers, rawBody }) => {
  const key = Buffer.from(secret.replace('whsec_', ''), 'base64');
  const signed = `${headers['webhook-id']}.${headers['webhook-timestamp']}.${rawBody}`;
  const expected = `v1,${createHmac('sha256', key).update(signed).digest('base64')}`;
  return headers['webhook-signature']
    .split(' ')
    .some((sig) => sig.length === expected.length && timingSafeEqual(Buffer.from(sig), Buffer.from(expected)));
};

Retries and delivery guarantees

Reply with a 2xx within 10 seconds (5 seconds on retries) and the delivery counts as done. Otherwise we try again no sooner than 1 minute, 5 minutes, 30 minutes, 2 hours and 8 hours later (the retry worker runs every 10 minutes), then stop. Delivery is at-least-once, so deduplicate by webhook-id.

While the webhook is paused, nothing is sent and nothing is queued: applications that arrive in the meantime can be pulled from the API with the since filter. Deliveries that were already retrying when you paused wait and go out once you switch it back on. Removing the webhook drops anything still waiting.

ATS integrationsComing soon

Ready-made connectors for popular applicant tracking systems are on the way. Until then the API and webhook above do the same job. Need a specific system first? Write to support@jobico.io.

  • Greenhouse
  • Lever
  • Teamtailor
  • PeopleForce
  • Workable

Usage rules

  • API keys and webhook secrets are confidential. Your company is responsible for every request made with them and must rotate them if they are ever exposed.
  • Candidate data you receive through the API or webhooks may be used only to process applications to your own vacancies, and must be deleted when the candidate asks.
  • Usage is subject to our Terms of Service