Refari is more than a website tool
Before the endpoints: what a Refari integration actually connects to, and why it asks for the data it does.
A conventional ATS-to-website integration is one-dimensional: jobs are pushed out to a careers page and applications come back. Refari operates on a different level. Alongside a branded job board, embeddable widgets and auto-maintained recruiter profiles, it is a recruitment marketing and engagement platform. It tracks referrals end to end, treats every application-status change as a trigger for transparency and communication, runs sentiment analytics through TopRec, and markets candidates out to demand through TalentReach and the Talent Board, much of it surfaced directly inside your ATS.
This is why the integration asks for more than a job feed. Job Orders, hiring-manager Contacts, recruiters, detailed locations and, critically, every application status (even for roles that never touched a Refari job board) are what power the capabilities below. A developer scoping this work should read Refari as a two-way engagement engine, not a publishing target.
Deep referral tracking & attribution
Built on Refari's Referrer.io heritage. Digital and traditional referrals are captured, attributed to the referrer, given ownership windows, and carried through to placement and reward reporting.
Status transparency & communications
Every application-status change is a heartbeat. Referral Transparency keeps referrers informed as their candidate progresses, and statuses drive automated, stage-appropriate communications to the right people.
TopRec sentiment analytics
Using Job Orders and hiring-manager Contacts, TopRec gathers structured feedback and testimonials at the right moments in the pipeline, turning placements into measurable sentiment and social proof.
Candidate marketing: TalentReach & Talent Board
Market your candidates, not just your jobs. Publish and promote available talent to employers and hiring managers with Candidate Ads and Talent Alerts, the mirror image of a job advert.
Embedded workflows (Partner Actions)
Refari's highest-value actions, socialising a role, generating Smartlinks, creating Candidate Ads, job alerts and referrals, launch from inside your ATS with the right context already loaded.
A real, two-way event stream
Webhooks push website and candidate activity back to you in real time, so recruiters act on engagement from the candidate record in your ATS rather than polling for changes.
Four tiers, building on one another
Each tier includes everything before it. Bronze delivers a complete, working integration; Platinum embeds Refari directly inside your ATS. The split lets a partner adopt the platform progressively, and lets a client buy in at the depth that suits them.
A complete, working integration
Jobs in, candidates and applications back, with full referral attribution and status-driven automation.
What the client gets
A live, branded job board and team widgets on their site, two-way candidate and application sync, recruiter profiles that publish themselves, and Refari's core referral engine running end to end, with transparency and communications driven by application status. Everything needed for the platform's referral and testimonial engines to operate.
Capabilities unlocked
- Job board, widgets and recruiter profile pages
- Digital and traditional referrals, with attribution and ownership windows
- Candidate and application sync, plus resume ingestion
- Application-status tracking driving Referral Transparency and comms
- Recruiter auto-invite, publish and removal
- Detailed location data for maps, feeds and parent/child boards
- Placements feeding the Referral CSV report
What you integrate
Higher-quality, mapped data capture
Capture richer applicant data and map it cleanly back into your ATS fields.
Builds on BronzeWhat the client gets
Screener questions authored in either system, with each answer mapped to a specific ATS field so the data lands in the right place automatically rather than as free text to be re-keyed. This is the groundwork for full, composable data-capture forms.
Capabilities unlocked
- Screener questions: text, list and file, with required and multi-select
- Two-way authoring (build them in the ATS or in Refari)
- Dashboard field mapping, surfaced on the application answers
- A forward path to composable data-capture forms
What you integrate
A genuine two-way conversation
Stop polling. Refari pushes website and candidate events to you in real time.
Builds on SilverWhat the client gets
Live signals of what candidates and referrers do on the site and across Refari's tools, used to add notes to candidate records, trigger workflows and surface engagement inside the ATS. This is the headline Gold capability: mapping website events to candidate records.
Capabilities unlocked
- 19 subscribable events across applications, candidates, referrals, alerts, testimonials, feedback, saved jobs and social shares
- BLAKE2-signed delivery, automatic retries, up to 3 endpoints per event
- Rich payloads for referral_created and socialise_created
- Website events written back to candidate records
What you integrate
Refari embedded inside your ATS
The deepest tier: high-value Refari workflows launch from within your platform, context preloaded.
Builds on GoldWhat the client gets
One joined-up workflow. Recruiters socialise roles, generate Smartlinks, open jobs in the widget, make post-production edits, create job alerts, market candidates through Candidate Ads (TalentReach and the Talent Board) and create referrals, all without leaving the ATS. It is also strong material for sales demonstrations.
Capabilities unlocked
- Partner Actions for Job Ads, Job Orders and Candidates
- Candidate marketing launched from the ATS, even for candidates not yet synced
- Socialise, Smartlinks/job links, widget detail and post-production edits
- Job alerts and referrals created in context
What you integrate
How this guide is organised
Each capability is documented as a use case you can scope and build independently.
The sections that follow group the integration into foundational data, the candidate and application lifecycle, and the advanced and embedded layer. Every use case carries the tier it belongs to and is documented the same way: what it is and why it matters, how the integration works, the exact endpoints (method, path and operation), and a short list of field notes and gotchas.
Throughout, note that objects can depend on one another. For example, you must create a company record before an advert can reference it, and the recruiter, category, work type and location an advert points at must all exist in Refari first. To resolve one of your ATS records to its Refari id, look it up by your own external_id on the relevant list endpoint.
Before you start
The conventions that apply across every endpoint in this guide.
🔗Base URL
All endpoints are relative to https://api.refari.co/api/v1/ats.
🔑Authentication
Every request carries your secret key in the API-KEY header. Rotate it with POST /token/reset/ (the old key stops working immediately).
📄Pagination & lookup
List endpoints are paginated with ?page= and accept ?external_id= to resolve your ATS id to a Refari id before referencing it elsewhere.
⚙Ownership & sync
Once an object is edited inside Refari it is flagged is_edited and ATS sync stops for it. Edited Job Ads return 403 on update or delete.
The data Refari needs, and why
For a job board to work, adverts and their associated objects have to flow into Refari. Some associations look excessive at first glance; each one drives a distinct presentation or matching behaviour.
1Job Adverts
BronzeWhat it is and why it matters
Job adverts are the primary payload of the integration. For a job board to function, adverts must flow continuously from the partner ATS into Refari, where they are rendered across job board widgets, custom feeds, recruiter profile pages and integrated external boards. Without a reliable advert feed, none of the downstream presentation layers have anything to display.
A Refari advert is more than a title and a description. Each advert carries associated objects that drive distinct behaviours: location data (both simple and detailed) for list, search and map-style interfaces; work type data so adverts can be filtered and grouped; the owning recruiter, so the advert can be attributed and surfaced on recruiter profile pages (and the recruiter surfaced on the advert); and an optional link to a Job (Job Order), which Refari uses in conjunction with the Job Contact (hiring manager) to power the TopRec process.
Because these associations are by reference, all of those records must exist in Refari before the advert that references them can be created. In practice a partner seeds the supporting objects first, then posts adverts. The key dependency to call out: you must create a company record (a Job Company) before you can create an advert that references it.
How the integration works
The flow is dependency-ordered. Before posting an advert, ensure the referenced recruiter, category, work type, location(s) and (optionally) company, contact and work address exist. Then post with createJobAd. The is_internal flag restricts an advert to the internal job board when true. Adverts are retired with removeJobAd, which marks them expired rather than hard-deleting. Once an advert has been edited inside the Refari dashboard, Refari takes ownership and both update and delete return 403; treat that as an expected terminal state, not an error to retry.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /jobads/ | listJobAd | List / find adverts | Query: page, external_id | Returns JobAdList items. |
| POST | /jobads/ | createJobAd | Create an advert | external_id, title, category, worktype, recruiter, expired_at, created_at | Plus one of location / locations. Referenced objects must already exist; 400 returns "Object does not exist." per field. |
| GET | /jobads/{id}/ | retrieveJobAd | Advert detail | Path id (UUID) | Full JobAd with nested company, category, location, work type, contact, questions. |
| PATCH | /jobads/{id}/ | partialUpdateJobAd | Partial update | Any JobAdUpdate field | 403 if edited in Refari; 400 on bad references / salary / expired_at. |
| DELETE | /jobads/{id}/ | removeJobAd | Expire the advert | Path id | Marks expired (not a hard delete). 403 if edited in Refari. |
Field notes & gotchas
- recruiter on create is the recruiter's Refari UUID; on the returned detail it appears as an integer id, while company, category, location, work type and contact return as nested objects.
- location vs locations: send a single id for simple cases or an array for multi-location adverts. If locations is set, location is ignored.
- salary_currency is an ISO 4217 three-letter code (for example AUD, GBP, EUR). The accepted currency list was extended on 2025-01-25; validate against it before sending. salary_rate_period is one of hour / day / week / month / year, and salary_rate_min must not exceed salary_rate_max.
- description accepts HTML and hashtags; summary drives list views and falls back to the first 150 characters of the description if omitted. description_original is deprecated.
- external_order_id links the advert to its ATS Job (Job Order), supporting the TopRec association. questions attaches screener question UUIDs (see use case 5).
2Recruiters
BronzeWhat it is and why it matters
Many clients struggle to keep their website team pages current through a CMS. Refari team widgets remove that friction and, paired with the ATS integration, can make it largely automatic. When a new recruiter is added to the ATS, the ATS sends them to Refari; Refari automatically invites them to complete their profile, and as soon as they do, they appear on the website. Manager and Admin level users can moderate these profiles to keep them on brand.
The relationship runs across the whole lifecycle. When a recruiter is removed from the ATS, the ATS notifies Refari, which deactivates them and removes them from the website. Recruiters are also load-bearing elsewhere: they own job adverts and Job Orders, so an accurate recruiter list underpins correct attribution across the product. To support this, the integration needs the full set of recruiters and notification when recruiters are deleted. Deactivation is reversible.
How the integration works
Create with createRecruiter (this also assigns an existing recruiter to the agency where one matches, so a duplicate returns 400 "Recruiter already exists."). Creation triggers the profile invitation automatically. Resolve a recruiter to its Refari UUID via listRecruiter, filtering by external_id or email. Deletion is a soft deactivation that removes the recruiter from the website; reactivate via /restore/.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /recruiters/ | listRecruiter | Find / list recruiters | Query: page, external_id, email | Use to resolve a recruiter to its Refari UUID. |
| POST | /recruiters/ | createRecruiter | Create or assign | external_id, email, first_name, last_name | Triggers the profile invitation. 400 if the email is already an agency member. |
| GET | /recruiters/{id}/ | getRecruiter | Get a recruiter | Path id (UUID) | Returns the full Recruiter. |
| PUT | /recruiters/{id}/ | updateRecruiter | Update | first_name, last_name | email and is_active are read-only on update. |
| PATCH | /recruiters/{id}/ | partialUpdateRecruiter | Partial update | Any RecruiterUpdate field | Same read-only constraints as PUT. |
| DELETE | /recruiters/{id}/ | removeRecruiter | Deactivate | Path id | Removes from website. 409 if already deactivated; 400 if disconnected from ATS. |
| POST | /recruiters/{id}/restore/ | reactivateRecruiter | Reactivate | Path id | Reverses a deactivation. 409 if already active. |
Field notes & gotchas
- role enum: consultant / manager / admin (default consultant); this maps to the recruiter's profile-moderation permission level.
- email cannot be changed after creation, and is_active is managed only through DELETE (deactivate) and /restore/, never by setting the field.
- Distinguish the codes: 409 means the state is already what you asked for; 400 on delete means the recruiter is disconnected from the ATS.
- The recruiter's Refari id (UUID) is the value referenced by recruiter on adverts and Job Orders.
7Detailed location data
BronzeWhat it is and why it matters
Refari supports two layers of location information. The first is the categorised Location (a single location id or a locations array) drawn from the agency's taxonomy and used for list views, filtering and search. The second is detailed, structured location data: the Work Address, carrying street, city, state, country, country code and postal code. This is the precise, geocodable address attached to the underlying Job (Job Order).
Detailed location data matters for the more demanding distribution scenarios: feeds into integrated job boards, custom feeds, and clients who want a richer location schema on their own board. It is used heavily by multinational clients who need an unambiguous, fully-qualified address rather than a taxonomy label alone, and it underpins map-style interfaces.
⚠ Hard requirement for parent / child boards
If a client enables a parent/child job board, Refari will not accept any job advert without a Work Address attributed to the Job Order. For those clients, Work Address creation and linkage is a precondition for advert creation, not an optional enrichment.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /work-address/ | listWorkAddress | Find / list addresses | Query: page, external_id | Resolve an address to its Refari id here. |
| POST | /work-address/ | createWorkAddress | Create an address | external_id, name, street, city, state, country / country_code, postal_code | Reference the returned id on the advert via work_address. Mandatory for parent/child boards. |
| PATCH | /work-address/{id}/ | partialUpdateWorkAddress | Partial update | Path id; required external_id | external_id is read-only on update. |
Field notes & gotchas
- country vs country_code: if country (the name) is supplied, country_code is ignored. Send one, not a conflicting pair.
- external_id must be unique; duplicates return "Object with this external_id already exists.".
- The advert references a Work Address by integer Refari id (work_address). The categorised location and the detailed Work Address are complementary; a richly integrated advert typically carries both.
Supporting objects & setup
BronzeThese objects are dependencies of the use cases above. They are referenced by adverts and Job Orders, and the General endpoints underpin initial integration setup. Categories, Locations and Work Types all expose status (published / hidden) plus is_created and is_edited flags (added 2025-11-25); is_edited means the object was edited in Refari and ATS sync for it has stopped.
Categories
A parent/child tree classifying adverts. Required on advert creation, referenced by integer id in category.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /categories/ | listCategory | List / find | Returns JobRelationTree with children, status, flags. |
| POST | /categories/ | createCategory | Create | Required name; optional external_id, parent_id. |
| GET | /categories/{id}/ | detailCategory | Detail | Path id (integer). |
| PATCH | /categories/{id}/ | partialUpdateCategory | Partial update | Body name only. |
Locations
The categorised, taxonomy-level location tree (distinct from Work Addresses). An advert needs at least one of location or locations.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /locations/ | listLocation | List / find | Returns JobRelationTree. |
| POST | /locations/ | createLocation | Create | Required name; optional external_id, parent_id. |
| GET | /locations/{id}/ | detailLocation | Detail | Path id (integer). |
| PATCH | /locations/{id}/ | partialUpdateLocation | Partial update | Body name only. |
Work Types
Separates advert engagement types (for example Permanent, Contract). Required on advert creation, referenced by integer id in worktype.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /worktypes/ | listWorktype | List / find | Returns WorkType items. |
| POST | /worktypes/ | createWorktype | Create | Fields name, external_id. |
| GET | /worktypes/{id}/ | detailWorktype | Detail | Includes status & flags. |
| PATCH | /worktypes/{id}/ | partialUpdateWorktype | Partial update | Body name only. |
Company Clients / Offices (Job Companies)
The client or office a Job Order and advert belong to. Must exist before an advert can reference it, and is a required field for TopRec. Referenced by integer id in company.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /jobs/companies/ | listCompanies | List / find | Returns JobCompany (id, name, is_active). |
| POST | /jobs/companies/ | createCompany | Create | Required name. Prerequisite for adverts and TopRec. |
| GET | /jobs/companies/{id}/ | detailCompanies | Detail | Path id (integer). |
| PATCH | /jobs/companies/{id}/ | partialUpdateCompany | Partial update | Body name, is_active. |
Job Contacts
The hiring-manager records used with the Job Order to drive the TopRec testimonial and feedback process; a placed candidate triggers a feedback email to the contact. Referenced by integer id in contact.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /jobs/contacts/ | listContacts | List / find | Returns JobContact items. |
| POST | /jobs/contacts/ | createContact | Create | Required external_id, email. From 2025-12-01: first_name, last_name, company also required. |
| PATCH | /jobs/contacts/{id}/ | partialUpdateContact | Partial update | external_id read-only on update. |
Job Orders (Jobs)
The internal job record used for the application, referral and testimonial processes, and (with the Job Contact) for TopRec. An advert links to it via external_order_id.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /jobs/ | listJobOrder | List / find | Returns JobOrderList items. |
| POST | /jobs/ | createJob | Create | Required title, recruiter (UUID); optional external_id, company, contact. |
| GET | /jobs/{id}/ | retrieveJobOrder | Detail | Returns job_url (link to the last advert based on this order). |
| PATCH | /jobs/{id}/ | partialUpdateJobOrder | Partial update | Body title, company, recruiter, contact. |
General: Statuses, Settings & Token reset
Foundational setup. Statuses establish the vocabulary used for status matching; Settings register the CRM URL templates Refari uses to deep-link back to your records; Token reset rotates the API key.
| Method | Path | Operation | Purpose | Notes |
|---|---|---|---|---|
| GET | /statuses/ | retrieveStatuses | Get status list | Returns StatusList; used for status matching. |
| POST | /statuses/ | createStatuses | Create / override | Required statuses (array). Replaces the whole list; post the complete set. |
| GET | /settings/ | retrieveSettings | Get settings | Returns CRMData. |
| POST | /settings/ | updateSettings | Save settings | Detail templates must contain the literal {external_id} placeholder. |
| POST | /token/reset/ | resetToken | Reset API-KEY | Old key stops working; confirmation email then a new key. 400 if no reset email on file; 429 if rate-limited. |
The referral and application lifecycle
Refari began life as Referrer.io, so candidate referral is the capability customers ask about most. Getting the candidate and application model right is what makes attribution, transparency and reward tracking possible.
3Candidate Referrals
BronzeWhat it is and why it matters
Candidate referral remains Refari's signature capability. For an integration partner it is the single most important reason to model the candidate and application objects correctly: when a referred candidate converts, the customer expects the referring person to be recognised, communicated with, and (where a reward applies) paid.
Referrals reach Refari in two broad shapes. Digital referrals are generated by Refari's own widgets and job boards on the customer's website and flow back to you. Traditional (direct) referrals are the older, human pattern: a candidate is introduced by phone or email, and a recruiter records the referrer's details on the candidate record in the ATS, which then push to Refari so referral-specific communications can run. The technology is deliberately backwards compatible with both.
How the integration works
There are three referral flavours to map:
- Digital referral, candidate record only. Submitted through a referral widget; Refari creates a candidate with source = "referral". You read it via listCandidate / retrieveCandidate and the candidate_created / referral_created events, then mirror it into the ATS.
- Digital referral, application. A job advert is shared via a referral URL and the candidate applies through that link. Refari attributes the application to the referrer and returns the referrer object on retrieveApplication.
- Traditional / direct referral. The partner is the source of truth: when you create the candidate via createCandidate, include the referrer object (email, first_name and referral_date required). There is no separate referral endpoint.
Referrer attribution is handed back two ways: the near-real-time referral_created webhook (which since 2026-02-25 carries extended candidate data), and synchronously on the application detail via the referrer object alongside rating, source and ownership_expiration.
Field notes & gotchas
- The candidate source enum has three read-only values, set by Refari: applicant (registration widget), referral (job widget), crm (posted via API).
- The application source enum is broader and records the channel: direct, application, application_linkedin, crm, email, facebook, linkedin, twitter, whatsapp.
- ownership_expiration tells you when the referrer's claim to the candidate lapses; surface it if your customers reason about ownership windows.
4Application statuses
BronzeWhat it is and why it matters
In Refari, an application's status is not just a label, it is a trigger. The stages of an application's journey in the ATS (for example Applied, Screening, Internal Interview, External Interview, Offered, Placed) drive several core automations. Different ATS systems use different wording, so Refari does not impose a fixed vocabulary: it works from the customer's own status strings.
Two flagship features depend on these statuses. Referral Transparency keeps a referrer informed as their candidate progresses. TopRec, our sentiment analytics system, uses status changes as the moments at which to act. Because customers choose which status triggers which automation, Refari needs the real status values, presented as selectable triggers.
Send every status, not just Refari-sourced ones
Refari needs all application statuses, including for applications that did not originate from a Refari job board, because a customer may have configured an automation (a testimonial request on Placed, say) that should fire regardless of source.
How the integration works
Push status with the free-text crm_status field on createApplication / updateApplication. To avoid pushing data Refari does not need, call getApplicationImportRules first: it returns the configured triggers grouped into toprec, referrer and progression status-match arrays. Compare an application's crm_status against these before creating. This is an optimisation, not a hard gate, and the response is cacheable (recommended TTL 2 hours).
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /applications/import-rules/ | getApplicationImportRules | Read CRM-status triggers | (none) | Returns toprec / referrer / progression status-match arrays. Cache ~2h. |
| POST | /applications/ | createApplication | Push an application + status | external_id, candidate, job_order, crm_status | Send for all applications, not only Refari-sourced ones. |
| PATCH | /applications/{id}/ | updateApplication | Update status as it progresses | Body usually crm_status | Re-triggers Referral Transparency and TopRec. |
Field notes & gotchas
- crm_status is free text (the customer's own stage label), not an enum, and is required on create.
- The toprec block also returns enabled and enable_candidate, so you can skip TopRec checks entirely when it is switched off.
- referral_status (new / viewed / interviewed / offered / placed) and testimonial_status (new / interviewed_internal / interviewed_external / placed) are Refari-derived and read-only. Send the raw crm_status and let Refari map it.
- external_status is deprecated; use referral_status.
Candidates
BronzeWhat it is and why it matters
The candidate is the person record at the centre of the referral and application lifecycle. Every application and placement ultimately hangs off a candidate, and the candidate's source tells you how that person entered the system. Candidates created by Refari widgets are read and mirrored into the ATS; candidates the partner owns are pushed in with source = "crm".
Update scope depends on source
For source = "crm" candidates you may update all editable fields. For applicant and referral candidates (created inside Refari) you may only change the recruiters array; edits to other fields will not take effect, by design.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /candidates/ | listCandidate | List / find | Query: source, external_id, page | Filter source=referral to isolate digital referrals. |
| POST | /candidates/ | createCandidate | Create a CRM candidate | external_id, email, first_name, last_name | Optional referrer, recruiters, resume_url. |
| GET | /candidates/{id}/ | retrieveCandidate | Detail | Path id (UUID) | Adds source, skills, resume, candidate_ad_url. email may be null. |
| PATCH | /candidates/{id}/ | updateCandidate | Update | Body CandidateUpdate | All fields only when source='crm'; otherwise only recruiters. |
Field notes & gotchas
- referrer on create requires email, first_name and referral_date (last_name optional); this is how a direct referral is recorded.
- resume_url must be a publicly accessible URL to a PDF / DOCX / DOC, max 25MB; private-network URLs are rejected.
- recruiters is an array of recruiter Refari UUIDs used to assign ownership.
- On detail, email is nullable (candidates can be created without one), so handle null defensively when mirroring into the ATS.
Applications
BronzeWhat it is and why it matters
An application links a candidate to a job order and carries the status that drives Refari's referral and testimonial automations. The Applications endpoints are how a partner pushes pipeline activity into Refari, reads back referrer attribution and Refari-derived statuses, and (via import rules) decides what is worth pushing in the first place. candidate and job_order are Refari UUIDs, so both must already exist.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /applications/import-rules/ | getApplicationImportRules | CRM-status triggers | (none) | Cache client-side, ~2h. |
| GET | /applications/ | listApplication | List / find | Query: external_id, candidate_id, created_before/after, page | Returns ApplicationList. |
| POST | /applications/ | createApplication | Create | external_id, candidate, job_order, crm_status | One application per candidate per job order. Optional event_recruiter, resume_url. |
| GET | /applications/{id}/ | retrieveApplication | Detail | Path id (UUID) | Returns referrer, rating, source, statuses, answers, resume. |
| PATCH | /applications/{id}/ | updateApplication | Update | Body ApplicationUpdate | Status change re-triggers automations. |
Field notes & gotchas
- event_recruiter (a recruiter UUID, added 2025-04-28) is available on create and update to attribute the status-change event to a specific recruiter.
- answers is an array of screener answers, each with question_text, answer_data and an optional mapping (see use case 5).
- resume_url ingestion (public PDF / DOCX / DOC, max 25MB) is available on create and update, the same contract as candidates.
- A second application for the same candidate and job order is rejected ("Application for candidate for this job order already exists.").
Placements
BronzeWhat it is and why it matters
A placement records that a referred or submitted candidate was successfully placed, and it is the object behind the Referral CSV report. For customers running referral reward schemes, placements close the loop: they are the confirmed outcome the report is built on. A placement is created against an existing application.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /placements/ | listPlacement | List / find | Query: external_id, page | Returns PlacementList. |
| POST | /placements/ | createPlacement | Create | external_id, application | Application must exist. Plus start_date, external_approved. Feeds the Referral CSV report. |
| GET | /placements/{id}/ | retrievePlacement | Detail | Path id (UUID) | Returns the PlacementList shape. |
| PATCH | /placements/{id}/ | updatePlacement | Update | Body start_date, external_approved | Only the two date fields are updatable. |
Field notes & gotchas
- application is the application's Refari UUID, so the application must exist first. A duplicate external_id is rejected ("Placement already exists.").
- start_date is a date; external_approved is a date-time (the approval date in the ATS). Keep both accurate for reward reconciliation.
Going beyond a surface integration
The capabilities that lift an integration from Silver to Platinum: mapped data capture, a real two-way event stream, and Refari functionality embedded inside your ATS.
5Screener questions
SilverWhat it is and why it matters
Screener questions let customers capture structured, decision-ready information at the point of application rather than parsing it from free text later. Questions can be authored in either system: an ATS partner can push its existing question library to Refari, or the client can build questions in the Refari dashboard. Both converge on the same Refari Question objects.
What lifts this into the Silver tier is the data-mapping capability. Each question can be mapped, via the dashboard, back to a specific ATS field (for example user.notification_period). When a candidate answers, the captured value is returned on the application alongside that mapping hint, so the integration knows exactly where to write the answer in the ATS. Questions are reusable building blocks, attached to one or more Job Ads through the advert's questions array, and in a near-future release they will compose into whole data-capture forms.
How the integration works
- Create questions in Refari (addQuestions) or reuse existing ones (listQuestions). Each has an answer_type of text, list or file.
- Attach question UUIDs to a Job Ad via the advert's questions array on create or update.
- Optionally configure, in the dashboard, a mapping from each question to a target ATS field.
- On retrieveApplication, captured responses appear in the answers array, each with question_text, answer_data and the optional mapping. Where mapping is set, write answer_data to the named field.
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /questions/ | listQuestions | List / search the library | Query: page, external_id, search | Use external_id to reconcile against ATS question IDs. |
| POST | /questions/ | addQuestions | Create a question | answer_type | 400 if answer_type=list but answer_values is missing. |
| PATCH | /questions/{id}/ | partialUpdateQuestion | Partial update | Path question id | Send only the fields you intend to change. |
Questions are consumed by createJobAd / partialUpdateJobAd (the questions UUID array) and surfaced back through retrieveApplication (the answers array).
Field notes & gotchas
- answer_type is exactly text / list / file. answer_values is mandatory when answer_type=list.
- is_required and multi_select both default to false; multi_select is only meaningful for list questions. max_length applies to text answers.
- In the application answers array, answer_data is always an array of strings: one element for text, several for a multi-select list, a file URL for file questions.
- mapping is set in the dashboard, not via the API. It is null for unmapped questions and a dotted field reference (for example user.notification_period) for mapped ones.
6Website events & webhooks
GoldWhat it is and why it matters
Webhooks turn a one-directional feed (adverts out, applications back) into a genuine two-way conversation. Instead of polling Refari for changes, the partner registers an endpoint and Refari pushes an HTTP request the moment something happens, so the two systems stay in step in near real time.
The breadth of events is what makes this a Gold-tier capability. Beyond applications and candidate changes, webhooks expose what candidates and referrers actually do on the careers site and across Refari's tools: job alerts, AI suggestions, referrals, testimonial requests and responses, feedback, saved jobs, talent alerts and social shares. Recruiters can use these signals to add timely notes to candidate records, trigger nurture workflows, or surface engagement directly in the ATS.
How the integration works
- Register with createWebhook, specifying the events and the url. Optionally include an authorization header value Refari will send with every notification.
- Refari POSTs to your URL on each subscribed event. The body is { id, event, created, data }.
- Verify authenticity via the X-Refari-Signature header: it holds the BLAKE2 signature of the entire raw request body keyed with your apiKey. Verify against the raw bytes before parsing.
- Respond 2xx. Any non-200 or timeout is retried up to 10 times; more than 10 consecutive errors suspends the webhook (status becomes suspended). Re-enable by patching status back to active.
Available events
application_created · candidate_created · candidate_updated · candidate_ad_created · job_alert_created · job_alert_deleted · suggestion_created · referral_created · testimonial_request_sent · testimonial_created · testimonial_revised · feedback_created · saved_job_created · saved_job_deleted · job_order_job_url_updated · talent_alert_created · talent_alert_deleted · talent_alert_suggestion_created · socialise_created
Notification body
Every notification shares the same envelope. Most events send an empty data object and act as a trigger to fetch full state; socialise_created and referral_created carry rich inline payloads.
{ "id": "ee4950cc-e62c-4b73-93ab-cc95c8aaf45c", "event": "application_created", "created": "2021-06-04T08:05:23.342140Z", "data": {} }
referral_created data (candidate block extended 2026-02-25 with job_title, company_name, linkedin_profile_url, phone, resume, resume_name):
{ "candidate": { "id": "a1b2c3d4-...", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "job_title": "Software Engineer", "company_name": "Acme Corp", "linkedin_profile_url": "https://linkedin.com/in/johndoe", "phone": "+61400000000", "resume": "https://api.refari.co/media/resumes/resume.pdf", "resume_name": "resume.pdf" }, "referrer": { "first_name": "Jane", "last_name": "Smith", "email": "jane.smith@example.com" }, "message": "I recommend this candidate.", "job": { "id": "f1e2d3c4-...", "title": "Senior Developer" }, "source": "agency", "ownership_expiration": "2026-03-25T12:00:00Z" }
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /webhooks/ | listWebhook | List webhooks | Query: page | Returns WebhookList (events, url, status, authorization). |
| POST | /webhooks/ | createWebhook | Register a webhook | events, url | Optional authorization; status defaults active. Up to 3 webhooks per event. |
| GET | /webhooks/{id}/ | retrieveWebhook | Retrieve one | Path id (UUID) | Check current status (active / suspended / disabled). |
| PATCH | /webhooks/{id}/ | updateWebhook | Update | Body status, authorization | Patch status to active to re-enable a suspended webhook. |
| DELETE | /webhooks/{id}/ | deleteWebhook | Delete | Path id (UUID) | Returns 204 No Content. |
Field notes & gotchas
- Verify the BLAKE2 signature against the raw request body before any JSON parse or reserialisation, which can change the bytes and break the comparison.
- Most events deliver an empty data object; treat the webhook as a trigger and fetch full state from the relevant detail endpoint. Only socialise_created and referral_created carry rich payloads.
- The optional authorization value is sent on outbound notifications so your endpoint can authenticate the caller; it complements, and is independent of, the signature.
- Make your endpoint idempotent: under retries the same event (identified by its id) may arrive more than once.
8Partner Actions
PlatinumWhat it is and why it matters
Partner Actions embed Refari's most powerful capabilities directly inside the partner's ATS. Rather than asking a recruiter to leave their system of record, a Partner Action is a configured deep-link that drops them straight into the right Refari screen for a specific object, with the context already loaded: socialising an advert, generating a trackable job link, opening the job in the widget, making post-production edits, viewing all adverts for a job order, creating a job alert, creating a candidate ad, or creating a referral.
This is the Platinum tier because it is the deepest form of integration: Refari functionality appears to live inside the partner platform, the recruiter experiences a single joined-up workflow, and these features are often strong enough to help win business in sales presentations.
How the integration works
- Create a Partner Action with createPartnerAction, supplying the obj_type and the external_id of the target object. The response returns the Refari id, which becomes the action_id in the deep-link.
- Configure a matching action in your ATS whose URL follows the structure for that obj_type.
- When a user triggers the action, your ATS builds the URL with the live action_id and external_id (plus candidate fields where required) and opens it; Refari resolves the object and renders the screen.
Common parameters: action_id is always required. external_id is required for Job Ad and Job Order actions and optional for Candidate actions (if provided and the candidate exists, the existing record is used).
Object types & target URLs
Job Ad actions · object must already exist in Refari · base https://app.refari.co/dashboard/job-ads/?action_id={action_id}&external_id={external_id}
| obj_type | Action |
|---|---|
| job_ad_socialize | Open the "Socialise" modal for an advert |
| job_ad_job_link | Create a job link for an advert |
| job_ad_widget_detail | Open an advert in the job board widget |
| job_ad_edit | Edit an advert (website-specific, post-production) |
Job Order actions · object must already exist · base https://app.refari.co/dashboard/jobs/?action_id={action_id}&external_id={external_id}
| obj_type | Action |
|---|---|
| job_order_job_ad_list | Open the list of all adverts for a Job Order |
Candidate actions · require first_name, last_name, email; external_id optional · query ?action_id=&first_name=&last_name=&email=&external_id=
| obj_type | Action | Base URL |
|---|---|---|
| candidate_job_alert | Create a Job Alert for a candidate | /tools/create-job-alert/ |
| candidate_ad_create | Create a Candidate Ad | /dashboard/candidate-ads/ |
| candidate_referral | Create a Referral for a candidate | /dashboard/candidates-info/ |
Endpoints
| Method | Path | Operation | Purpose | Key / required fields | Notes & dependencies |
|---|---|---|---|---|---|
| GET | /partner-actions/ | listPartnerActions | List actions | Query: page | Returns PartnerAction (id, obj_type, external_id). |
| POST | /partner-actions/ | createPartnerAction | Create an action | obj_type, external_id | Returns the read-only id used as action_id. |
| DELETE | /partner-actions/{id}/ | deletePartnerAction | Delete an action | Path id (UUID) | Returns 204. No update verb: delete and recreate to change. |
Field notes & gotchas
- Candidate fields (first_name, last_name, email) were added 2025-12-08 so you can create candidate ads even for candidates not yet synced to Refari.
- Job Ad and Job Order objects must already exist in Refari for the deep-link to resolve, so sync the object before exposing the action.
- The three URL families use three distinct base URLs; use the one that matches the action's obj_type.
- candidate_job_alert also supports a direct URL without a Partner Action: https://app.refari.co/tools/create-job-alert/?email={candidate_email}.
Release notes
A snapshot of recent and upcoming API changes. The interactive reference at api.refari.co always carries the live version.
- 2025-12-01UpcomingFields first_name, last_name and company will be required when creating a Job Contact.
- 2026-02-25ChangedWebhook referral_created extended with candidate job_title, company_name, linkedin_profile_url, phone, resume and resume_name.
- 2025-12-08ChangedPartner Actions for candidates now support first_name, last_name and email, so you can create candidate ads for candidates not yet synced to Refari.
- 2025-11-25AddedNew fields is_created and is_edited on Work Type, Category and Location.
- 2025-04-28AddedNew field event_recruiter on Create / Update Application.
- 2025-01-25ChangedExtended list of accepted currencies on Job Ads.
- 2024-11-26AddedNew webhook socialise_created.