---
title: "Provider and dispatch"
description: "What the provider and the dispatch program do, and where the provider can run."
---

> Documentation Index
> Fetch the complete documentation index at: https://cf-orbs-site.mdick85.workers.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Provider and dispatch

The provider and the dispatch program are how Amp's orb jobs reach your Cloudflare account.

## Provider

The provider is the process `amp orb provider`. It takes orb jobs from Amp over an outbound connection, so nothing connects in to it. It needs one Amp provider token (`aop_live_...`).

Run exactly one provider for each token. A second provider on the same token waits and takes no jobs.

One provider serves one orb size, because Amp sends no size in a job. For a second size, make a second provider token and a second install with a different `name`.

### Where the provider runs

Set `providerHost` in `cf-orbs.config.jsonc`.

| | `cloudflare` (default) | `external` |
| --- | --- | --- |
| Where it runs | A small container (`lite`) in your Worker | A machine that you run |
| Where the Amp token lives | Worker secret `AMP_ORB_PROVIDER_TOKEN` | An env file on your host. Never on Cloudflare |
| How dispatch reaches the Worker | `http://control.internal` | `https://<worker>.<subdomain>.workers.dev/v1` with the control token |
| Restart after a failure | Entry loop, a Durable Object alarm every 5 min, and a cron every 5 min | Your service manager, for example systemd |

The Worker runs the provider only while the secret `AMP_ORB_PROVIDER_TOKEN` exists. In external mode, every deploy deletes that secret.

For the external setup, see [Run the provider on your own host](/docs/guides/external-provider/).

## Dispatch

`dispatch.sh` is the program that `amp orb provider` runs once for each job. It passes the job to the cf-orbs control plane, which is the Worker (see [How it works](/docs/concepts/how-it-works/#terms)). It's POSIX `sh` and needs only `curl`, `sed`, `awk`, `date` and `sleep`.

For each job it:

1. Prints `cf-orbs: <op> <orbId>`.
2. Sends the job to the Worker: `POST /v1/orbs/<id>/ops`. Then it prints `started <op> <opId>`, or `attaching to running <op> <opId>` when the same op is already running.
3. Long-polls `GET /v1/ops/<opId>` and prints each progress line from the Worker once.
4. On success, prints `cf-orbs: <op> <orbId> done in <n> s` and exits 0. On failure, prints `Failed: <cause> — fix: <command>` and exits 1.

When a request to the Worker fails and is retried, it also prints `control plane: <cause>, retry <n> of 2`.

Exit codes: 0 is success, 1 is a failure, 2 is bad input.

The default deadline is 270 s. Amp's job limit is 300 s. A deadline failure reads `Failed: control plane did not finish <op> within 270 s — fix: cf-orbs logs <orbId>`.

Curl errors and HTTP 408, 429 and 5xx responses are retried. A request gets 3 attempts in total, 2 s apart.

### Secrets in dispatch

- No secret is in `argv`. `curl` reads the URL, header and body from a config on stdin.
- Every printed line is redacted: the exact `ORB_TOKEN` and control token, `aop_live_*`, long `orb_*` tokens, JWT-shaped strings, and `Bearer <value>`.
- The script never prints its environment.

You don't run `dispatch.sh` yourself, except in external mode. For its variables, see [Environment and files](/docs/reference/environment/).

Amp shows these lines in the thread setup log, so that is the first place to look when an orb doesn't start. For the orb's own bootstrap log, run `cf-orbs logs <orb>`.

Source: https://cf-orbs-site.mdick85.workers.dev/docs/concepts/provider-and-dispatch/index.mdx
