Cloudflare
In this guide, you’ll learn how to build a server-side paywall using Pelcro and Cloudflare Workers to securely enforce content access at the edge.
Category: How-To Guide
Overview
In this guide, you’ll learn how to build a server-side paywall using Pelcro and Cloudflare Workers to securely enforce content access at the edge.
You’ll use Pelcro’s Authentication and Authorization APIs to:
- Identify logged-in users from their Pelcro token.
- Retrieve the user resource.
- Verify the user’s entitlements before serving premium content.
By the end, you’ll have a working Cloudflare Worker that authenticates a Pelcro user, checks their subscription, and conditionally serves or blocks content.
Prerequisites
- A Pelcro tenant with API access (server-side key).
- A Cloudflare account with Workers and KV storage enabled.
Step 1 — Understand the Flow
A server-side paywall runs before your content is served.
Cloudflare Workers intercept the request, validate the user’s Pelcro token, and call Pelcro APIs to check entitlements.
User → Cloudflare Worker → Pelcro API (auth + entitlements) → CMS (content)
If the user is entitled, the Worker lets the request continue to your CMS.
Otherwise, it blocks or shows a preview.
Step 2 — Authenticate the User via Pelcro
You can retrieve a user’s information using their token.
After login on your site, Pelcro sets the JWT token.
Inside your Worker, extract the token and call the Pelcro Open API /customer endpoint:
async function getUserFromPelcro(apiBase, siteId, token) {
const res = await fetch(`${apiBase}/customer?site_id=${siteId}`, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!res.ok) return null;
const data = await res.json();
return data.data; // returns the Pelcro user resource
}Response Example:
{
"data": {
"id": 1017,
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"subscriptions": [
{
"id": 55501,
"status": "active",
"current_period_start": "2026-09-01",
"current_period_end": "2026-10-01",
"cancel_at_period_end": 0,
"plan": {
"id": 6789,
"nickname": "Digital Monthly",
"interval": "month",
"entitlements": ["premium"],
"product": {
"id": 321,
"name": "Digital Access"
}
}
}
],
"memberships": [
{
"id": 901,
"status": "active",
"subscription_id": 77002,
"subscription": {
"id": 77002,
"status": "active",
"plan": {
"id": 7001,
"nickname": "Corporate Licence",
"entitlements": ["newsletter_pro"],
"product": { "id": 400, "name": "Business Edition", "entitlements": [] }
}
}
}
],
"orders": [
{
"id": 3301,
"status": "paid",
"items": [
{
"id": 1,
"product_sku_id": 88,
"product_sku_name": "Election Guide eBook",
"product_sku_entitlements": ["ebook_election_2026"]
}
]
}
],
"expired_subscriptions": null
}
}
```✅ Tip: Store your PELCRO_API_URL (e.g., https://api.pelcro.com/v3) as an environment variable or Worker Secret.
Step 3 — Check Entitlements
Following Pelcro’s Authorization recipe, you can verify whether the user has access to a specific resource (content, tier, or plan).
Step 4 — Combine Authentication and Authorization in the Worker
Here’s how the complete Cloudflare Worker ties everything together:
export default {
async fetch(req, env) {
const url = new URL(req.url);
const cookies = parseCookies(req.headers.get("Cookie") || "");
const raw = cookies["pelcro.user.auth.token"];
const token = raw ? atob(decodeURIComponent(raw)) : null;
// Step 1: Authenticate
const user = token ? await getUserFromPelcro(env.PELCRO_API_URL, env.PELCRO_SITE_ID, token) : null;
// Step 2: Check entitlement
const allowed = user ? checkEntitlement(user, env.PELCRO_ENTITLEMENT) : false;
// Step 3: Enforce paywall
if (allowed) {
return fetch(req);
}
// Not allowed — redirect to Pelcro offers
return Response.redirect("https://yourdomain.com/subscribe", 302);
}
};
function parseCookies(str) {
return Object.fromEntries(str.split(";").map(v => v.trim().split("=")).filter(p => p[0]));
}✅ Note: This Worker enforces the paywall server-side, so users cannot bypass access control by disabling JavaScript.
Step 5 — Deploy
- Save your Worker code.
- Store
PELCRO_API_URLas a secret:npx wrangler secret put PELCRO_API_URL - Deploy your Worker:
wrangler deploy
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
401 Unauthorized | Token expired or missing | Confirm Pelcro cookie (pelcro.user.auth.token) is present and valid |
| Slow responses | Entitlement API not cached | Use Cloudflare KV to store entitlement results for a few minutes |
Next Steps
- Pelcro API Reference – Authentication
- Pelcro API Reference – Authorization
- Pelcro Paywall Enforcement Overview
- Cloudflare Workers Documentation
Summary
You’ve successfully implemented a server-side paywall using Cloudflare Workers and Pelcro APIs.
Your Worker now:
- Authenticates users with their Pelcro session token.
- Verifies entitlements for each content request.
- Enforces paywall logic before the CMS responds.
This design keeps premium content secure, improves performance, and provides a scalable integration pattern for publishers using Zephyr or Naviga with Pelcro.
Updated 1 day ago

