# Scheduled HTTP calls

A job calls your HTTP handler on a Black Hole server at scheduled times. If the feature is unavailable to your Bitrix24 account, you cannot create, enable or run a job. Jobs are configured through the API and MCP. This is separate from [wake windows](./wake-schedules.md).

## Capabilities via Vibecode API

A key with `vibe:infra` can read jobs and history. Changes require the existing server management permissions: its managing key or a permitted development team role. The job belongs to the server, not the key that created it. Rebinding the server's managing key transfers job control without recreating jobs. The MCP tool `manage_server_jobs` takes `serverId`, `jobId` for actions on a single job, `body` for create and update, and `cursor` and `limit` for run history. It makes the same API calls with the same refusals. Some of the tool's actions modify data, call the handler or rotate the secret.

## Schedule and limits

At most 20 non-deleted jobs per server. Disabled jobs count too. The `cronExpr` expression has five fields; `timezone` is a supported IANA time zone. The minimum interval is set by the platform, 5 minutes by default. `path` is a relative path with an optional query string, up to 512 characters: `/tasks/digest?mode=daily`. Absolute URLs, paths starting with `//`, traversal `..`, control characters and an unencoded `#` are forbidden. Only the path of the handler that receives the `POST` request is configurable: the host, HTTP method, headers and request body cannot be set.

Creation, a change to `cronExpr` or `timezone`, and re-enabling start the schedule strictly in the future. Changing only `label` or `path` does not shift the next occurrence. A run snapshots its path and account, so a later `PATCH` does not redirect it. After downtime, at most one latest occurrence is recovered, rather than the entire missed backlog. If the feature or schedule entitlement was temporarily unavailable, recovery may also produce one latest run, including one from that period.

## Wake and delivery

Jobs are also allowed on a server in effective `ALWAYS` mode: it needs no additional wake window. In `IDLE` and `SCHEDULE` modes the platform prepares the server in time for the call. A galaxy host is unsupported; a galaxy app requires separate entitlement. Current account access, payment, server binding, wake restrictions and schedule availability are checked before waking and sending. A job does not bypass restrictions and does not require an external application API key.

Each run, including a manual run on a disabled job, waits for readiness for at most 30 minutes from creation. Waiting does not consume attempts. One run per job is active at a time. An already sent run in `RUNNING` status finishes its attempt even after the job is disabled or deleted. A newer scheduled occurrence supersedes only an older `SCHEDULE` run in `PENDING` status that has had no attempts yet. `MANUAL` runs and already started runs are not superseded.

Up to four delivery attempts share one `runId`. The app must verify [signatures and durable deduplication](./jobs/signature.md). An HTTP 2xx response means acceptance, not completion of background work. A run in `PENDING` status lives for at most 96 hours. Background work in the app is protected only by the server's ordinary idle timer, not until it completes. Do not rely on exactly-once execution of a business operation.

## Observe and stop

[History](./jobs/runs.md) retains completed runs according to the platform setting: 90 days by default, at least 7 days. Runs in `PENDING` and `RUNNING` status are not removed by age. The secret is shown only on creation and rotation: store it on the receiving handler side. List and history do not return it.

When the feature or entitlement is unavailable, an authorized owner can read jobs and history, delete a job, or replace its settings as a whole if the replacement only disables the job and changes nothing else. A regular `PATCH` with other changes requires entitlement. There are no separate notifications for runs in `FAILED` status; access or payment refusals use the existing daily notification. After deletion, the job disappears from the list and its history at the job's address returns `404`. Save records you need beforehand.

## Operations

- [List jobs](./jobs/list.md) — `GET /v1/infra/servers/:id/jobs`
- [Create a job](./jobs/create.md) — `POST /v1/infra/servers/:id/jobs`
- [Replace job settings](./jobs/update.md) — `PATCH /v1/infra/servers/:id/jobs/:jobId`
- [Delete a job](./jobs/delete.md) — `DELETE /v1/infra/servers/:id/jobs/:jobId`
- [Run manually](./jobs/run.md) — `POST /v1/infra/servers/:id/jobs/:jobId/run`
- [Run history](./jobs/runs.md) — `GET /v1/infra/servers/:id/jobs/:jobId/runs`
- [Rotate the secret](./jobs/rotate-secret.md) — `POST /v1/infra/servers/:id/jobs/:jobId/rotate-secret`
- [Daily digest](./jobs/daily-digest.md)
- [Verify signatures](./jobs/signature.md)

## See also

- [Infrastructure](/docs/infra)
- [Servers](/docs/infra/servers)
- [Lifecycle](/docs/infra/lifecycle)
- [Scheduled wake](/docs/infra/wake-schedules)
