BETA
Skip to content

Jobs ​

Create, manage, and control scheduled cron jobs. Each job defines an HTTP request that Krafter executes on a recurring schedule.

Base URL: https://app.krafter.dev/api/v1

List Jobs ​

Retrieve all cron jobs.

GET /cron/jobs

Required scope: cron:read

A page carries at most 1,000 jobs — which covers every plan with a finite job limit, so most teams get everything in one call. When more remain, the response carries a next_cursor; pass it back as cursor for the following page.

Query Parameters ​

ParameterTypeDefaultDescription
limitinteger1000Jobs per page. Clamped to 1--1000.
cursorstring—The next_cursor from a previous response. Pass it back unchanged.

The response's meta.total is how many jobs the team has in total, not how many this page carries. next_cursor is absent on the last page rather than null, so if (body.next_cursor) is the whole loop condition.

TIP

A cursor belongs to this endpoint. One minted by the cron_list_jobs MCP tool is refused here, and a malformed cursor is answered with 422, not 500.

bash
# Walk every job, whatever the team's plan allows.
cursor=""
while :; do
  page=$(curl -s "https://app.krafter.dev/api/v1/cron/jobs?limit=100&cursor=$cursor" \
    -H "Authorization: Bearer kr_live_abc123def456")
  echo "$page" | jq -r '.data[].name'
  cursor=$(echo "$page" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done

Example Request ​

bash
curl https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
{
  "data": [
    {
      "id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
      "name": "Health Check",
      "schedule_type": "interval",
      "schedule": "every_5m",
      "timezone": "UTC",
      "url": "https://example.com/api/health",
      "method": "GET",
      "headers": {},
      "timeout_ms": 30000,
      "max_retries": 3,
      "enabled": true,
      "failure_notify": false,
      "last_status": "success",
      "last_run_at": "2025-01-15T10:05:00Z",
      "next_run_at": "2025-01-15T10:10:00Z",
      "created_at": "2025-01-15T10:00:00Z",
      "updated_at": "2025-01-15T10:00:00Z"
    },
    {
      "id": "b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
      "name": "Nightly Report",
      "schedule_type": "cron",
      "schedule": "0 0 * * *",
      "timezone": "Europe/Berlin",
      "url": "https://example.com/api/reports/generate",
      "method": "POST",
      "headers": {"X-Api-Key": "secret"},
      "timeout_ms": 60000,
      "max_retries": 3,
      "enabled": true,
      "failure_notify": false,
      "last_status": "success",
      "last_run_at": "2025-01-15T23:00:00Z",
      "next_run_at": "2025-01-16T23:00:00Z",
      "created_at": "2025-01-10T08:00:00Z",
      "updated_at": "2025-01-10T08:00:00Z"
    }
  ]
}

Create Job ​

Create a new cron job.

POST /cron/jobs

Required scope: cron:write

Request Body ​

FieldTypeRequiredDescription
namestringYesDisplay name for the job.
schedule_typestringYes"cron", "interval", or "once".
schedulestringYesCron expression (5-field), interval preset, or ISO-8601 datetime (when schedule_type is "once").
urlstringYesHTTP endpoint to call on each execution.
timezonestringNoIANA timezone identifier. Defaults to "UTC".
methodstringNoHTTP method: "GET", "POST", "PUT", "PATCH", or "DELETE". Defaults to "POST".
headersobjectNoCustom HTTP headers to include with each request.
bodystringNoRequest body sent verbatim with each execution. Useful for POST/PUT/PATCH endpoints.
timeout_msintegerNoRequest timeout in milliseconds. Defaults to 30000. Maximum 300000 (5 minutes).
max_retriesintegerNoRetries after a failed attempt, 0--10. Total attempts are max_retries + 1, with 15s/30s/45s linear backoff. Defaults to 3 (four attempts).
enabledbooleanNoWhether the job is active. Defaults to true.
signing_secretstringNoWhen set, outgoing requests are signed with HMAC-SHA256. The value is encrypted at rest. See the Signing guide for verification.
failure_notifybooleanNoEmail the team owner when the job fails and Krafter stops retrying. Sent once per outage, not per attempt — see Failure Notifications. Defaults to false.

Example Request ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly Report",
    "schedule_type": "cron",
    "schedule": "0 0 * * *",
    "timezone": "Europe/Berlin",
    "url": "https://example.com/api/reports/generate",
    "method": "POST",
    "headers": {"X-Api-Key": "secret"},
    "timeout_ms": 60000,
    "max_retries": 3
  }'

Example Request with Body ​

The body field is sent verbatim with each execution. Combine with headers to control the content type.

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Webhook Pinger",
    "schedule_type": "interval",
    "schedule": "every_5m",
    "url": "https://example.com/api/webhook",
    "method": "POST",
    "headers": {"Content-Type": "application/json"},
    "body": "{\"source\":\"krafter-cron\",\"event\":\"heartbeat\"}"
  }'

Example Response ​

json
// 201 Created
{
  "data": {
    "id": "b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
    "name": "Nightly Report",
    "schedule_type": "cron",
    "schedule": "0 0 * * *",
    "timezone": "Europe/Berlin",
    "url": "https://example.com/api/reports/generate",
    "method": "POST",
    "headers": {"X-Api-Key": "secret"},
    "timeout_ms": 60000,
    "max_retries": 3,
    "enabled": true,
    "failure_notify": false,
    "last_status": null,
    "last_run_at": null,
    "next_run_at": "2025-01-15T23:00:00Z",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T10:00:00Z"
  }
}

