Subscribe to the members:create Patreon webhook event and handle incoming JSON:API payloads to send personalized welcome emails and grant Discord roles. Webhook payloads are JSON:API graphs — not flat objects — so you need a graph walker to resolve tier names from the included array. Verify signatures with MD5-HMAC using the X-Patreon-Signature header. Note: the official patreon-js Node SDK is deprecated — use direct fetch calls.
| Fact | Value |
|---|---|
| Platform | Patreon |
| Rate limits | Undisclosed per-second limits; 4xx circuit breaker: 2,000 bad requests in 10… |
| Difficulty | Beginner |
| Time required | 45 minutes |
| Last updated | May 2026 |
API Quick Reference
Undisclosed per-second limits; 4xx circuit breaker: 2,000 bad requests in 10 min = 30-min block
REST only
Patreon Webhook-Based Member Onboarding Overview
Patreon's webhook system fires events when membership actions occur — new members joining, pledges created, members leaving. The members:create event fires when someone becomes a patron. Your handler receives a JSON:API payload with member data and must send welcome communications. This is more reliable than polling because it fires in real time.
https://www.patreon.com/api/oauth2/v2Setting Up Webhook Authentication
- 1Create your Patreon OAuth2 client at patreon.com/portal/registration/register-clients
- 2Request the campaigns.members and w:campaigns.webhook scopes
- 3Deploy your webhook handler to a public HTTPS URL before registering
- 4Create the webhook via POST /api/oauth2/v2/webhooks with your public URL and triggers
- 5Patreon will send an initial verification request — your handler must respond with 200
- 6The webhook secret is returned when you create the webhook — store it immediately for signature verification
Key endpoints
/api/oauth2/v2/webhooksCreate a webhook subscription for member events. Requires w:campaigns.webhook scope.
/api/oauth2/v2/members/{member_id}Fetch a single member's full data after receiving a webhook event. Webhook payloads are sparse — use this to get complete member details.
Step-by-step automation
Register the members:create Webhook
Why: You must register your endpoint with Patreon before events start flowing. Without registration, you'll never receive new member events.
Create the webhook via the API. Your endpoint must be publicly reachable over HTTPS before you register. The webhook secret returned in the response is used to verify incoming signature headers.
1export PATREON_TOKEN="your_creator_access_token"23curl -s -X POST \4 -H "Authorization: Bearer $PATREON_TOKEN" \5 -H "User-Agent: MyApp (admin@myapp.com)" \6 -H "Content-Type: application/json" \7 -d '{8 "data": {9 "type": "webhook",10 "attributes": {11 "triggers": ["members:create"],12 "uri": "https://yourapp.com/webhooks/patreon/onboarding"13 }14 }15 }' \16 'https://www.patreon.com/api/oauth2/v2/webhooks' | python3 -m json.toolVerify MD5-HMAC Signature on Incoming Webhooks
Why: Anyone can POST to your webhook URL. Signature verification confirms the request genuinely came from Patreon using your webhook secret. Without this, attackers could fake member events.
Verify the X-Patreon-Signature header on every incoming webhook. The signature is an MD5-HMAC hex digest of the raw request body using the webhook secret as the key.
1# Verification is done in your webhook handler server code, not curl2# Test that your endpoint is reachable:3curl -s -X POST \4 -H "Content-Type: application/json" \5 -H "X-Patreon-Event: members:create" \6 -H "X-Patreon-Signature: test" \7 -d '{"test": true}' \8 https://yourapp.com/webhooks/patreonParse JSON:API Payload and Extract Member Data
Why: Patreon webhook payloads are JSON:API graphs with nested relationships. The member resource has relationships pointing to tiers and user objects in the included array. You must walk these relationships to get the tier name.
Write a JSON:API graph walker that resolves the member, their entitled tier(s), and their user profile from the webhook payload.
1# Example of what a members:create payload looks like:2# {3# "data": {4# "type": "member",5# "id": "member_id",6# "attributes": {7# "full_name": "Jane Doe",8# "patron_status": "active_patron",9# "currently_entitled_amount_cents": 50010# },11# "relationships": {12# "currently_entitled_tiers": { "data": [{ "type": "tier", "id": "tier_id" }] }13# }14# },15# "included": [16# { "type": "tier", "id": "tier_id", "attributes": { "title": "Gold Tier" } }17# ]18# }Send Welcome Email and Grant Discord Role
Why: Automated welcome flows create a strong first impression and confirm to new patrons that their membership is active. Manual welcome emails are inconsistent and slow.
After extracting member data, send a personalized welcome email and grant the appropriate Discord role based on tier. Process these asynchronously — always return 200 to Patreon first.
1# Discord role grant via Discord API2# Replace DISCORD_BOT_TOKEN, GUILD_ID, USER_ID, ROLE_ID with your values3curl -s -X PUT \4 -H "Authorization: Bot $DISCORD_BOT_TOKEN" \5 -H "Content-Type: application/json" \6 "https://discord.com/api/v10/guilds/$GUILD_ID/members/$DISCORD_USER_ID/roles/$ROLE_ID"Complete working code
Complete Patreon member onboarding webhook handler. Verifies MD5-HMAC signature, parses JSON:API payload, extracts member and tier data, and triggers welcome automation.
Error handling
The webhook was created but your URL is not publicly reachable, or the webhook is paused.
Verify your endpoint is accessible from the public internet. Use ngrok for local testing. Check webhook status at GET /api/oauth2/v2/webhooks — look for paused: true. Unpause with PATCH /api/oauth2/v2/webhooks/{id} with paused: false.
Signature verification fails if you parse the body before verification, or if the webhook secret is wrong.
Always verify against the RAW request body bytes — before JSON.parse or body parsing middleware processes it. The express.raw() middleware captures the raw buffer. Confirm the secret matches the one returned when the webhook was created.
The campaigns.members[email] scope was not requested when creating the OAuth client.
Re-register your OAuth client requesting the campaigns.members[email] scope, then re-authorize. Without this scope, email is simply omitted from all member responses — no error is thrown.
Your handler returned a non-200 status, causing Patreon to retry. If a member joins while retries are in flight, they may receive multiple welcome emails.
Always return 200 immediately. Process member onboarding logic asynchronously after the response. Add idempotency checking: store processed member IDs in a database and skip duplicates.
The access token lacks the w:campaigns.webhook scope.
The w:campaigns.webhook scope is required to create, list, update, or delete webhooks via the API. Alternatively, create webhooks manually at patreon.com/portal/registration/clients/{id}/webhooks without needing this scope.
Rate Limiting for Patreon Webhook Handlers
| Scope | Limit | Window |
|---|---|---|
Security checklist
- Store PATREON_WEBHOOK_SECRET in environment variables — never hardcode
- Always verify X-Patreon-Signature before processing any webhook payload
- Use the RAW request body for signature verification — parsed JSON will fail
- Return 200 immediately and process asynchronously to prevent timeout retries
- Implement idempotency: store processed member IDs to prevent duplicate welcome emails from retried webhooks
- Add campaigns.members[email] scope only if you genuinely need email for onboarding
- Rotate webhook secrets periodically — delete and recreate webhooks to rotate
Automation use cases
Instant Discord Role Grant
When a new patron joins, immediately grant the corresponding Discord role based on tier. Requires a flow to link Patreon accounts to Discord IDs — typically via a 'Connect Discord' OAuth page on your site.
Personalized Welcome Email Series
Trigger a welcome email sequence via ConvertKit, Mailchimp, or Beehiiv tagged with the patron's tier and pledge amount. Include exclusive content links specific to their tier.
Slack/Discord Creator Alert
Notify yourself in a private Slack or Discord channel when a new patron joins, with their name, tier, and pledge amount. Useful for high-touch creator communities.
Best practices
- Always return 200 from your webhook handler immediately — then process asynchronously. Non-200 responses cause Patreon to retry, leading to duplicate welcome emails
- Implement idempotency from day one — store processed member IDs and skip duplicates in case of retried deliveries
- Write a JSON:API graph walker function — every Patreon webhook payload has this structure and you'll reuse the resolver across multiple handlers
- Test with ngrok and a local server before deploying — this lets you inspect the exact payload format before writing production code
- Request campaigns.members[email] scope only if you need email for the onboarding flow — don't request more scope than necessary
- Log the full webhook payload on first receipt — the actual payload structure sometimes differs slightly from documentation
- Never use the deprecated patreon-js SDK — use direct fetch/axios calls or the community patreon-api.ts TypeScript library
Ask AI to help
Copy one of these prompts to get a personalized, working implementation.
I'm building a Patreon member onboarding webhook handler. It needs to verify X-Patreon-Signature using MD5-HMAC with the webhook secret, then parse the JSON:API payload to extract member name, email, and tier name (from the included array relationships). After verification, it should send a welcome email and return 200 immediately. Can you help me add an idempotency layer that checks a Redis set for already-processed member IDs before sending the welcome email?
Frequently asked questions
How do I get the patron's email from the webhook payload?
Email is only included if you requested the campaigns.members[email] scope when creating your OAuth client. Without this scope, the email field is simply absent from member responses — no error is thrown, it's just missing. Re-register your client with this scope, then re-authorize. The scope addition is retroactive to the next authorization.
What does the MD5-HMAC signature verification involve?
Compute HMAC-MD5 of the raw request body using the webhook secret as the key. Compare the hex digest to the X-Patreon-Signature header value. MD5 is not collision-resistant but is acceptable for webhook integrity checks in this context. Always use the raw bytes before JSON parsing — parsing first changes the byte content and invalidates the signature.
Why are there nested relationships in the webhook payload?
Patreon uses the JSON:API specification which separates resource objects from their relationships. The member's tier information is in the included array, referenced via ID in the relationships section. You must walk from member → relationships.currently_entitled_tiers.data[].id → find matching item in included[]. This is standard JSON:API pattern but unfamiliar if you're used to flat REST APIs.
How do I test my webhook handler locally?
Use ngrok to create a temporary public HTTPS tunnel to your local server: ngrok http 3000. Register the ngrok URL as your webhook endpoint in Patreon. Then join your own campaign at the lowest tier to trigger a members:create event. Use a test or free tier if available. ngrok's web interface (localhost:4040) shows the exact payload received.
What happens if my webhook handler is down when a member joins?
Patreon queues webhook deliveries and retries them. When your handler comes back online and returns 200, Patreon delivers all queued events. This means your handler could receive a burst of multiple events at restart. Implement idempotency (check processed member IDs) to prevent duplicate welcome emails from batch retries.
Can I link Patreon membership to Discord roles without code?
Yes — Patreon has a native Discord integration in the creator dashboard that automatically grants roles when patrons join specific tiers. This requires no code and is the recommended approach unless you need custom logic (e.g., dynamic role names, additional integrations, or custom welcome messages).
Can RapidDev help set up a complete Patreon onboarding flow?
Yes. RapidDev builds complete creator monetization automations that connect Patreon webhooks to email providers, Discord, Slack, and custom membership databases. The basic webhook handler in this guide is a solid foundation — production systems typically add idempotency, error alerting, and multi-tier routing logic.
Need this automated?
Our team has built 600+ apps with API automations. We can build this for you.
Book a free consultation