---
title: "Deploy hooks & CI — warmup.rocks Docs"
description: "Trigger a warm run right after every deploy: per-project deploy-hook URL, the official GitHub Action, and examples for GitLab CI, Netlify, Vercel and plain curl."
canonical: https://warmup.rocks/docs/deploy-hooks
---

# Deploy hooks & CI

Every deploy purges parts of your CDN cache. A deploy hook re-warms it _immediately_ — instead of your visitors paying the cold-cache penalty until the next scheduled run.

## Get your hook URL

1.  Open your project in the [dashboard](https://warmup.rocks/app/) and go to **Settings**.
2.  Under **Deploy hook**, click **Generate hook URL**.
3.  Copy the URL and store it as a secret in your CI system — anyone with the URL can trigger runs for this project.

The URL looks like this:

```
https://warmup.rocks/api/hooks/<token>
```

You can **rotate** it (old URL stops working, new one is issued) or **disable** it entirely at any time, in the same place.

## GitHub Action (recommended)

Use the official [warmup-rocks/warm-action](https://github.com/warmup-rocks/warm-action) (also on the [GitHub Marketplace](https://github.com/marketplace/actions/warmup-rocks-cdn-cache-warmer)). Add your hook URL as an encrypted repository secret named `WARMUP_HOOK_URL`, then append one step to your deploy workflow:

```
- name: Warm CDN cache
  uses: warmup-rocks/warm-action@v1
  with:
    hook-url: ${{ secrets.WARMUP_HOOK_URL }}
```

The Action runs in _your_ repository's CI, takes about a second, and fails your workflow only if the hook is unreachable or invalid — never because a run was skipped.

## Plain curl (works everywhere)

The hook is a single `POST` request, so any CI system, deploy script or platform webhook can call it:

```
curl -fsS -X POST "$WARMUP_HOOK_URL"
```

-   **GitLab CI:** add the URL as a masked CI/CD variable and run the curl command as the last step of your deploy job.
-   **Netlify / Vercel:** call the curl command in a post-deploy step (`netlify.toml` deploy hook, or a Vercel deployment webhook pointed at a tiny forwarder). If your pipeline lives on GitHub anyway, prefer the Action.
-   **Server-side deploys:** append the curl line to your deploy script, after the cache purge.

## Responses & rate limiting

The endpoint always answers with JSON:

```
{ "ok": true, "runId": 1234 }          // run started
{ "ok": true, "skipped": "already-running" }
{ "ok": true, "skipped": "cooldown" }  // < 5 min since last hook run
```

-   Hook runs are limited to **one per project every 5 minutes**. Rapid deploy sequences (retries, matrix builds) simply return `skipped` — that's a success, not an error.
-   While a warm run is already in progress, new hook calls return `already-running`.
-   A paused or unverified project answers `409`; an unknown or rotated token answers `404`.

Runs triggered this way appear in your [run history](https://warmup.rocks/app/) with the trigger **deploy**, with the same per-location statistics as scheduled runs.

## Security notes

-   The hook URL is the only credential — treat it like a password and always inject it via your CI's secret store, never commit it.
-   If a URL leaks, rotate it in the dashboard; the old token is invalidated immediately.
-   The worst an attacker can do with a leaked URL is warm your cache once every 5 minutes — annoying, not dangerous. Rotate anyway.
