Webhook Refresh API
Overview
The Webhook Refresh API lets you trigger cache refreshes from external systems -- deploy pipelines, CMS webhooks, or custom scripts. This is different from the Cache API refresh endpoints: it uses webhook tokens instead of API keys, and it is scoped to a single domain per token.
Available on Agency+ plans only.
Endpoint
POST /api/webhook/refresh
Authentication
Webhook requests use a Bearer token in the Authorization header. Tokens are created per-domain from the dashboard.
Authorization: Bearer rk_wh_your_token_here
Creating a Webhook Token
- Go to Dashboard > Your Domain > Cache tab.
- Scroll to Webhook Tokens.
- Click Create Token and give it a name.
- Copy the token immediately -- it is only shown once.
You can have up to 5 tokens per domain.
Selective URL Refresh
Refresh specific pages by passing a urls array. Each path must start with /. Maximum 20 paths per request.
curl
curl -X POST https://rndrkit.io/api/webhook/refresh \
-H "Authorization: Bearer rk_wh_your_token_here" \
-H "Content-Type: application/json" \
-d '{"urls": ["/", "/blog/new-post", "/pricing"]}'
JavaScript
const response = await fetch("https://rndrkit.io/api/webhook/refresh", {
method: "POST",
headers: {
"Authorization": "Bearer rk_wh_your_token_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
urls: ["/", "/blog/new-post", "/pricing"],
}),
});
const data = await response.json();
console.log(`${data.pagesQueued} pages queued for ${data.domain}`);
Response 200
{
"message": "Cache refresh queued",
"domain": "example.com",
"pagesQueued": 3
}
Full Domain Refresh
Set all: true to refresh the entire domain. This fires off a full cache warm -- all known paths are re-rendered.
curl
curl -X POST https://rndrkit.io/api/webhook/refresh \
-H "Authorization: Bearer rk_wh_your_token_here" \
-H "Content-Type: application/json" \
-d '{"all": true}'
JavaScript
const response = await fetch("https://rndrkit.io/api/webhook/refresh", {
method: "POST",
headers: {
"Authorization": "Bearer rk_wh_your_token_here",
"Content-Type": "application/json",
},
body: JSON.stringify({ all: true }),
});
const data = await response.json();
console.log(data.message); // "Full cache refresh started"
Response 200
{
"message": "Full cache refresh started",
"domain": "example.com"
}
Rate Limits
The webhook endpoint is rate-limited to 10 requests per hour per domain. This limit is shared across all tokens for the same domain.
If you exceed the limit:
{
"error": "Rate limit exceeded (10 requests/hour)"
}
The counter resets after one hour from the first request in the window.
Requests that fail validation (missing urls/all, invalid paths) still count against the limit. Always include Content-Type: application/json and a valid request body.
Render Quota
Webhook refreshes count against your monthly render quota. If the domain has reached its monthly_render_limit, the request is rejected:
{
"error": "Monthly render limit reached"
}
Error Responses
| Status | Body | Meaning |
|---|---|---|
400 | {"error": "Provide \"urls\" array or \"all\": true"} | Missing or empty request body |
400 | {"error": "No valid URL paths (must start with /)"} | Paths do not start with / |
401 | {"error": "Missing or invalid Authorization header"} | No Bearer token provided |
401 | {"error": "Invalid token"} | Token not found or revoked |
403 | {"error": "Domain is not active"} | Domain has been deactivated |
403 | {"error": "Webhook refresh requires Agency+ plan"} | Subscription does not support webhooks |
403 | {"error": "Monthly render limit reached"} | Render quota exhausted |
429 | {"error": "Rate limit exceeded (10 requests/hour)"} | Too many requests |
Integration Examples
GitHub Actions
Trigger a cache refresh after every deploy:
# .github/workflows/deploy.yml
name: Deploy & Refresh Cache
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ... your deploy steps ...
- name: Refresh RndrKit cache
run: |
curl -X POST https://rndrkit.io/api/webhook/refresh \
-H "Authorization: Bearer ${{ secrets.RNDRKIT_WEBHOOK_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"urls": ["/", "/about", "/pricing", "/blog"]}'
Generic CI/CD
Drop this into any pipeline that supports shell commands:
# Refresh specific pages after deploy
curl -sf -X POST https://rndrkit.io/api/webhook/refresh \
-H "Authorization: Bearer $RNDRKIT_WEBHOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls": ["/", "/about"]}' \
&& echo "Cache refresh queued" \
|| echo "Cache refresh failed"
Vercel Deploy Hook
Add a post-deploy script to your package.json:
{
"scripts": {
"postdeploy": "curl -sf -X POST https://rndrkit.io/api/webhook/refresh -H 'Authorization: Bearer $RNDRKIT_WEBHOOK_TOKEN' -H 'Content-Type: application/json' -d '{\"all\": true}'"
}
}
Full Site Refresh on Content Update
If your CMS supports webhooks, point it at the RndrKit endpoint with "all": true to refresh the entire site when content changes:
curl -X POST https://rndrkit.io/api/webhook/refresh \
-H "Authorization: Bearer rk_wh_your_token_here" \
-H "Content-Type: application/json" \
-d '{"all": true}'