API Docs / Webhooks

Webhooks

Webhooks allow your application to receive real-time notifications when events occur in Tuberalytics. Instead of polling the API, register a webhook endpoint and we'll send HTTP POST requests to your URL.

Endpoints

Method Path Description
GET /api/v1/webhooks List your webhook endpoints
POST /api/v1/webhooks Create a webhook endpoint
PATCH /api/v1/webhooks/:id Update a webhook endpoint
DELETE /api/v1/webhooks/:id Delete a webhook endpoint

Event Types

Event Description
channel.analysis.completed AI channel analysis finished successfully
channel.analysis.failed AI channel analysis failed
niche.synthesis.completed Niche synthesis completed
niche.research.completed Niche research run completed
keywords.generated Keyword generation completed
competitors.discovered Competitor discovery completed
outlier.detected.niche New outlier video detected in a tracked niche
outlier.detected.competitor New outlier video from a competitor channel
outliers.weekly.niche Weekly digest: top 100 outliers from your niches
outliers.weekly.competitor Weekly digest: top 100 outliers from tracked competitors
video.new.competitor New video published by a competitor

Webhook Payload Format

All webhook deliveries are HTTP POST requests with a JSON body:

{
  "event": "channel.analysis.completed",
  "data": {
    "channel_id": 170,
    "channel_title": "Nick Saraev",
    "analysis_id": 456
  },
  "timestamp": "2026-03-30T15:30:00Z"
}

Headers

Header Description
Content-Type application/json
X-Tuberalytics-Signature HMAC-SHA256 signature for verification
X-Tuberalytics-Event Event type (e.g. channel.analysis.completed)
X-Tuberalytics-Delivery Unique delivery ID

Signature Verification

Every webhook delivery is signed with your endpoint's signing secret using HMAC-SHA256. Always verify signatures to ensure requests are from Tuberalytics.

The signature is in the X-Tuberalytics-Signature header, formatted as sha256=<hex_digest>.

Verification Examples

import hmac
import hashlib

def verify_signature(payload_body, signature_header, signing_secret):
    expected = "sha256=" + hmac.new(
        signing_secret.encode(),
        payload_body.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Retry Policy

Failed deliveries are retried with exponential backoff:

Attempt Delay
1st retry 1 minute
2nd retry 5 minutes
3rd retry 30 minutes

After 3 failed attempts, the delivery is marked as permanently failed.

Auto-disable: After 10 consecutive delivery failures across any deliveries, the webhook endpoint is automatically disabled. Re-enable it from the API or web UI after fixing the issue.


List Webhook Endpoints

GET /api/v1/webhooks

List all your registered webhook endpoints.

Example Request

curl -X GET "https://tuberalytics.com/api/v1/webhooks" \
  -H "Authorization: Bearer sk_live_your_api_key"

Example Response

{
  "data": [
    {
      "id": 1,
      "url": "https://myapp.com/webhooks/tuberalytics",
      "events": ["channel.analysis.completed", "competitors.discovered"],
      "enabled": true,
      "failure_count": 0,
      "last_triggered_at": "2026-03-30T10:00:00Z",
      "created_at": "2026-03-15T12:00:00Z"
    }
  ]
}

Create Webhook Endpoint

POST /api/v1/webhooks

Register a new webhook endpoint. The response includes the signing_secret — save it immediately, as it is never returned again.

Parameters

Parameter Type Required Description
url string Yes HTTPS endpoint URL
events array No Event types to subscribe to (defaults to all events)

Example Request

curl -X POST "https://tuberalytics.com/api/v1/webhooks" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://myapp.com/webhooks/tuberalytics", "events": ["channel.analysis.completed"]}'

Example Response (HTTP 201)

{
  "data": {
    "id": 2,
    "url": "https://myapp.com/webhooks/tuberalytics",
    "events": ["channel.analysis.completed"],
    "enabled": true,
    "failure_count": 0,
    "last_triggered_at": null,
    "created_at": "2026-03-30T15:00:00Z",
    "signing_secret": "whsec_abc123def456ghi789jkl012"
  }
}

Important: The signing_secret is only returned when the endpoint is first created. Store it securely.


Update Webhook Endpoint

PATCH /api/v1/webhooks/:id

Update a webhook endpoint's URL, events, or enabled status.

Parameters

Parameter Type Required Description
url string No New HTTPS endpoint URL
events array No New event subscriptions
enabled boolean No Enable or disable the endpoint

Example Request

curl -X PATCH "https://tuberalytics.com/api/v1/webhooks/2" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"events": ["channel.analysis.completed", "competitors.discovered"], "enabled": true}'

Example Response

{
  "data": {
    "id": 2,
    "url": "https://myapp.com/webhooks/tuberalytics",
    "events": ["channel.analysis.completed", "competitors.discovered"],
    "enabled": true,
    "failure_count": 0,
    "last_triggered_at": null,
    "created_at": "2026-03-30T15:00:00Z"
  }
}

Delete Webhook Endpoint

DELETE /api/v1/webhooks/:id

Permanently delete a webhook endpoint. Any pending deliveries will be cancelled.

Example Request

curl -X DELETE "https://tuberalytics.com/api/v1/webhooks/2" \
  -H "Authorization: Bearer sk_live_your_api_key"

Example Response

{
  "data": {
    "message": "Webhook endpoint deleted."
  }
}

Weekly Digest Events

Two digest events deliver a curated list of outlier videos every Monday at 10am UTC.

outliers.weekly.niche

Top 100 outlier videos from the past 7 days across all niches your channels belong to. Niches are deduplicated — if two of your channels share a niche, you receive one digest covering all unique niches.

Example Payload

{
  "event": "outliers.weekly.niche",
  "data": {
    "period_start": "2026-03-26",
    "period_end": "2026-04-02",
    "total_outliers": 47,
    "videos": [
      {
        "video_id": 123,
        "youtube_video_id": "abc123",
        "title": "Video Title",
        "channel_title": "Channel Name",
        "channel_id": 456,
        "niche_name": "home fitness",
        "niche_id": 15,
        "view_count": 500000,
        "average_views_ratio": 12.5,
        "published_at": "2026-03-28T10:00:00Z"
      }
    ]
  },
  "timestamp": "2026-04-02T10:00:00Z"
}

outliers.weekly.competitor

Top 100 outlier videos from the past 7 days published by your tracked competitors, ordered by average_views_ratio descending.

Example Payload

{
  "event": "outliers.weekly.competitor",
  "data": {
    "period_start": "2026-03-26",
    "period_end": "2026-04-02",
    "total_outliers": 23,
    "videos": [
      {
        "video_id": 789,
        "youtube_video_id": "xyz789",
        "title": "Competitor Video Title",
        "channel_title": "Competitor Channel",
        "channel_id": 101,
        "view_count": 250000,
        "average_views_ratio": 8.3,
        "published_at": "2026-03-29T14:00:00Z"
      }
    ]
  },
  "timestamp": "2026-04-02T10:00:00Z"
}

Videos are ordered by average_views_ratio descending and capped at 100 per digest. Both digests can be configured from the API Keys page in the web UI or via the webhooks API.