Wipperoz
Explorar a documentação

Jobs

Reading the calling account's published, closed and expired jobs. Drafts never appear here.

List the account's jobs

GET /v1/jobs

Published jobs, plus closed and expired ones with their status set, so a careers page can render its own closed state instead of breaking links it already published. Drafts are never returned.

Parameters

NameInTypeDescription
statusquerystringComma-separated statuses to include. Defaults to all three. Example published,closed.
updatedSincequerystringISO 8601 timestamp or epoch milliseconds. Only jobs changed at or after this moment. Example 2026-09-01T00:00:00Z.
limitqueryinteger Default 50.
cursorquerystringThe nextCursor of the previous page.

Responses

200 — One page of jobs. Body: JobList.

Headers: X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset

{
  "jobs": [
    {
      "id": "job_01J8Z3K9Q0EXAMPLE",
      "status": "published",
      "title": "Senior Backend Engineer",
      "description": "Own the services behind our hiring pipeline, from the API surface to the queues that move applications through it.",
      "responsibilities": [
        "Design and ship services on AWS Lambda and DynamoDB",
        "Review and mentor across the backend team"
      ],
      "skills": [
        {
          "name": "TypeScript",
          "level": "required"
        },
        {
          "name": "DynamoDB",
          "level": "nice_to_have"
        }
      ],
      "benefits": [
        "Remote-first",
        "Learning budget"
      ],
      "seniority": "senior",
      "yearsExperience": "5+",
      "employmentType": "full_time",
      "contractType": "permanent",
      "salary": {
        "min": 150000,
        "max": 180000,
        "currency": "AUD",
        "period": "year"
      },
      "location": {
        "country": "AU",
        "state": "NSW",
        "city": "Sydney",
        "remotePolicy": "hybrid",
        "onsiteDays": "2"
      },
      "workStyle": "hybrid",
      "company": {
        "name": "Acme Robotics",
        "logoUrl": "https://content.wipperoz.com/accounts/acme/logo.png"
      },
      "postedAt": "2026-09-01T02:15:00.000Z",
      "updatedAt": "2026-09-03T10:40:00.000Z",
      "expiresAt": "2026-10-01T02:15:00.000Z",
      "url": "https://www.wipperoz.com/en/jobs/acme-robotics/senior-backend-engineer",
      "applyLink": "https://www.wipperoz.com/en/apply/job_01J8Z3K9Q0EXAMPLE?src=careers&account=acc_01J8Z3EXAMPLE"
    }
  ],
  "nextCursor": null
}

400 — A query parameter is malformed. The message says which. Body: Error.

