Skip to content

REST API

Complete reference for the Chronos developer-facing API.

ConventionValue
Base URLhttps://api.chronos.sh
AuthenticationAuthorization: Bearer chrns_your_api_key
Content typeapplication/json
Field casingsnake_case
IDsUUID v4
TimestampsISO 8601
Paginationpage + size query params (defaults: page 1, size 20, max size 100)

All responses use a consistent envelope:

{
"success": true,
"message": "Human-readable message",
"data": { ... }
}

Paginated responses add:

{
"meta": {
"paging": { "page": 1, "pages": 5, "size": 20, "total": 100 }
}
}

Error responses:

{
"success": false,
"message": "What went wrong",
"code": "error_code",
"errors": [{ "field": "name", "message": "is required" }]
}

100 requests per 10 seconds per API key. Exceeding returns 429 with code rate_limit_exceeded.


POST /v1/schedules

Creates a recurring schedule. Exactly one of cron or interval is required.

Request body:

FieldTypeRequiredDefaultDescription
namestringYesDisplay name. Max 255 chars.
descriptionstringNonullMax 1000 chars.
handlerstringRequired for pull deliveryRouting key. Max 255 chars.
cronstringXOR with intervalCron expression.
intervalobjectXOR with cron{ value: int, unit: string }
interval.valueintegerYes (if interval)Positive integer.
interval.unitstringYes (if interval)second, minute, hour, day, week
timezonestringNoAccount timezoneIANA timezone (e.g., America/New_York).
runsintegerNonull (unlimited)Max jobs to create before completing.
stop_atstringNonullISO 8601 date. Must be in the future.
deliveryobjectNo{ type: "pull" }Delivery configuration.
delivery.typestringYes (if delivery)pull or push
delivery.httpobjectRequired if pushHTTP delivery config.
delivery.http.urlstringYesHTTPS URL. No private/localhost IPs.
delivery.http.methodstringYesGET, POST, PUT, PATCH, DELETE
delivery.http.headersobjectNoCustom headers (Record<string, string>).
payloadobjectNonullJob payload. Max 64KB serialized. Must be non-empty if provided.
timeoutintegerNo30Seconds. Positive integer.
max_retriesintegerNo3Min 0.

Response: 201 Created

{
"success": true,
"message": "Schedule created",
"data": {
"id": "uuid",
"account_id": "uuid",
"name": "string",
"description": "string | null",
"handler": "string | null",
"cron": "string | null",
"interval": "{ value, unit } | null",
"timezone": "string",
"runs": "number | null",
"run_count": 0,
"stop_at": "ISO 8601 | null",
"delivery": { "type": "pull | push", "http": "{ url, method, headers? } | undefined" },
"payload": "object | null",
"timeout": 30,
"max_retries": 3,
"status": "active",
"next_run_at": "ISO 8601 | null",
"last_run_at": "ISO 8601 | null",
"created_at": "ISO 8601",
"updated_at": "ISO 8601"
}
}

Errors:

  • validation_error (422): invalid or missing fields
  • rate_limit_exceeded (429)

GET /v1/schedules

Query params:

ParamTypeDefaultDescription
pageinteger1Page number.
sizeinteger20Items per page. Max 100.
statusstringFilter: active, paused, completed, archived

Returns all schedules including archived unless filtered by status.

Response: 200 OK. paginated array of schedule objects.


GET /v1/schedules/:id

Response: 200 OK. single schedule object.

Errors:

  • schedule_not_found (404)

PATCH /v1/schedules/:id

All fields optional. At least one field required.

FieldTypeDescription
namestringMax 255 chars.
descriptionstring | nullnull clears. Max 1000 chars.
handlerstringMax 255 chars.
cronstringCannot combine with interval in same request.
intervalobjectCannot combine with cron in same request.
timezonestringIANA timezone.
runsinteger | nullnull removes run limit.
stop_atstring | nullnull removes stop time.
deliveryobjectSame shape as create.
payloadobject | nullnull clears. Max 64KB.
timeoutintegerPositive.
max_retriesintegerMin 0.

If cron or interval changes, next_run_at is recomputed. If timezone changes, next_run_at is recomputed for cron schedules.

Response: 200 OK. updated schedule object.

Errors:

  • schedule_not_found (404)
  • schedule_archived (409): cannot update archived schedules
  • schedule_completed (409): cannot update completed schedules
  • handler_required_for_pull (400): pull delivery requires a handler
  • schedule_status_changed (409): optimistic concurrency conflict
  • validation_error (422)

POST /v1/schedules/:id/archive

No request body. Cancels all pending/queued/ready/retrying jobs for this schedule.

Response: 200 OK. schedule object with status: "archived".

Errors:

  • schedule_not_found (404)

DELETE /v1/schedules/:id

Permanently deletes the schedule. Associated jobs have their schedule_id set to null.

Response: 204 No Content

Errors:

  • schedule_not_found (404)

POST /v1/jobs

Creates a one-off job. Runs immediately unless delay or scheduled_for is set.

Request body:

