> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spitzli.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugin background jobs

> Use Core-owned durable job execution with current authority and retry rules.

The native job service stores execution state, receipts, claims and leases in Core's PostgreSQL database. Plugins execute in separate runtimes and receive scoped host access. They do not receive database or queue credentials. Older BullMQ examples describe the retained TypeScript implementation, not the current native queue.

## Declare a handler

A job must appear in the matching [manifest](https://docs.spitzli.cloud/developers/plugin-manifest.md), request supported capabilities and be included in the installation's approved project grant. Permission to enqueue a job is separate from the handler's own host-service capabilities.

The current host supports immediate jobs using document and named HTTP capabilities. Interval scheduling is rejected; declaring `intervalSeconds` does not start a scheduler. Dependencies, tables and migrations have separate installer restrictions.

## Enqueue and retry

The native enqueue input contains `name`, `payload`, `idempotencyKey` and optional `attempts`:

```json theme={null}
{
  "name": "demo.process",
  "payload": { "message": "hello" },
  "idempotencyKey": "request-42",
  "attempts": 3
}
```

| Input | Limit |
| - | - |
| Payload | 32 KiB |
| Attempts | 1–5; default 3 |
| Idempotency key | 8–128 letters, digits, dots, underscores or hyphens |

Use the matching SDK's private host-service transport for one authenticated invocation. The host derives plugin, customer and project scope; a request body cannot choose another tenant. Keep the same idempotency key for unchanged intent. Changed input with a reused key fails instead of creating another job.

## Execution and cancellation

Core rechecks current identity, stored browser/OAuth authority, installation generation, configuration and grants when claiming and running work. Leases fence stale workers; retries preserve durable state. Cancellation and revocation cannot undo a provider effect already accepted. Handlers must retain operation identities and reconcile uncertain remote writes before attempting another effect.

Installation disablement waits for durable jobs and provider continuations to drain. An unavailable blocker check does not mean there are no blockers.

## Verification boundary

Use owned disposable PostgreSQL and runtime fixtures. The repository command targets the native integration suite:

```sh theme={null}
bun run test:plugin-jobs
```

Read its fixture requirements before running it. A local suite does not prove that a given release is installed or that its runtime supports the required job RPC. Independent images, registry signatures and controller rollout remain separate [release gates](https://docs.spitzli.cloud/developers/plugin-releases.md).

Source: native job service (`crates/plugin-host/src/jobs.rs`), runtime dispatcher (`crates/control-plane/src/plugin_jobs.rs`) and job integration tests (`crates/plugin-host/tests/jobs.rs`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.