{
  "error": {
    "code": "bad_request",
    "message": "`limit` must be an integer between 1 and 100",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

401 — No API key, or one that is not valid. Body: Error.

{
  "error": {
    "code": "unauthorized",
    "message": "This endpoint requires an API key. Send it as `Authorization: Bearer <key>` or in `x-api-key`.",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

403 — The key is valid but does not carry the scope this route needs. Body: Error.

{
  "error": {
    "code": "forbidden",
    "message": "This key does not carry the `jobs:read` scope. Mint a key with it in Orbit → Settings → API keys.",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

429 — Over the per-key limit. Wait Retry-After seconds. Body: Error.

Headers: Retry-After

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit of 120 requests per minute exceeded. Retry after 37 seconds.",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

Read one job

GET /v1/jobs/{jobId}

One of the calling account's jobs. Another account's job, a draft and an unknown id all answer 404 — a draft has no public existence yet.

Parameters

NameInTypeDescription
jobIdrequiredpathstring Example job_01J8Z3K9Q0EXAMPLE.

Responses

200 — The job.

Headers: X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset

{
  "job": {
    "id": "job_01J8Z3K9Q0EXAMPLE",
    "status": "published",
    "title": "Senior Backend Engineer",
    "description": "Own the services behind our hiring pipeline, from the API surface to the queues that move applications through it.",
    "responsibilities": [
      "Design and ship services on AWS Lambda and DynamoDB",
      "Review and mentor across the backend team"
    ],
    "skills": [
      {
        "name": "TypeScript",
        "level": "required"
      },
      {
        "name": "DynamoDB",
        "level": "nice_to_have"
      }
    ],
    "benefits": [
      "Remote-first",
      "Learning budget"
    ],
    "seniority": "senior",
    "yearsExperience": "5+",
    "employmentType": "full_time",
    "contractType": "permanent",
    "salary": {
      "min": 150000,
      "max": 180000,
      "currency": "AUD",
      "period": "year"
    },
    "location": {
      "country": "AU",
      "state": "NSW",
      "city": "Sydney",
      "remotePolicy": "hybrid",
      "onsiteDays": "2"
    },
    "workStyle": "hybrid",
    "company": {
      "name": "Acme Robotics",
      "logoUrl": "https://content.wipperoz.com/accounts/acme/logo.png"
    },
    "postedAt": "2026-09-01T02:15:00.000Z",
    "updatedAt": "2026-09-03T10:40:00.000Z",
    "expiresAt": "2026-10-01T02:15:00.000Z",
    "url": "https://www.wipperoz.com/en/jobs/acme-robotics/senior-backend-engineer",
    "applyLink": "https://www.wipperoz.com/en/apply/job_01J8Z3K9Q0EXAMPLE?src=careers&account=acc_01J8Z3EXAMPLE"
  }
}

401 — No API key, or one that is not valid. Body: Error.

{
  "error": {
    "code": "unauthorized",
    "message": "This endpoint requires an API key. Send it as `Authorization: Bearer <key>` or in `x-api-key`.",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

403 — The key is valid but does not carry the scope this route needs. Body: Error.

{
  "error": {
    "code": "forbidden",
    "message": "This key does not carry the `jobs:read` scope. Mint a key with it in Orbit → Settings → API keys.",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

404 — No such job on this account. Body: Error.

{
  "error": {
    "code": "not_found",
    "message": "No such job on this account",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

429 — Over the per-key limit. Wait Retry-After seconds. Body: Error.

Headers: Retry-After

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit of 120 requests per minute exceeded. Retry after 37 seconds.",
    "requestId": "5f7a9c1e-2b3d-4e5f-8a9b-0c1d2e3f4a5b"
  }
}

Schemas

Error

FieldTypeDescription
errorrequiredobject

JobList

FieldTypeDescription
jobsrequiredJob[]
nextCursorrequiredstring | nullPass back as cursor for the next page. null when there is no more.

Skill

FieldTypeDescription
namerequiredstring
levelrequiredstringOne of: required, nice_to_have.

Salary

FieldTypeDescription
minnumber
maxnumber
currencystringISO 4217, as entered by the recruiter.
periodstringFree text as entered, typically year, month, day or hour.

Location

FieldTypeDescription
countrystring
statestring
citystring
remotePolicystringOne of: onsite, hybrid, remote.
onsiteDaysstring

Company

FieldTypeDescription
namestring
logoUrlstring (uri)

Job

Enough to build a JobPosting JSON-LD block: title, description, postedAtdatePosted, expiresAtvalidThrough, companyhiringOrganization, locationjobLocation, salarybaseSalary, employmentType.

FieldTypeDescription
idrequiredstring
statusrequiredstringpublished accepts applications. The other two are returned, not omitted, so a careers page can render its own closed state. One of: published, closed, expired.
titlerequiredstring
descriptionrequiredstring
responsibilitiesrequiredstring[]
skillsrequiredSkill[]
benefitsrequiredstring[]
senioritystring
yearsExperiencestring
employmentTypestringOne of: full_time, part_time.
contractTypestringOne of: permanent, part_time, fixed_term, contract, casual.
salarySalary
locationLocation
workStylestring
companyrequiredCompany
postedAtstring (date-time)
updatedAtstring (date-time)The latest of an edit, the publish and the close. What updatedSince compares against.
expiresAtstring (date-time)The role stops accepting applications at this moment. Use as validThrough.
closedAtstring (date-time)
urlstring (uri)The Wipperoz-hosted job page, when the role has one.
applyLinkrequiredstring (uri)The hosted apply page. Link candidates here; it records that they came from your site.

JobWrite

What you may set on a job. Every field is optional on PATCH; title is required on POST. The vocabulary is the one the reads return, so an enum you already map for rendering is the enum you send. What you may **not** set: status, id, slug, url, applyLink, company, postedAt, updatedAt and closedAt are ours — derived, permanent, or a lifecycle transition with its own endpoint. Sending one is a 400, deliberately, rather than being ignored: a field you thought you set and we silently dropped is worse than an error.

FieldTypeDescription
titlestring
descriptionstringRich text HTML, as the Orbit editor produces. Plain text is fine.
responsibilitiesstring[]
skillsSkill[]
benefitsstring[]
senioritystring
yearsExperiencestring
employmentTypestringOne of: full_time, part_time.
contractTypestringOne of: permanent, part_time, fixed_term, contract, casual.
salarySalary
locationLocation
workStylestring
expiresAtstring | null (date-time)When the role stops accepting applications. null clears it — live until closed by hand. Applies immediately, even on a published ad.
maxMatchesinteger | nullStop generating AI matches once this many exist. null removes the cap. Applies immediately, even on a published ad.

AuthoredJob

The job as its own account sees it. Identical to Job, except that status may also be draft — the state a job is created in, which the read endpoints never return. A draft already carries an applyLink. It does not resolve until the role is published; it is there so a careers page can be built against the record before it goes live.

FieldTypeDescription
idrequiredstring
statusrequiredstringOne of: draft, published, closed, expired.
titlerequiredstring
descriptionrequiredstring
responsibilitiesrequiredstring[]
skillsrequiredSkill[]
benefitsrequiredstring[]
senioritystring
yearsExperiencestring
employmentTypestringOne of: full_time, part_time.
contractTypestringOne of: permanent, part_time, fixed_term, contract, casual.
salarySalary
locationLocation
workStylestring
companyrequiredCompany
postedAtstring (date-time)
updatedAtstring (date-time)The latest of an edit, the publish and the close. What updatedSince compares against.
expiresAtstring (date-time)The role stops accepting applications at this moment. Use as validThrough.
closedAtstring (date-time)
urlstring (uri)The Wipperoz-hosted job page, when the role has one.
applyLinkrequiredstring (uri)The hosted apply page. Link candidates here; it records that they came from your site.
Wipperoz Logo

A Wipperoz é uma plataforma de CV virtual interativa com vídeo em primeiro lugar, criada para substituir currículos em PDF tradicionais por perfis dinâmicos e compartilháveis.

© 2026 Wipperoz. Todos os direitos reservados

Desenvolvido por epoqx.ai