FieldTypeRequiredDefaultDescription
namestringYesDisplay name. Max 255 chars.
handlerstringRequired for pullRouting key. Max 255 chars.
delayobjectNoRelative timing. XOR with scheduled_for.
delay.valueintegerYes (if delay)Positive integer.
delay.unitstringYes (if delay)second, minute, hour, day, week
scheduled_forstringNoAbsolute ISO 8601 time. Must be in the future. XOR with delay.
deliveryobjectNo{ type: "pull" }Same shape as schedules.
payloadobjectNonullMax 64KB. Must be non-empty if provided.
timeoutintegerNo30Seconds. Positive integer.
max_retriesintegerNo3Min 0.
idempotency_keystringNonullDedup key. Max 255 chars. Scoped to your account.

Timing options:

  • Neither delay nor scheduled_for → runs immediately
  • delay → runs after the specified duration
  • scheduled_for → runs at the specified time

Response: 201 Created

{
"success": true,
"message": "Job created",
"data": {
"id": "uuid",
"account_id": "uuid",
"schedule_id": null,
"name": "string",
"handler": "string | null",
"idempotency_key": "string | null",
"scheduled_for": "ISO 8601",
"run_at": "ISO 8601",
"delivery": { "type": "pull | push", "http": "..." },
"payload": "object | null",
"timeout": 30,
"max_retries": 3,
"attempt_count": 0,
"status": "pending",
"last_error": "string | null",
"started_at": "ISO 8601 | null",
"completed_at": "ISO 8601 | null",
"created_at": "ISO 8601",
"updated_at": "ISO 8601"
}
}

Errors:

  • idempotency_key_conflict (409): duplicate key on same account
  • validation_error (422)

GET /v1/jobs

Query params:

ParamTypeDefaultDescription
pageinteger1Page number.
sizeinteger20Max 100.
schedule_idstringUUID, or literal "null" for one-off jobs.
handlerstringFilter by handler name.
statusstringpending, admitting, queued, ready, running, retrying, completed, failed, cancelled, skipped
scheduled_beforestringISO 8601 upper bound.
scheduled_afterstringISO 8601 lower bound. Must be ≤ scheduled_before.

Response: 200 OK. paginated array of job objects.


GET /v1/jobs/:id

Response: 200 OK. single job object.

Errors:

  • job_not_found (404)

GET /v1/executions

Query params:

ParamTypeDefaultDescription
pageinteger1Page number.
sizeinteger20Max 100.
job_idstringUUID.
schedule_idstringUUID, or "null" for one-off job executions.
handlerstringFilter by handler name.
statusstringpending, running, completed, failed, timeout
created_beforestringISO 8601 upper bound.
created_afterstringISO 8601 lower bound. Must be ≤ created_before.

Response: 200 OK

{
"success": true,
"message": "Executions fetched",
"data": [{
"id": "uuid",
"account_id": "uuid",
"job_id": "uuid",
"status": "pending | running | completed | failed | timeout",
"trigger": "system | system_retry | manual",
"started_at": "ISO 8601 | null",
"completed_at": "ISO 8601 | null",
"duration_ms": "number | null",
"result": "object | null",
"error": "string | null",
"response_code": "number | null",
"created_at": "ISO 8601"
}],
"meta": { "paging": { ... } }
}

GET /v1/executions/:id

Response: 200 OK. single execution object.

Errors:

  • execution_not_found (404)

These endpoints are used by the SDK internally. You can also call them directly if building a custom worker.

POST /v1/worker/jobs/claim

Claims the next available job for your registered handlers.

Request body:

FieldTypeRequiredDefaultDescription
wait_time_secondsintegerNo0Long-poll duration. 0–20.
handlersstring[]NoFilter by handler names. Min 1 item if provided.

When wait_time_seconds > 0, the request holds open until a job is available or the timeout expires. The SDK uses 20 seconds by default.

Response (job claimed): 200 OK

{
"success": true,
"message": "Job claimed",
"data": {
"job_id": "uuid",
"execution_id": "uuid",
"handler": "string",
"scheduled_for": "ISO 8601",
"attempt": 1,
"timeout": 30,
"payload": "object | null",
"schedule": "{ id: uuid, name: string } | null"
}
}

Response (no job available): 200 OK

{
"success": true,
"message": "No job available",
"data": null
}

POST /v1/worker/executions/:id/result

Reports the outcome of a claimed job’s execution.

Request body:

FieldTypeRequiredDescription
statusstringYescompleted or failed
resultobjectNoExecution result data. Allowed only when completed; forbidden when failed.
errorstringRequired when failedError message. Max 4096 chars.

Business rules:

  • Same-status re-report is idempotent (returns 200, no-op)
  • On failed with retries remaining: job transitions to retrying, new execution scheduled with exponential backoff
  • On failed with retries exhausted: job transitions to failed

Response: 200 OK

{
"success": true,
"message": "Result recorded",
"data": null
}

Errors:

  • execution_not_found (404)
  • execution_not_running (409): execution is not in running status

Signing key and API key management are session-authenticated dashboard operations. API-key clients cannot read, create, rotate, or revoke keys through these endpoints.

See the Signature Verification guide for using your signing secret.