Candidates
Candidates, with their attachments, values and sharing settings
The candidate object
Attributes
iduuidUnique identifier
member_iduuid | nullIdentifier of the member responsible for the candidate, initially its creator
created_atread-onlytimestamp with time zoneCreation timestamp
updated_atread-onlytimestamp with time zoneLast modification timestamp
deleted_attimestamp with time zone | nullDeletion timestamp
attachmentsRecord<string, CandidateAttachment>Files attached to the candidate, such as CVs and vacancies
avatartext | nullAvatar image of the candidate. Filled automatically when the candidate is edited in the app
export_filenametextFilename of exported PDF files (without .pdf). When empty, the layout's export_filename applies
external_dataCandidateExternalData | nullData imported from an external source, such as an ATS
ftsread-onlytsvectorFull text search index
languageLanguageLanguage in which the candidate is displayed
messagesArray<CandidateMessage>Messages exchanged with the AI about the candidate
nametextName of the candidate, used for search. Filled automatically when the candidate is edited in the app
secretread-onlytextSecret string. Used to share the candidate's proposal privately, with personal information
secret_anonymousread-onlytextSecret string. Used to share the candidate's proposal privately, with personal information redacted
secret_editableread-onlytextSecret string. Used to share the candidate for editing
section_attachmentsRecord<string, Array<SectionAttachment>>Attachments shown in each attachment section, by section
statusread-onlyCandidateStatusStatus of the candidate. Only active candidates can be shared
valuesJsonObjectValues of the variables defined in the candidate's layout
Related resources
Embed related resources in the response with the select parameter, for example select=*,layouts(*). See selecting data. Resources related through more than one column need the column as a hint, like table!column(*).
organizations!organization_id(*)object | nullThe organization referenced by organization_id.
candidate_analytics(*)arrayThe candidate analytics referencing this candidate through candidate_analytics.candidate_id.
candidate_views(*)arrayThe candidate views referencing this candidate through candidate_views.candidate_id.
{
"id": "00000000-0000-0000-0000-000000000000",
"layout_id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"organization_id": "00000000-0000-0000-0000-000000000000",
"created_at": "2026-01-01T12:00:00+00:00",
"updated_at": "2026-01-01T12:00:00+00:00",
"deleted_at": null,
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": {
"default": "Text from the attachment"
},
"type": "pdf",
"url": "https://ddcaybdkekwxbpgpotoa.supabase.co/storage/v1/object/public/common/organizations/00000000-0000-0000-0000-000000000000/document.pdf"
}
},
"avatar": "",
"export_filename": "",
"external_data": {
"avatar": "https://example.com/candidates/123/avatar.jpg",
"name": "John Doe",
"id": "123",
"url": "https://integration.com/candidates/123",
"values": {
"first_name": "John",
"last_name": "Doe"
}
},
"fts": "'doe':2 'john':1",
"language": "en",
"messages": [
{
"comment": "Filled in values",
"created_at": "2026-11-13T03:35:51.285Z",
"id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"prompt": "Fill in values",
"selector": []
}
],
"name": "",
"secret": "",
"secret_anonymous": "",
"secret_editable": "",
"section_attachments": {},
"status": "active",
"values": {
"name": "John Doe",
"date_of_birth": "1995-01-01",
"experiences": [
{
"interval": {
"start": "2015-01-01",
"end": "2018-01-01"
},
"company": "Example Inc.",
"position": "Developer"
}
]
}
}curl "https://api.cv-transformer.com/v1/candidates?limit=10&select=*,layouts(*),members(*)" \
-H "Authorization: Bearer YOUR_API_KEY"List candidates
Requirescandidates:read
Filters
idFilter<uuid>Unique identifier
member_idFilter<uuid | null>Identifier of the member responsible for the candidate, initially its creator
created_atFilter<timestamp with time zone>Creation timestamp
updated_atFilter<timestamp with time zone>Last modification timestamp
deleted_atFilter<timestamp with time zone | null>Deletion timestamp
attachmentsFilter<Record<string, CandidateAttachment>>Files attached to the candidate, such as CVs and vacancies
avatarFilter<text | null>Avatar image of the candidate. Filled automatically when the candidate is edited in the app
export_filenameFilter<text>Filename of exported PDF files (without .pdf). When empty, the layout's export_filename applies
external_dataFilter<CandidateExternalData | null>Data imported from an external source, such as an ATS
ftsFilter<tsvector>Full text search index
languageFilter<Language>Language in which the candidate is displayed
messagesFilter<Array<CandidateMessage>>Messages exchanged with the AI about the candidate
nameFilter<text>Name of the candidate, used for search. Filled automatically when the candidate is edited in the app
secretFilter<text>Secret string. Used to share the candidate's proposal privately, with personal information
secret_anonymousFilter<text>Secret string. Used to share the candidate's proposal privately, with personal information redacted
secret_editableFilter<text>Secret string. Used to share the candidate for editing
section_attachmentsFilter<Record<string, Array<SectionAttachment>>>Attachments shown in each attachment section, by section
statusFilter<CandidateStatus>Status of the candidate. Only active candidates can be shared
valuesFilter<JsonObject>Values of the variables defined in the candidate's layout
Responses
200A list of candidates with the selected columns. The Content-Range header holds the range returned and the total count, like 0-9/42.
206Partial Content
400The request is malformed, for example an unknown column or an invalid filter.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl "https://api.cv-transformer.com/v1/candidates?limit=10&select=*" \
-H "Authorization: Bearer YOUR_API_KEY"[
{
"id": "00000000-0000-0000-0000-000000000000",
"layout_id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"organization_id": "00000000-0000-0000-0000-000000000000",
"created_at": "2026-01-01T12:00:00+00:00",
"updated_at": "2026-01-01T12:00:00+00:00",
"deleted_at": null,
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": {
"default": "Text from the attachment"
},
"type": "pdf",
"url": "https://ddcaybdkekwxbpgpotoa.supabase.co/storage/v1/object/public/common/organizations/00000000-0000-0000-0000-000000000000/document.pdf"
}
},
"avatar": "",
"export_filename": "",
"external_data": {
"avatar": "https://example.com/candidates/123/avatar.jpg",
"name": "John Doe",
"id": "123",
"url": "https://integration.com/candidates/123",
"values": {
"first_name": "John",
"last_name": "Doe"
}
},
"fts": "'doe':2 'john':1",
"language": "en",
"messages": [
{
"comment": "Filled in values",
"created_at": "2026-11-13T03:35:51.285Z",
"id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"prompt": "Fill in values",
"selector": []
}
],
"name": "",
"secret": "",
"secret_anonymous": "",
"secret_editable": "",
"section_attachments": {},
"status": "active",
"values": {
"name": "John Doe",
"date_of_birth": "1995-01-01",
"experiences": [
{
"interval": {
"start": "2015-01-01",
"end": "2018-01-01"
},
"company": "Example Inc.",
"position": "Developer"
}
]
}
}
]Delete candidates
Requirescandidates:write
Filters
Without filters, this request deletes all candidates the API key has access to. Always filter on at least one column, like id=eq.{id}.
idFilter<uuid>Unique identifier
member_idFilter<uuid | null>Identifier of the member responsible for the candidate, initially its creator
created_atFilter<timestamp with time zone>Creation timestamp
updated_atFilter<timestamp with time zone>Last modification timestamp
deleted_atFilter<timestamp with time zone | null>Deletion timestamp
attachmentsFilter<Record<string, CandidateAttachment>>Files attached to the candidate, such as CVs and vacancies
avatarFilter<text | null>Avatar image of the candidate. Filled automatically when the candidate is edited in the app
export_filenameFilter<text>Filename of exported PDF files (without .pdf). When empty, the layout's export_filename applies
external_dataFilter<CandidateExternalData | null>Data imported from an external source, such as an ATS
ftsFilter<tsvector>Full text search index
languageFilter<Language>Language in which the candidate is displayed
messagesFilter<Array<CandidateMessage>>Messages exchanged with the AI about the candidate
nameFilter<text>Name of the candidate, used for search. Filled automatically when the candidate is edited in the app
secretFilter<text>Secret string. Used to share the candidate's proposal privately, with personal information
secret_anonymousFilter<text>Secret string. Used to share the candidate's proposal privately, with personal information redacted
secret_editableFilter<text>Secret string. Used to share the candidate for editing
section_attachmentsFilter<Record<string, Array<SectionAttachment>>>Attachments shown in each attachment section, by section
statusFilter<CandidateStatus>Status of the candidate. Only active candidates can be shared
valuesFilter<JsonObject>Values of the variables defined in the candidate's layout
Responses
204Deleted. With the header Prefer: return=representation, the response is a 200 whose body holds the deleted candidates with the selected columns.
400The request is malformed, for example an unknown column or an invalid filter.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs, or no permission for this change, for example when writing rows of another organization.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl -X DELETE "https://api.cv-transformer.com/v1/candidates?id=eq.00000000-0000-0000-0000-000000000000" \
-H "Authorization: Bearer YOUR_API_KEY"(no content)Update candidates
Requirescandidates:write
Filters
Without filters, this request updates all candidates the API key has access to. Always filter on at least one column, like id=eq.{id}.
idFilter<uuid>Unique identifier
member_idFilter<uuid | null>Identifier of the member responsible for the candidate, initially its creator
created_atFilter<timestamp with time zone>Creation timestamp
updated_atFilter<timestamp with time zone>Last modification timestamp
deleted_atFilter<timestamp with time zone | null>Deletion timestamp
attachmentsFilter<Record<string, CandidateAttachment>>Files attached to the candidate, such as CVs and vacancies
avatarFilter<text | null>Avatar image of the candidate. Filled automatically when the candidate is edited in the app
export_filenameFilter<text>Filename of exported PDF files (without .pdf). When empty, the layout's export_filename applies
external_dataFilter<CandidateExternalData | null>Data imported from an external source, such as an ATS
ftsFilter<tsvector>Full text search index
languageFilter<Language>Language in which the candidate is displayed
messagesFilter<Array<CandidateMessage>>Messages exchanged with the AI about the candidate
nameFilter<text>Name of the candidate, used for search. Filled automatically when the candidate is edited in the app
secretFilter<text>Secret string. Used to share the candidate's proposal privately, with personal information
secret_anonymousFilter<text>Secret string. Used to share the candidate's proposal privately, with personal information redacted
secret_editableFilter<text>Secret string. Used to share the candidate for editing
section_attachmentsFilter<Record<string, Array<SectionAttachment>>>Attachments shown in each attachment section, by section
statusFilter<CandidateStatus>Status of the candidate. Only active candidates can be shared
valuesFilter<JsonObject>Values of the variables defined in the candidate's layout
Body
Partial<Candidate>The attributes are listed under the candidate object. Read-only attributes are set by CV-Transformer and can't be written.
Responses
204Updated. With the header Prefer: return=representation, the response is a 200 whose body holds the updated candidates with the selected columns.
400The request is malformed, for example an unknown column, an invalid filter or an invalid body.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs, or no permission for this change, for example when writing rows of another organization.
409The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl -X PATCH "https://api.cv-transformer.com/v1/candidates?id=eq.00000000-0000-0000-0000-000000000000" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": { "default": "Text from the attachment" },
"type": "pdf",
"url": "https://ddcaybdkekwxbpgpotoa.supabase.co/storage/v1/object/public/common/organizations/00000000-0000-0000-0000-000000000000/document.pdf"
}
}
}'(no content)Create candidate
Requirescandidates:write
Create a new candidate. Uses one credit. When no credits are available in the organization, the candidate is created with status="pending" instead. Omitted fields get their default. An invalid field fails the request with a 400 that names it; nothing is created or billed. Files are uploaded with Upload candidate attachment after creating the candidate.
Body
attachmentsRecord<string, { detected_source_language: string | null, external_id: string | number | null, label: string, text: MultiLanguageString, type: "image" | "image-pdf" | "link" | "pdf" | "text", url: string }>Files attached to the candidate, by key
external_data{ avatar: string | null, name: string, id: string | number, url: string, values?: unknown } | nullData imported from an external source
languageLanguage | nullLanguage the candidate is displayed in. Defaults to the layout's first language
layout_idstring | nullIdentifier of a layout of the organization. Defaults to the organization's default layout, also when the layout doesn't exist
member_external_idstring | nullThe ID of the member in an external system, to find the member by when member_id is not set
member_idstring | nullIdentifier of the member of the organization associated with the candidate. No member when it doesn't exist
valuesRecord<string, unknown> | nullValues for the variables defined in the layout
Responses
201The created candidate
400The body is invalid: not JSON, a required field is missing or a field has the wrong type or value. The details name each invalid field and why.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl "https://api.cv-transformer.com/v1/candidates" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": { "default": "" },
"type": "link",
"url": "https://example.com/cv"
}
},
"language": "nl",
"layout_id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"values": { "key": "value" }
}'{
"id": "00000000-0000-0000-0000-000000000000",
"layout_id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"organization_id": "00000000-0000-0000-0000-000000000000",
"created_at": "2026-01-01T12:00:00+00:00",
"updated_at": "2026-01-01T12:00:00+00:00",
"deleted_at": null,
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": {
"default": "Text from the attachment"
},
"type": "pdf",
"url": "https://ddcaybdkekwxbpgpotoa.supabase.co/storage/v1/object/public/common/organizations/00000000-0000-0000-0000-000000000000/document.pdf"
}
},
"avatar": "",
"export_filename": "",
"external_data": {
"avatar": "https://example.com/candidates/123/avatar.jpg",
"name": "John Doe",
"id": "123",
"url": "https://integration.com/candidates/123",
"values": {
"first_name": "John",
"last_name": "Doe"
}
},
"fts": "'doe':2 'john':1",
"language": "en",
"messages": [
{
"comment": "Filled in values",
"created_at": "2026-11-13T03:35:51.285Z",
"id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"prompt": "Fill in values",
"selector": []
}
],
"name": "",
"secret": "",
"secret_anonymous": "",
"secret_editable": "",
"section_attachments": {},
"status": "active",
"values": {
"name": "John Doe",
"date_of_birth": "1995-01-01",
"experiences": [
{
"interval": {
"start": "2015-01-01",
"end": "2018-01-01"
},
"company": "Example Inc.",
"position": "Developer"
}
]
}
}Upload candidate attachment
Requirescandidates:write
Upload an attachment for a candidate. The body is the file, with its type in the Content-Type header. Supported file types: .pdf, .doc, .docx, .jpeg, .png, .txt, .webp.
Route parameters
candidate_idrequireduuidThe identifier of the candidate.
Query parameters
locationstringLabel of the attachment, like CV or Vacancy. Defaults to CV.
Responses
200The updated candidate
400The file type isn't supported.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs.
404The candidate doesn't exist in the API key's organization.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl "https://api.cv-transformer.com/v1/candidates/{candidate_id}/attach?location=CV" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @cv.pdf{
"id": "00000000-0000-0000-0000-000000000000",
"layout_id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"organization_id": "00000000-0000-0000-0000-000000000000",
"created_at": "2026-01-01T12:00:00+00:00",
"updated_at": "2026-01-01T12:00:00+00:00",
"deleted_at": null,
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": {
"default": "Text from the attachment"
},
"type": "pdf",
"url": "https://ddcaybdkekwxbpgpotoa.supabase.co/storage/v1/object/public/common/organizations/00000000-0000-0000-0000-000000000000/document.pdf"
}
},
"avatar": "",
"export_filename": "",
"external_data": {
"avatar": "https://example.com/candidates/123/avatar.jpg",
"name": "John Doe",
"id": "123",
"url": "https://integration.com/candidates/123",
"values": {
"first_name": "John",
"last_name": "Doe"
}
},
"fts": "'doe':2 'john':1",
"language": "en",
"messages": [
{
"comment": "Filled in values",
"created_at": "2026-11-13T03:35:51.285Z",
"id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"prompt": "Fill in values",
"selector": []
}
],
"name": "",
"secret": "",
"secret_anonymous": "",
"secret_editable": "",
"section_attachments": {},
"status": "active",
"values": {
"name": "John Doe",
"date_of_birth": "1995-01-01",
"experiences": [
{
"interval": {
"start": "2015-01-01",
"end": "2018-01-01"
},
"company": "Example Inc.",
"position": "Developer"
}
]
}
}Fill / adjust candidate data
Requirescandidates:write
Fill or adjust a candidate's values.
Route parameters
candidate_idrequireduuidThe identifier of the candidate.
Query parameters
promptstringCustom prompt, e.g. "Expand introduction", "Sort skills by level". Organization's default prompt is used when left empty.
selectorArray<string>JSON selector to which the prompt should be applied, e.g. ["experiences", 0] to apply the prompt to the first experience. Repeat the parameter for each part. If left empty, the prompt is applied to the entire candidate.
Responses
200The updated candidate
400The candidate has no layout.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs.
404The candidate doesn't exist in the API key's organization.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl -X POST "https://api.cv-transformer.com/v1/candidates/{candidate_id}/fill?prompt=&selector=experiences&selector=0" \
-H "Authorization: Bearer YOUR_API_KEY"{
"id": "00000000-0000-0000-0000-000000000000",
"layout_id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"organization_id": "00000000-0000-0000-0000-000000000000",
"created_at": "2026-01-01T12:00:00+00:00",
"updated_at": "2026-01-01T12:00:00+00:00",
"deleted_at": null,
"attachments": {
"CV": {
"detected_source_language": null,
"external_id": null,
"label": "CV",
"text": {
"default": "Text from the attachment"
},
"type": "pdf",
"url": "https://ddcaybdkekwxbpgpotoa.supabase.co/storage/v1/object/public/common/organizations/00000000-0000-0000-0000-000000000000/document.pdf"
}
},
"avatar": "",
"export_filename": "",
"external_data": {
"avatar": "https://example.com/candidates/123/avatar.jpg",
"name": "John Doe",
"id": "123",
"url": "https://integration.com/candidates/123",
"values": {
"first_name": "John",
"last_name": "Doe"
}
},
"fts": "'doe':2 'john':1",
"language": "en",
"messages": [
{
"comment": "Filled in values",
"created_at": "2026-11-13T03:35:51.285Z",
"id": "00000000-0000-0000-0000-000000000000",
"member_id": "00000000-0000-0000-0000-000000000000",
"prompt": "Fill in values",
"selector": []
}
],
"name": "",
"secret": "",
"secret_anonymous": "",
"secret_editable": "",
"section_attachments": {},
"status": "active",
"values": {
"name": "John Doe",
"date_of_birth": "1995-01-01",
"experiences": [
{
"interval": {
"start": "2015-01-01",
"end": "2018-01-01"
},
"company": "Example Inc.",
"position": "Developer"
}
]
}
}Extract candidate data
Requirescandidates:read
Extract custom data from a candidate. The body is the JSON Schema of the data to extract.
Route parameters
candidate_idrequireduuidThe identifier of the candidate.
Responses
200The extracted data, following the JSON schema
400The candidate has no attachments with text.
401The API key is missing or invalid.
403The API key doesn't have the scope this request needs.
404The candidate doesn't exist in the API key's organization.
429The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the Retry-After header.
message, details and hint, and for database errors a code. See errors.curl "https://api.cv-transformer.com/v1/candidates/{candidate_id}/extract" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "object",
"properties": {
"email": { "type": "string" },
"first_name": { "type": "string" },
"last_name": { "type": "string" }
},
"$schema": "http://json-schema.org/draft-07/schema#"
}'{
"email": "john.doe@example.com",
"experiences": [
{
"company": "Example Inc.",
"position": "Developer"
}
],
"name": "John Doe"
}