Scenario
A customer buys “Premium Course” on Hotmart. Within seconds they get access to the “Premium Students” group and to the course inside your Cativa community. The bridge between both sides is the badge-as-permission concept: thePremium badge is configured in the Console as the access requirement on that group and course. Once the user gets the badge, access shows up automatically. When the badge is removed, access is gone.
Prerequisites
- Cativa API Key — generated in the Console (Developers > API Keys). See Quick Start: API Key. Every call uses
Authorization: Bearer cativa_live_.... - Badge configured in the Console — create the
Premiumbadge (or whatever your product is called) and configure it as the access requirement on the group/course. See Badges as Permissions. - Purchase webhook from your gateway — Hotmart, Kiwify, Eduzz and Stripe fire a webhook to your server’s endpoint when a purchase is confirmed. Do not point the gateway webhook directly at Cativa — you need a proxy server that receives, validates and translates the event.
- A reliable buyer email — every gateway sends the email in the purchase payload. That’s the join key with the Cativa user.
Architecture
- Validate the gateway webhook (each one has its own signature — check the gateway docs).
- Handle idempotency (Hotmart can fire the same webhook twice).
- Log the gateway purchase ID for audit/reconciliation.
- Decide the right badge based on which product was purchased.
user_received_badge webhook to fire a welcome email, update your CRM, or log an analytics event.
Implementation
Receive the gateway webhook
https://myapp.com/webhooks/hotmart).Cativa does not document the gateway webhook formats — refer to the official docs:Receiver skeleton (Express, Hotmart example):Resolve or create the user on Cativa by email
User.Id from the email with GET /admin/users/email/{email}.200 OK response (illustrative; full schema in the API Reference, Users tag):email → cativa_user_id table populated by Cativa’s user_created webhook and look it up locally:404. You have two options:- Create directly via API with
POST /admin/users(schema in the API Reference, Users tag) — creates the account on the spot and returns theid, which you use right away to assign the badge. - Invite and complete later: register the intent in
pendingGrants, send the tenant’s sign-up link, and complete the assignment when theuser_createdwebhook arrives (see step 4).
Assign the badge
productId to the Cativa badgeId configured in the Console.Badge assignment via partner API Key is available. You have two options:- Assign by email (
POST /admin/membership/badges/{badgeId}/users/by-email) — no need to resolve theuserIdfirst; Cativa matches on the buyer’s email. Ideal for the webhook, where you only have the email. - Assign by id (
POST /admin/membership/badges/{badgeId}/users/{userId}) — when you already have theuserId(e.g. from theuser_createdwebhook).
200 OK response (illustrative; full schema in the API Reference, Badge tag):userId already resolved:purchaseId check above still avoids redundant calls and helps reconciliation.(Optional) React to the user_received_badge webhook
user_received_badge every time a badge is assigned (regardless of whether it came from the API, Console, or another flow). Subscribe a listener to it if you want to:- Send a welcome email with a link to the community
- Update the contact status in your CRM
- Track conversion in analytics
Cancellation and chargeback
When the gateway cancels or charges back, you want to remove the badge to revoke access.DELETE /admin/membership/badges/{badgeId}/users/{userId}. See the schema in the API Reference tab (Badge tag). Removal is idempotent too: removing a badge that isn’t assigned returns success without error.Common errors
Buyer doesn't have a Cativa account, paid and ended up without access
Buyer doesn't have a Cativa account, paid and ended up without access
pendingGrants and send the invite. Subscribe the user_created webhook and, when sign-up happens, complete the assignment:Different email between gateway and Cativa for the same user
Different email between gateway and Cativa for the same user
Gateway webhook fired twice — did the user get the badge twice?
Gateway webhook fired twice — did the user get the badge twice?
purchaseId in a local table and check before:Gateway offers recurring subscription — how do I handle monthly renewal?
Gateway offers recurring subscription — how do I handle monthly renewal?
SUBSCRIPTION_CHARGE_SUCCESS). Treat it as an idempotent handlePurchase — re-apply the badge (no effect if already there). If the renewal fails (e.g. card declined), treat it as handleCancellation.Customer refunded but kept using the community
Customer refunded but kept using the community
Multiple badges for the same product (course + bonus)
Multiple badges for the same product (course + bonus)
Premium Course unlocks both Premium (course access) and Mentoring-2026 (mentoring group access). Make two assignments inside handlePurchase.Next steps
Cativa webhooks
user_created (cover the “bought before signing up” case) and user_received_badge (trigger post-access actions).