Recipe: sync CV data back to your ATS
Build a two-way flow — pull a CV from your ATS, parse it with RemakeCV, and write the extracted candidate details back onto the record.
To sync RemakeCV with your ATS, pull the candidate's CV from your system and POST it to /cvs/process, then write the extracted candidate name, employer and role back onto the record. This recipe covers the parsing and write-back half; for branded document output on the candidate record, use a native integration or ask our team to build one for your platform.
The shape of the integration
Trigger
A consultant clicks a button on the candidate record, or a webhook fires when a CV is attached. Prefer an explicit trigger over formatting everything automatically — it wastes credits on candidates nobody submits.
Fetch the source CV
Pull the raw file from your ATS.
Resolve the acting user
Map the ATS user to their RemakeCV email. This determines template visibility and credit attribution — see authentication.
Process
POST /cvs/processwith the file,acting_user_emailand optionallytemplate_id.Store the identifier
Persist the returned
idagainst your candidate record.Write the extracted fields back
candidate_name,latest_companyandlatest_roleare the useful output. Write them onto the candidate record, or use them to reconcile against what your ATS already holds.
Worked example
async function formatAndAttach(candidateId) {
const candidate = await ats.getCandidate(candidateId);
const source = await ats.downloadAttachment(candidate.cvAttachmentId);
const form = new FormData();
form.append('file', new Blob([source.buffer]), source.filename);
form.append('acting_user_email', resolveActingUser(candidate.ownerId));
form.append('template_id', String(templateFor(candidate.clientId)));
const response = await fetch(`${BASE}/cvs/process`, {
method: 'POST',
headers: { Authorization: `Bearer ${KEY}` },
body: form,
});
if (!response.ok) {
const { error } = await response.json();
// request_id is what support needs to trace this exact call.
throw new Error(`${error.code} (${error.request_id}): ${error.message}`);
}
const { data: cv } = await response.json();
// The parsed fields are the value here — not the file.
await ats.updateCandidate(candidateId, {
latestEmployer: cv.latest_company,
latestRole: cv.latest_role,
});
// Lets you re-fetch the stored source file later without spending another credit.
await ats.setCustomField(candidateId, 'remakecv_id', cv.id);
// OCR ran, so the extraction is worth a human check.
if (cv.processing_method === 'image') {
await ats.addNote(candidateId, 'CV was OCR-processed — verify extracted details.');
}
return cv;
}Design decisions worth getting right
| Decision | Recommendation |
|---|---|
| Trigger | Explicit consultant action, not automatic on every upload — credits |
| Acting user | Real consultant, never a shared service account |
| Template selection | Derive from the client on the record, so the right variant is used |
| Idempotency | Check for an existing remakecv_id before posting — each call creates a new CV and spends a credit, so store the id and reuse it |
| Failure handling | Surface the request_id to the consultant, do not swallow it |
| Rate limiting | Queue with backoff — see rate limits |
This recipe syncs parsed data, not the branded document. download_url gives you back the source file you uploaded, converted to PDF. If your goal is a branded, template-rendered CV landing on the candidate record, that is what the native integrations do — and our team builds them for any platform. See integrations overview, or use the web app.
Guard against double-processing. A consultant clicking twice, or a webhook firing on retry, will process the same CV twice and spend two credits. Check for an existing remakecv_id before you call the API.
Re-downloading later
Do not store download_url — it expires after an hour. Store id, and when a consultant asks for the file again:
const { data } = await request(`/cvs/${remakecvId}/file`);
// data.url is a signed URL to the source CV as a PDF, valid for data.expires_in seconds (3600).Note the file is the source CV as a PDF, not a formatted document, and the URL lasts an hour.
See GET /cvs/{cvId}/file.
Frequently asked questions
- Should I store the file or the CV id?
- Store the id. It lets you fetch a fresh signed URL for the stored source file at any time without spending another credit, so store it rather than re-posting the same file.
- How do I map ATS users to acting_user_email?
- Match on email address. If your ATS emails differ from RemakeCV logins, keep an explicit mapping table rather than falling back to a service account.
Related articles
Last updated . Still stuck? Email support@remakecv.com or book a call.