https://api.certo.bio/v1openapi.json

Create a position

POST/v1/positionsscope hiring:write

A position: the terms an invitation to it starts from (what the candidate shares and must have ready). Owners, admins and recruiters.

As an MCP tool: create_position

Request body

NameTypeRequiredDescription
titlestringYesThe position's title, 1 to 120 characters.
locationstring or nullWhere the work is, at most 120 characters.
descriptionstring or nullWhat the work is, at most 1000 characters.
scope_typesarray of one of employment, education, certification, role, language, right_to_work or nullWhat the candidate is asked to share: record types, or null (or every one) for all of them.
include_contactbooleanInvitations to it ask for the candidate's contact details too.
include_birth_datebooleanInvitations to it ask for the date of birth too (with birth_date_reason).
birth_date_reasonstring or nullWhy the date of birth is needed, 3 to 280 characters; required with include_birth_date. The candidate reads it.
requirementsobject or nullWhat the candidate must have ready, docs/request-requirements.md: {"v": 1, "work_years", "education_min_level", "certifications", "right_to_work", "contact"}; null for the defaults.
ats_job_iduuid or nullThe ATS job (the organisation's, from the ATS integration) that feeds this position, or null.
custom_dataobject or nullYour own data on the position: any JSON object (an id from your ATS or HR system, a requisition number), at most 4096 bytes. certo stores it and answers it back on the reads and in your webhook events; it never reads it, and the candidate never sees it. A change replaces it whole; null clears it.

Response fields

position
object. The position.
position.id
uuid. The position's id.
position.title
string. Its title.
position.location
string or null. Where the work is.
position.status
one of open, closed. open, or closed (kept with its candidates; it only leaves the invite picker).
position.counts
object. How far the position is.
position.counts.invited
integer. Invitations and asks under the position.
position.counts.accepted
integer. Of those, accepted or approved.
position.counts.ready
integer. Candidates under it whose checklist is complete.
position.custom_data
object or null. Your own data on the position, as you sent it; null for none.
position.created_at
string. When it was made, ISO 8601.
scope_types
array of string. What invitations to it ask to share; empty for everything.
include_contact
boolean. Invitations ask for contact details.
include_birth_date
boolean. Invitations ask for the date of birth.
requirements
object or null. What the candidate must have ready; null for the defaults.

Errors

  • 400 position.invalid
  • 400 position.ats_job_invalid
  • 409 position.ats_job_taken
  • 400 invite.birth_date_reason_required
  • 400 request.unknown_field
  • 409 api.idempotency_mismatch
  • 409 api.idempotency_in_progress
  • 400 api.credential_in_url
  • 401 api.key_invalid
  • 401 api.key_expired
  • 401 api.key_revoked
  • 401 api.key_suspended
  • 403 api.scope_missing
  • 429 api.rate_limited