Set your webhook endpoint
Sets the https endpoint that receives your app’s events. The first call also creates the signing secret and returns it **once** as `secret`. Store it; later calls don’t return it (use rotate-webhook-secret).
/api/external/webhooksNewSets the https endpoint that receives your app’s events. The first call also creates the signing secret and returns it once as secret. Store it; later calls don’t return it (use rotate-webhook-secret).
Leave events out to get every event, including ones added later.
Authentication
Send the creator's API key as a bearer token: Authorization: Bearer dpfn_…. See Authentication & API keys.
Request body
Content type: application/json
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Required | Public https URL (no IPs, no localhost, no credentials). Format: uri |
events | string[] | Optional | Subset of events to receive. Omit for all. |
{
"url": "https://crm.example.com/hooks/dropfans"
}Responses
| Name | Type | Description |
|---|---|---|
url | string | The saved endpoint. Format: uri |
events | string[] | Events delivered. |
secret | string | Signing secret (whsec_…) — only on the first save. |
{
"url": "https://crm.example.com/hooks/dropfans",
"events": [
"drop.paid",
"drop.refunded",
"account.kyc_updated"
],
"secret": "whsec_8d1e…"
}Errors
| Status | Body | When |
|---|---|---|
| 400 | {"error":"url must use https"} | Not a public https URL, or unknown events. |
| 401 | {"error":"Unauthorized","code":"unauthorized"} | Missing or invalid API key. |
| 403 | {"error":"This endpoint needs a key bound to an approved app.","code":"app_key_required"} | A Personal key was used. |
| 403 | {"error":"Use the app owner's key for this endpoint.","code":"owner_key_required"} | The key was minted by a creator for themselves. App-level calls need a key held by your app owner: their own, or one their agency minted for its personas or managed creators. |
Rate limiting
Every response carries the X-RateLimit-Tier header and, on limited tiers, the per-minute and per-day trios — read X-RateLimit-Remaining and X-RateLimit-Reset instead of hardcoding limits. Details in Rate limits.
Code samples
curl -X PUT "https://www.dropfans.io/api/external/webhooks" \
-H "Authorization: Bearer $DROPFANS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://crm.example.com/hooks/dropfans"
}'const res = await fetch(`https://www.dropfans.io/api/external/webhooks`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.DROPFANS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"url": "https://crm.example.com/hooks/dropfans"
}),
});
console.log(await res.json());import os
import requests
res = requests.put(
"https://www.dropfans.io/api/external/webhooks",
headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"},
json={
"url": "https://crm.example.com/hooks/dropfans",
},
)
print(res.json())Questions? [email protected]