Get Job ​

Retrieve details of a specific job.

GET /cron/jobs/:id

Required scope: cron:read

Example Request ​

bash
curl https://app.krafter.dev/api/v1/cron/jobs/b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
{
  "data": {
    "id": "b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
    "name": "Nightly Report",
    "schedule_type": "cron",
    "schedule": "0 0 * * *",
    "timezone": "Europe/Berlin",
    "url": "https://example.com/api/reports/generate",
    "method": "POST",
    "headers": {"X-Api-Key": "secret"},
    "timeout_ms": 60000,
    "max_retries": 3,
    "enabled": true,
    "failure_notify": false,
    "last_status": "success",
    "last_run_at": "2025-01-15T23:00:00Z",
    "next_run_at": "2025-01-16T23:00:00Z",
    "created_at": "2025-01-10T08:00:00Z",
    "updated_at": "2025-01-10T08:00:00Z"
  }
}

Update Job ​

Update an existing job. Only provided fields are changed.

PUT /cron/jobs/:id

Required scope: cron:write

Request Body ​

FieldTypeRequiredDescription
namestringNoDisplay name for the job.
schedule_typestringNo"cron", "interval", or "once".
schedulestringNoCron expression, interval preset, or ISO-8601 datetime.
urlstringNoHTTP endpoint to call.
timezonestringNoIANA timezone identifier.
methodstringNoHTTP method: "GET", "POST", "PUT", "PATCH", or "DELETE".
headersobjectNoCustom HTTP headers.
bodystringNoRequest body sent verbatim with each execution.
timeout_msintegerNoRequest timeout in milliseconds. Maximum 300000 (5 minutes).
max_retriesintegerNoRetries after a failed attempt, 0--10. Total attempts are max_retries + 1, with 15s/30s/45s linear backoff.
enabledbooleanNoWhether the job is active.
signing_secretstringNoWhen set, outgoing requests are signed with HMAC-SHA256. The value is encrypted at rest. See the Signing guide.
failure_notifybooleanNoEmail the team owner when the job fails and Krafter stops retrying. Sent once per outage, not per attempt — see Failure Notifications.

Example Request ​

bash
curl -X PUT https://app.krafter.dev/api/v1/cron/jobs/b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": "0 2 * * *",
    "timeout_ms": 120000
  }'

Example Response ​

json
{
  "data": {
    "id": "b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
    "name": "Nightly Report",
    "schedule_type": "cron",
    "schedule": "0 2 * * *",
    "timezone": "Europe/Berlin",
    "url": "https://example.com/api/reports/generate",
    "method": "POST",
    "headers": {"X-Api-Key": "secret"},
    "timeout_ms": 120000,
    "max_retries": 3,
    "enabled": true,
    "failure_notify": false,
    "last_status": "success",
    "last_run_at": "2025-01-15T23:00:00Z",
    "next_run_at": "2025-01-17T01:00:00Z",
    "created_at": "2025-01-10T08:00:00Z",
    "updated_at": "2025-01-16T09:30:00Z"
  }
}

Delete Job ​

Permanently delete a job and all its execution history.

DELETE /cron/jobs/:id

Required scope: cron:write

Example Request ​

bash
curl -X DELETE https://app.krafter.dev/api/v1/cron/jobs/b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

// 204 No Content

Trigger Job ​

Manually trigger a job immediately, regardless of its schedule. The job must be enabled — triggering a paused job returns 200 but the execution is silently dropped by the worker. To trigger a paused job, resume it first.

POST /cron/jobs/:id/trigger

Required scope: cron:write

WARNING

The trigger endpoint enqueues an execution unconditionally, but the worker checks enabled at run time and skips paused jobs without recording an execution. The HTTP 200 response only confirms the job was enqueued, not that it ran.

Example Request ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/trigger \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
{
  "ok": true
}

TIP

Manual triggers on enabled jobs create a normal execution entry in the job's history. Check the Executions API to see the result.


Pause Job ​

Pause a job by setting enabled to false. Prevents future scheduled runs until resumed.

POST /cron/jobs/:id/pause

Required scope: cron:write

Example Request ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/pause \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
{
  "data": {
    "id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "name": "Health Check",
    "schedule_type": "interval",
    "schedule": "every_5m",
    "timezone": "UTC",
    "url": "https://example.com/api/health",
    "method": "GET",
    "headers": {},
    "timeout_ms": 30000,
    "max_retries": 3,
    "enabled": false,
    "failure_notify": false,
    "last_status": "success",
    "last_run_at": "2025-01-15T10:05:00Z",
    "next_run_at": "2025-01-15T10:10:00Z",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T10:06:00Z"
  }
}

Resume Job ​

Resume a paused job by setting enabled to true. next_run_at is preserved from before the pause — for cron expressions this can mean an immediate first run if the job was paused past its scheduled time. The next scheduler tick (every minute) will fire the job if next_run_at <= now.

POST /cron/jobs/:id/resume

Required scope: cron:write

Example Request ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/resume \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
{
  "data": {
    "id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "name": "Health Check",
    "schedule_type": "interval",
    "schedule": "every_5m",
    "timezone": "UTC",
    "url": "https://example.com/api/health",
    "method": "GET",
    "headers": {},
    "timeout_ms": 30000,
    "max_retries": 3,
    "enabled": true,
    "failure_notify": false,
    "last_status": "success",
    "last_run_at": "2025-01-15T10:05:00Z",
    "next_run_at": "2025-01-15T10:10:00Z",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T10:11:00Z"
  }
}

Built by Krafter Studio