-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[Workers] Deploy Hooks documentation and changelog #29467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
14388fd
initial draft commit for deploy hooks
yomna-shousha ad56c7e
remove proxy worker section - not necessary
yomna-shousha ffd3a6c
[Workers] Rewrite deploy hooks docs, add changelog entry
yomna-shousha f8caf07
[Workers] Fix relative URLs and sidebar order collision per review
yomna-shousha 8ff83f6
Update 2026-04-01-deploy-hooks.mdx
yomna-shousha b62ec9a
docs: add introductory sentence to deploy hooks changelog
yomna-shousha b23d74d
Tighten deploy hooks changelog and fix limits formatting
yomna-shousha File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| --- | ||
| title: Deploy Hooks are now available for Workers Builds | ||
| description: Trigger a build for a specific branch by sending a POST request to a unique URL. | ||
| products: | ||
| - workers | ||
| date: 2026-04-01 | ||
| --- | ||
|
|
||
| import { TypeScriptExample } from "~/components"; | ||
|
|
||
| [Workers Builds](/workers/ci-cd/builds/) now supports Deploy Hooks — trigger builds from your headless CMS, a Cron Trigger, a Slack bot, or any system that can send an HTTP request. | ||
|
|
||
| Each Deploy Hook is a unique URL tied to a specific branch. Send it a `POST` and your Worker builds and deploys. | ||
|
|
||
| ```sh | ||
| curl -X POST "https://api.cloudflare.com/client/v4/workers/builds/deploy_hooks/<DEPLOY_HOOK_ID>" | ||
| ``` | ||
|
|
||
| To create one, go to **Workers & Pages** > your Worker > **Settings** > **Builds** > **Deploy Hooks**. | ||
|
|
||
| Since a Deploy Hook is a URL, you can also call it from another Worker. For example, a Worker with a [Cron Trigger](/workers/configuration/cron-triggers/) can rebuild your project on a schedule: | ||
|
|
||
| <TypeScriptExample> | ||
|
|
||
| ```ts | ||
| export default { | ||
| async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> { | ||
| ctx.waitUntil(fetch(env.DEPLOY_HOOK_URL, { method: "POST" })); | ||
| }, | ||
| } satisfies ExportedHandler<Env>; | ||
| ``` | ||
|
|
||
| </TypeScriptExample> | ||
|
|
||
| You can also use Deploy Hooks to [rebuild when your CMS publishes new content](/workers/ci-cd/builds/deploy-hooks/#cms-integration) or [deploy from a Slack slash command](/workers/ci-cd/builds/deploy-hooks/#deploy-from-a-slack-slash-command). | ||
|
|
||
| ## Built-in optimizations | ||
|
|
||
| - **Automatic deduplication**: If a Deploy Hook fires multiple times before the first build starts running, redundant builds are automatically skipped. This keeps your build queue clean when webhooks retry or CMS events arrive in bursts. | ||
| - **Last triggered**: The dashboard shows when each hook was last triggered. | ||
| - **Build source**: Your Worker's build history shows which Deploy Hook started each build by name. | ||
|
|
||
| Deploy Hooks are rate limited to 10 builds per minute per Worker and 100 builds per minute per account. For all limits, see [Limits & pricing](/workers/ci-cd/builds/limits-and-pricing/). | ||
|
|
||
| To get started, read the [Deploy Hooks documentation](/workers/ci-cd/builds/deploy-hooks/). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| --- | ||
| pcx_content_type: concept | ||
| title: Deploy Hooks | ||
| description: Generate unique URLs that trigger new builds when they receive an HTTP POST request. | ||
| sidebar: | ||
| order: 8 | ||
| --- | ||
|
|
||
| import { Aside, DashButton, TypeScriptExample } from "~/components"; | ||
|
|
||
| By default, Workers Builds triggers a build when you push a commit to your [connected Git repository](/workers/ci-cd/builds/git-integration/). Deploy Hooks provide another way to trigger a build. Each hook is a unique URL that triggers a manual build for one branch when it receives an HTTP POST request. Use Deploy Hooks to connect Workers Builds with workflows such as: | ||
|
|
||
| - Rebuild automatically when content changes in a headless CMS | ||
| - Build on a schedule using an external cron service | ||
| - Trigger deployments from custom CI/CD pipelines based on specific conditions | ||
|
|
||
| ## Create a Deploy Hook | ||
|
|
||
| Before creating a Deploy Hook, ensure your Worker is [connected to a Git repository](/workers/ci-cd/builds/git-integration/). | ||
|
|
||
| 1. Go to **Workers & Pages** and select your Worker. | ||
|
|
||
| <DashButton url="/?to=/:account/workers-and-pages" /> | ||
|
|
||
| 2. Go to **Settings** > **Builds** > **Deploy Hooks**. | ||
| 3. Enter a **name** and select the **branch** to build. | ||
| 4. Select **Create** and copy the generated URL. | ||
|
|
||
| :::note | ||
| Give each Deploy Hook a descriptive name so you can tell them apart. If you have multiple content sources that each need to trigger builds independently, create a separate hook for each one. | ||
| ::: | ||
|
|
||
| ## Trigger a Deploy Hook | ||
|
|
||
| Send an HTTP POST request to your Deploy Hook URL to start a build: | ||
|
|
||
| ```bash | ||
| curl -X POST "https://api.cloudflare.com/client/v4/workers/builds/deploy_hooks/<DEPLOY_HOOK_ID>" | ||
| ``` | ||
|
|
||
| No `Authorization` header is needed. The unique identifier embedded in the URL acts as the authentication credential. | ||
|
|
||
| Example response: | ||
|
|
||
| ```json | ||
| { | ||
| "success": true, | ||
| "errors": [], | ||
| "messages": [], | ||
| "result": { | ||
| "build_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", | ||
| "branch": "main", | ||
| "worker": "my-worker" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The `build_uuid` in the response can be used to [monitor build status and retrieve logs](/workers/ci-cd/builds/api-reference/#get-build-logs). | ||
|
|
||
| ### Verify the build | ||
|
|
||
| After you trigger a Deploy Hook, you can verify it from the dashboard: | ||
|
|
||
| - In the **Deploy Hooks** list, the hook shows when it was last triggered. | ||
| - In your Worker's build history, the **Triggered by** column identifies builds started by a Deploy Hook using the hook name and a `deploy hook` label. | ||
|
|
||
| If you need to inspect these builds programmatically, use [List builds for a Worker](/workers/ci-cd/builds/api-reference/#list-builds-for-a-worker) in the Builds API reference. Hook-triggered builds are recorded with `build_trigger_source: "deploy_hook"`. | ||
|
|
||
| ## CMS integration | ||
|
|
||
| Most headless CMS platforms support webhooks that call your Deploy Hook URL when content changes. The general setup is the same across platforms: | ||
|
|
||
| 1. Find the webhooks or integrations settings in your CMS. | ||
| 2. Create a new webhook and paste your Deploy Hook URL as the target URL. | ||
| 3. Select which events should trigger the webhook (for example, publish, unpublish, or update). | ||
|
|
||
| Refer to your CMS documentation for platform-specific instructions. Popular platforms with webhook support include Contentful, Sanity, Strapi, Storyblok, DatoCMS, and Prismic. | ||
|
|
||
| ## Idempotency | ||
|
|
||
| If the same Deploy Hook is triggered again before the previous build has fully started, Workers Builds does not create a duplicate build. Instead, it returns the build that is already in progress. | ||
|
|
||
| If an external system sends the same Deploy Hook twice in quick succession: | ||
|
|
||
| 1. The first request creates a build. | ||
| 2. If a second request arrives while that build is still `queued` or `initializing`, no second build is created. | ||
| 3. Instead, the response returns the existing `build_uuid` and sets `already_exists` to `true`. | ||
|
|
||
| Example response when an existing pending build is returned: | ||
|
|
||
| ```json | ||
| { | ||
| "success": true, | ||
| "errors": [], | ||
| "messages": [], | ||
| "result": { | ||
| "build_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", | ||
| "status": "queued", | ||
| "created_on": "2026-01-21T18:50:00Z", | ||
| "already_exists": true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Once the earlier build moves past `initializing`, a later POST creates a new build as normal. This makes Deploy Hooks safe to use with systems that retry webhooks or emit bursts of content-update events. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Deploy from a Slack slash command | ||
|
|
||
| A Worker that receives a `/deploy` command from Slack and triggers a build: | ||
|
|
||
| <TypeScriptExample> | ||
|
|
||
| ```ts | ||
| export default { | ||
| async fetch(request: Request, env: Env): Promise<Response> { | ||
| const body = await request.formData(); | ||
| const command = body.get("command"); | ||
| const token = body.get("token"); | ||
|
|
||
| if (token !== env.SLACK_VERIFICATION_TOKEN) { | ||
| return new Response("Unauthorized", { status: 401 }); | ||
| } | ||
|
|
||
| if (command === "/deploy") { | ||
| const res = await fetch(env.DEPLOY_HOOK_URL, { method: "POST" }); | ||
| const { result } = await res.json<{ result: { build_uuid: string } }>(); | ||
| return new Response(`Build started: ${result.build_uuid}`); | ||
| } | ||
|
|
||
| return new Response("Unknown command", { status: 400 }); | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| </TypeScriptExample> | ||
|
|
||
| ### Rebuild on a schedule | ||
|
|
||
| A Worker with a [Cron Trigger](/workers/configuration/cron-triggers/) that rebuilds every hour: | ||
|
|
||
| <TypeScriptExample> | ||
|
|
||
| ```ts | ||
| export default { | ||
| async scheduled(event: ScheduledEvent, env: Env): Promise<void> { | ||
| await fetch(env.DEPLOY_HOOK_URL, { method: "POST" }); | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| </TypeScriptExample> | ||
|
|
||
| ## Security considerations | ||
|
|
||
| <Aside type="caution"> | ||
| Deploy Hook URLs do not require a separate authorization header. Anyone with | ||
| access to the URL can trigger builds for your Worker, so store them like | ||
| other sensitive credentials. | ||
| </Aside> | ||
|
|
||
| - Store Deploy Hook URLs in environment variables or a secrets manager, never in source code or public configuration files. | ||
| - Restrict access to the URL to only the systems that need it. | ||
| - If a URL is compromised or you suspect unauthorized use, delete the Deploy Hook immediately and create a new one. The old URL stops working as soon as it is deleted. | ||
|
|
||
| ### Using the Builds API for authenticated triggers | ||
|
|
||
| If your external system supports custom headers, you can call the [manual build endpoint](/api/resources/workers_builds/subresources/triggers/methods/create_build) with an API token in the `Authorization` header instead. This gives you token-based authentication and the ability to choose the branch per request. For a step-by-step walkthrough, see [Trigger a manual build](/workers/ci-cd/builds/api-reference/#trigger-a-manual-build). | ||
|
|
||
| ## Limits | ||
|
|
||
| Deploy Hooks are rate limited to 10 builds per minute per Worker and 100 builds per minute per account. For all Workers Builds limits, see [Limits & pricing](/workers/ci-cd/builds/limits-and-pricing/). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.