Webhooks
Receive real-time notifications when events occur in your Trakkr account. Integrate with Zapier, Make, Slack, Discord, and more.
Code example
curl -X POST 'https://api.trakkr.ai/webhooks' \
-H "Authorization: Bearer $TRAKKR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"url":"https://hooks.zapier.com/hooks/catch/123456/abcdef","events":["report_completed","rank_changed"],"brand_id":"00000000-0000-4000-8000-81f286d10c3c","auth_type":"none"}'{
"id": "whk_abc123xyz",
"object": "webhook",
"url": "https://hooks.zapier.com/hooks/catch/123456/abcdef",
"events": ["report_completed", "rank_changed"],
"brand_id": "00000000-0000-4000-8000-81f286d10c3c",
"provider": "zapier",
"active": true,
"signing_secret": "redacted-example",
"created_at": "2026-01-09T10:00:00Z"
}Synthetic example. Values are made up.
API key required
10 to 60 req/minOverview
Webhooks allow you to receive real-time HTTP notifications when events occur in your Trakkr account. Instead of polling for changes, webhooks push data to your endpoint the moment something happens.
Supported Integrations
- • Generic webhooks (any HTTPS endpoint)
- • Zapier and Make (Integromat)
- • Slack (with rich block formatting)
- • Discord (with embed formatting)
- • Microsoft Teams (with adaptive cards)
Event Types
Subscribe to one or more event types when creating a webhook. Every type listed here has a live producer behind it.
| Event | Description |
|---|---|
| Visibility and competitive position | |
visibility_changed | Your visibility score moved beyond the alert threshold |
rank_changed | A tracked competitor crossed your brand. Carries competitors_crossed |
competitor_changed | A competitor's visibility moved beyond the alert threshold |
competitor_added | A new competitor was detected or added |
report_completed | A report finished. report_type is daily for the daily visibility scan, or the document type when you call POST /get-reports |
| Citations | |
citation_gained | Brand gained a new citation source |
citation_lost | A page that was being cited stopped appearing |
page_cited | One of your pages was cited by an AI model |
| Perception | |
perception_changed | A perception score moved |
narrative_shift | AI changed how it positions or talks about the brand |
descriptor_change | The words AI uses to describe the brand turned over |
goal_achieved | A perception goal reached its target |
goal_regression | A perception goal slipped off track |
| Opportunities and content | |
opportunity_found | A citation opportunity was found |
prompt_gap | AI answers a prompt with competitors and not you |
article_generated | An article finished generating |
article_published | An article was marked published |
campaign_completed | Every article in a campaign finished |
research_completed | A research scan finished |
| Site health and crawlers | |
audit_score_dropped | Site AI readiness score dropped |
crawler_spike | AI crawler traffic spiked above its normal daily average |
crawler_first_seen | An AI bot crawled one of your pages for the first time |
crawler_silent | A previously active AI bot stopped visiting |
crawler_error_surge | AI crawlers started hitting broken pages |
| Actions | |
action_created | A new action landed in the queue |
action_completed | An action was marked complete |
| Client portal | |
client_invite_accepted | A client accepted their invite to your white-label portal |
client_access_revoked | A client's portal access was revoked |
report_completed instead. It fires when the daily visibility scan completes and carries that day's visibility along with the change since the previous report, so you can act on the event without a follow-up read.crawler_first_seen is the highest volume of all, one per new bot and page pair. Visibility, ranking, citation and competitor events follow the completed daily visibility scan. Content, action and client portal events fire as the work happens.Create Webhook
/webhooksAuthenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
JSON request body (required)
urlstringRequired
HTTPS endpoint URL
eventsstring[]Required
Event types to subscribe to
Fields in events
Array of string.
string.
brand_idstringRequired
Brand UUID
Format: uuid
auth_typestring | nullOptional
Authentication: "none", "bearer", "basic", or "api_key"
Default: "none" · Options: "none", "bearer", "basic", "api_key"
auth_tokenstring | nullOptional
Bearer token (if auth_type is bearer)
auth_usernamestring | nullOptional
auth_passwordstring | nullOptional
api_key_headerstring | nullOptional
api_key_valuestring | nullOptional
signing_secretstring | nullOptional
Custom signing secret (auto-generated if omitted)
headersobject | nullOptional
payload_templateobject | nullOptional
Responses and errors
200Successful Response
application/json
idstringRequired
objectstringOptional
Default: "webhook"
urlstringRequired
eventsstring[]Required
Fields in events
Array of string.
string.
brand_idstringRequired
providerstringRequired
activebooleanRequired
signing_secretstring | nullOptional
created_atstringRequired
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
422Validation Error
application/json
detailobject[]Optional
Fields in detail
Array of object.
locstring | integer[]Required
Fields in loc
Array of string | integer.
string
string.
integer
integer.
msgstringRequired
typestringRequired
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
Register a new webhook endpoint to receive event notifications.
Payload Format
Webhook payloads follow a consistent structure across all event types:
{
"event": {
"id": "evt_xyz789abc",
"type": "visibility_changed",
"triggered_at": "2026-01-09T14:30:00Z",
"data": {
"brand_id": "00000000-0000-4000-8000-81f286d10c3c",
"previous_score": 42.5,
"current_score": 38.2,
"change_percent": -10.1,
"direction": "down"
}
},
"brand": {
"id": "00000000-0000-4000-8000-81f286d10c3c",
"name": "Notion",
"website": "https://notion.so"
},
"workflow": {
"id": "wf_123abc",
"name": "Visibility Drop Alert"
},
"summary": "Visibility dropped 10.1% from 42.5 to 38.2",
"meta": {
"source": "trakkr",
"version": "2.0",
"event_id": "evt_xyz789abc",
"timestamp": "2026-01-09T14:30:00Z"
}
}Synthetic example. Values are made up.
meta.event_id field for idempotency. Store processed event IDs to prevent duplicate handling if a webhook is retried.Payload Templating
Customize webhook payloads using variable substitution with double curly braces:
{
"text": "Alert: {{brand.name}} visibility changed!",
"score": "{{event.data.current_score}}",
"change": "{{event.data.change_percent}}%"
}Available Variables
{{brand.id}}{{brand.name}}{{brand.website}}{{event.type}}{{event.data.*}}{{summary}}{{workflow.name}}{{timestamp}}Authentication
Secure your webhook endpoints with one of the supported authentication methods:
Bearer Token
Set auth_type: "bearer" and provide auth_token. The token is sent in the Authorization: Bearer header.
Basic Auth
Set auth_type: "basic" with auth_username and auth_password.
API Key Header
Set auth_type: "api_key" with api_key_header and api_key_value.
Signature Verification
Verify webhook authenticity using HMAC-SHA256 signatures. When you provide asigning_secret, every request includes an X-Trakkr-Signature header.
X-Trakkr-Signature: sha256=abc123def456...
Verification Example (Python)
import hmac
import hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)Retry Logic
Webhooks are retried automatically on failure with exponential backoff:
3 retries with delays of 1s, 2s, 4s (exponential backoff)
5xx errors and timeouts trigger retries
429 rate limits respect the Retry-After header
Provider-Specific Formatting
Trakkr automatically formats payloads for popular platforms:
Discord
Rich embeds with title, description, fields, and Trakkr green accent color.
Slack
Block Kit formatting with headers, sections, and context elements.
Zapier & Make
Standard JSON payload with all fields available for mapping.
Manage webhooks
List webhooks with an optional brand filter, inspect one endpoint, remove it or send a test event. Each operation checks your API key and access.
GET /webhooks
/webhooksAuthenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
Request parameters
brand_idstring | nullqueryOptional
Filter by brand UUID
Format: uuid
Responses and errors
200Successful Response
application/json
webhooksobject[]Required
Fields in webhooks
Array of object.
idstringRequired
objectstringOptional
Default: "webhook"
urlstringRequired
eventsstring[]Required
Fields in events
Array of string.
string.
brand_idstringRequired
providerstringRequired
activebooleanRequired
signing_secretstring | nullOptional
created_atstringRequired
totalintegerRequired
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
422Validation Error
application/json
detailobject[]Optional
Fields in detail
Array of object.
locstring | integer[]Required
Fields in loc
Array of string | integer.
string
string.
integer
integer.
msgstringRequired
typestringRequired
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
GET /webhooks/{webhook_id}
/webhooks/{webhook_id}Authenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
Request parameters
webhook_idstringpathRequired
Responses and errors
200Successful Response
application/json
idstringRequired
objectstringOptional
Default: "webhook"
urlstringRequired
eventsstring[]Required
Fields in events
Array of string.
string.
brand_idstringRequired
providerstringRequired
activebooleanRequired
signing_secretstring | nullOptional
created_atstringRequired
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
422Validation Error
application/json
detailobject[]Optional
Fields in detail
Array of object.
locstring | integer[]Required
Fields in loc
Array of string | integer.
string
string.
integer
integer.
msgstringRequired
typestringRequired
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
DELETE /webhooks/{webhook_id}
/webhooks/{webhook_id}Authenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
Request parameters
webhook_idstringpathRequired
Responses and errors
200Successful Response
application/json
successbooleanRequired
deleted_idstringRequired
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
422Validation Error
application/json
detailobject[]Optional
Fields in detail
Array of object.
locstring | integer[]Required
Fields in loc
Array of string | integer.
string
string.
integer
integer.
msgstringRequired
typestringRequired
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
POST /webhooks/{webhook_id}/test
/webhooks/{webhook_id}/testAuthenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
Request parameters
webhook_idstringpathRequired
Responses and errors
200Successful Response
application/json
successbooleanRequired
status_codeinteger | nullOptional
response_time_msinteger | nullOptional
errorstring | nullOptional
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
422Validation Error
application/json
detailobject[]Optional
Fields in detail
Array of object.
locstring | integer[]Required
Fields in loc
Array of string | integer.
string
string.
integer
integer.
msgstringRequired
typestringRequired
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
