API Reference
Webhooks
Webhooks let your application receive real-time HTTP callbacks when events occur in your Outfame account. Instead of polling the API, register a URL and Outfame will send a POST request with event data as it happens.
Scope required —
webhooks:manage
Events
| Event | Description | Trigger |
|---|---|---|
account.growth_milestone | Account reached a follower milestone (100, 500, 1K, 5K, 10K, etc.). | Follower count crosses a milestone threshold. |
account.status_changed | Account status transitioned (e.g., setup to active, active to paused). | Any status change on a connected account. |
account.flagged | Account was flagged for unusual activity or a potential issue. | Outfame detects a risk that requires attention. |
engagement.daily_summary | End-of-day summary of all engagement actions performed. | Sent daily at 23:55 UTC for each active account. |
targeting.suggestions_ready | New AI targeting suggestions are available. | AI model generates new recommendations (typically weekly). |
billing.payment_succeeded | A subscription payment was processed successfully. | Recurring or one-time payment completes. |
billing.payment_failed | A payment attempt failed. | Card declined, insufficient funds, etc. |
Create a webhook
POST /v1/webhooksBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The HTTPS endpoint to receive webhook events. |
events | string[] | Yes | Array of event types to subscribe to. Use ["*"] for all events. |
description | string | No | Human-readable description for this webhook. |
metadata | object | No | Arbitrary key-value pairs for your reference. |
Request
curl -X POST https://api.outfame.com/v1/webhooks \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/outfame",
"events": [
"account.growth_milestone",
"engagement.daily_summary",
"account.flagged"
],
"description": "Production growth notifications"
}'Response 201 Created
{
"id": "wh_4nRtYuIo",
"url": "https://yourapp.com/webhooks/outfame",
"events": [
"account.growth_milestone",
"engagement.daily_summary",
"account.flagged"
],
"description": "Production growth notifications",
"signing_secret": "whsec_5f8a2b3c4d5e6f7g8h9i0j...",
"active": true,
"created_at": "2026-02-09T14:30:00Z"
}Important — The
signing_secretis only returned on creation. Store it securely; you will need it to verify webhook signatures.
List webhooks
GET /v1/webhooksRequest
curl https://api.outfame.com/v1/webhooks \
-H "Authorization: Bearer sk_live_your_api_key"Response
{
"data": [
{
"id": "wh_4nRtYuIo",
"url": "https://yourapp.com/webhooks/outfame",
"events": ["account.growth_milestone", "engagement.daily_summary", "account.flagged"],
"description": "Production growth notifications",
"active": true,
"last_delivery_at": "2026-02-09T12:00:00Z",
"last_delivery_status": 200,
"created_at": "2026-02-09T14:30:00Z"
}
]
}Delete a webhook
DELETE /v1/webhooks/:idRequest
curl -X DELETE https://api.outfame.com/v1/webhooks/wh_4nRtYuIo \
-H "Authorization: Bearer sk_live_your_api_key"Response 200 OK
{
"id": "wh_4nRtYuIo",
"deleted": true
}Webhook payload
Every webhook delivery is a POST request with a JSON body following this structure:
{
"id": "evt_xYz789AbC",
"type": "account.growth_milestone",
"created_at": "2026-02-09T14:30:00Z",
"data": {
"account_id": "acc_7Gx2kLm9Qr",
"instagram_username": "yourhandle",
"milestone": 15000,
"previous_milestone": 10000,
"current_followers": 15023,
"days_since_last_milestone": 42
}
}Event-specific payloads
engagement.daily_summary
{
"id": "evt_aBc123DeF",
"type": "engagement.daily_summary",
"created_at": "2026-02-09T23:55:00Z",
"data": {
"account_id": "acc_7Gx2kLm9Qr",
"date": "2026-02-09",
"actions": {
"likes": 148,
"follows": 58,
"comments": 19,
"story_views": 195
},
"total_actions": 420,
"new_followers": 47,
"new_unfollowers": 3,
"net_growth": 44,
"engagement_rate": 4.21,
"avg_quality_score": 0.86
}
}account.flagged
{
"id": "evt_gHi456JkL",
"type": "account.flagged",
"created_at": "2026-02-09T10:15:00Z",
"data": {
"account_id": "acc_7Gx2kLm9Qr",
"flag_type": "unusual_activity",
"severity": "warning",
"message": "Higher than normal unfollow rate detected. Engagement has been automatically reduced.",
"recommended_action": "Review your targeting configuration and consider narrowing filters."
}
}Signature verification
Every webhook request includes an X-Outfame-Signature header containing an HMAC-SHA256 signature. Always verify this signature to ensure the request is genuine.
Verification algorithm
- Extract the
X-Outfame-Signatureheader value. - Extract the
X-Outfame-Timestampheader value. - Concatenate:
timestamp + "." + raw_body - Compute HMAC-SHA256 using your webhook's
signing_secret. - Compare the computed signature with the header value (use constant-time comparison).
Node.js
import crypto from "crypto";
function verifyWebhookSignature(payload, signature, timestamp, secret) {
const signedPayload = timestamp + "." + payload;
const expected = crypto
.createHmac("sha256", secret)
.update(signedPayload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler
app.post("/webhooks/outfame", (req, res) => {
const signature = req.headers["x-outfame-signature"];
const timestamp = req.headers["x-outfame-timestamp"];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
timestamp,
process.env.OUTFAME_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}
// Process the event
const event = req.body;
console.log("Received:", event.type);
res.status(200).json({ received: true });
});Python
import hmac
import hashlib
def verify_signature(payload: str, signature: str, timestamp: str, secret: str) -> bool:
signed_payload = f"{timestamp}.{payload}"
expected = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Retry policy
If your endpoint returns a non-2xx status code or times out, Outfame retries the delivery using exponential backoff.
| Attempt | Delay after failure |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
After 3 failed attempts, the delivery is marked as failed. You can view failed deliveries in the dashboard under Settings → Webhooks → Delivery history.
If an endpoint fails consistently (10+ consecutive failures across any events), the webhook is automatically disabled and you receive an email notification.
Best practices
- Respond quickly — Return a
200within 5 seconds. Process the event asynchronously. - Handle duplicates — Use the
idfield to deduplicate. Events may be delivered more than once. - Verify signatures — Always validate
X-Outfame-Signaturebefore processing. - Check timestamps — Reject events with timestamps older than 5 minutes to prevent replay attacks.
- Use HTTPS — Webhook URLs must use HTTPS. HTTP endpoints are rejected.
Error codes
| Status | Code | Description |
|---|---|---|
400 | invalid_url | URL must be a valid HTTPS endpoint. |
400 | invalid_events | One or more event types are not recognized. |
409 | duplicate_url | A webhook with this URL already exists. |
403 | webhook_limit_reached | Maximum webhook limit reached for your plan (Basic: 2, Pro: 10, Turbo: 50). |