Wipperoz Orbit public API
Version 1.0.0 · OpenAPI 3.1.0
Base URLs
| Environment | URL |
|---|---|
| Production | https://api.wipperoz.com |
The Orbit public API lets an account render its own jobs on its own site. Wipperoz is the production tool; the employer is the origin. Every job carries an applyLink to the Wipperoz-hosted apply page, which records the candidate's consent — the employer owns the page, Wipperoz owns the transaction.
Authentication
Every request carries an account API key, minted in Orbit → Settings → API keys. Send it either as Authorization: Bearer <key> or in the x-api-key header. A revoked key stops working within one request. Keys are account-scoped: every response is the calling account's jobs, and there is no cross-account read or write.
Three scopes, chosen when the key is minted and fixed for its life:
- jobs:read — the two read endpoints. What a careers site needs. - jobs:write — create, edit, publish and close. Publishing puts an advertisement in front of the public, so this is deliberately not implied by jobs:read: a key that renders a careers page should not also be able to post ads. - screening — invite a candidate to an AI screening on a managed ad. Issuing a key with this scope is the account's consent to screening overage: past a managed ad's included screenings, each screening is billed at the template's locked price without a per-call confirmation, up to the account's monthly overage cap.
Writing jobs
Creating and publishing are two calls. POST /v1/jobs makes a draft — nothing public — and POST /v1/jobs/{jobId}/publish takes it live. Publishing is free. An integration that wants the whole loop without a person calls both.
Editing a published ad stages the new words rather than replacing the ones candidates are applying against; the response says pendingRevision: true, and publishEdits: true promotes them in the same call. The closing date and the match cap are exempt and apply immediately — both exist to stop something.
Retries
Send an Idempotency-Key header on POST requests. A retry with the same key returns the first answer (with Idempotent-Replay: true) instead of creating a second advertisement or publishing twice; the key is remembered for 24 hours. The same key with a different body is refused with 409. Without the header, two identical creates make two ads.
Rate limits
120 requests per minute per key. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (epoch seconds); a request over the limit is answered 429 with Retry-After. A careers page that syncs incrementally needs a handful of calls an hour; the limit exists to stop a misconfigured loop.
Pagination
GET /v1/jobs returns up to limit jobs (default 50, maximum 100) and a nextCursor. Pass it back as cursor to fetch the next page; null means there is no more. Cursors are opaque and issued by this API only.
Incremental sync
updatedSince returns jobs edited, published or closed at or after the given moment. Expiry is time-based and writes nothing, so a page that syncs by updatedSince alone must read each job's expiresAt itself — or ask for status=published and treat anything missing as gone.
Errors
Every error is the same shape: {"error": {"code", "message", "requestId"}}. Quote the requestId to support.
Endpoints
Jobs
Reading the calling account's published, closed and expired jobs. Drafts never appear here.
Writing jobs
Creating, editing, publishing and closing the account's advertisements. Needs the `jobs:write` scope.
Screening
Inviting a candidate to an AI screening on a managed ad. Needs the `screening` scope.