Skip to content
Developers

API reference

REST, JSON, bearer tokens. 60 requests a minute per user.

https://app.jugglehire.comGet an API key

Overview

A REST API for reading and moving your jobs and candidates. It was built so an AI agent — Claude, ChatGPT, a script of your own — can work your pipeline with a token that only carries the permissions you grant it.

Quickstart · cURL
curl https://app.jugglehire.com/api/v1/jobs \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

Authentication

The API uses bearer tokens. Create one in the app at Organization → API, give it a name you will recognise later, and tick only the scopes that integration needs. The token is shown once, when you create it. Copy it then, because it cannot be retrieved afterwards.

Tokens expire six months after they are created, and you can revoke one at any time from the same page. Team owners and admins see every token created inside their team, with who created it and when it was last used.

Response · 401 Unauthorized
{ "error": { "code": "unauthenticated", "message": "Unauthenticated.", "details": null } }

Scopes

A token carries only the scopes you tick. Calling an endpoint without its scope returns 403 insufficient_scope and the request never reaches your data. Start read-only and add write scopes when you need them.

ScopeGrants
jobs:readList and read jobs, stages, and pipeline
jobs:writeCreate and update jobs
candidates:readSearch and read applicants, notes, and ratings
candidates:writeMove stages, change status, add notes and ratings
messages:sendSend emails and messages to candidates
scheduling:writeSchedule and cancel interviews

messages:send and scheduling:write can be granted today but have no endpoints yet.

Conventions

  • The base URL is https://app.jugglehire.com. Every path in this reference is relative to it.
  • A single record comes back under data. Lists come back under data with links and meta. Page through with ?page=2. Pages hold 15 records.
  • A token reaches only what its owner can reach in the app: every job on teams they own or administer, and on other teams only the jobs they own or are assigned to. Anything else returns 404, not 403, so the API never confirms that a job you cannot see exists.
  • Every write is recorded on our side with the user, token and IP address that made it.

Errors

Every error uses the same envelope:

Error envelope
{
  "error": {
    "code": "validation_failed",
    "message": "The title field is required.",
    "details": { "title": ["The title field is required."] }
  }
}

details carries field messages when validation fails and is null otherwise.

Status · codeMeans
401 · unauthenticatedMissing, revoked or expired token.
403 · insufficient_scopeThe token lacks the scope this endpoint needs. details.required_scope names it.
403 · forbiddenValid scope, but the account is not allowed to do this — a plan limit, for example.
404 · not_foundNo such record, or one the token cannot reach.
422 · validation_failedThe request did not validate. Field errors are in details.
429 · rate_limitedMore than 60 requests in a minute. Wait for the minute to pass, then retry.
500 · server_errorSomething broke on our side. The message is deliberately generic.

Rate limits

60 requests a minute, counted per user rather than per token, so two tokens that belong to the same person share one budget. Successful responses carry X-RateLimit-Limit and X-RateLimit-Remaining. When the remaining count reaches zero, wait for the minute to pass before sending more.

Response · 429 Too Many Requests
{ "error": { "code": "rate_limited", "message": "Too Many Attempts.", "details": null } }

Idempotency

Every write accepts an optional Idempotency-Key header. Send the same key twice and the second call returns the first call’s stored response instead of acting again. Useful when a network error leaves you unsure whether a job was created.

Request · cURL
curl -X POST https://app.jugglehire.com/api/v1/jobs \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f14e45f-ea6a-4c3b-9f2d-1b7c0a5e6d90" \
  -d '{"title": "Backend Engineer"}'
  • A replayed response carries Idempotent-Replay: true.
  • Keys are scoped to your team and remembered for 24 hours.
  • Only successful responses are stored, so a call that failed can be retried with the same key. Use a fresh UUID per action.

Endpoints

Something missing?

If you need an endpoint that is not here yet, message us and tell us what you are building.