Bloss Docs

Webhooks

Get Discord or HTTP alerts when videos cross view targets, links go dead, creators stop posting or handles change, plus a daily performance report.

DevelopersBrand admins

Webhooks let Bloss tell you when something happens in your brand. Each webhook goes either to a Discord channel (as a formatted message) or to your own URL (as JSON).

Set up a webhook

  1. Go to SettingsIntegrationsWebhooks and click Add integration.
  2. Choose the Platform: Discord (paste a Discord channel webhook URL) or Custom (any HTTPS endpoint you control).
  3. Pick the Video platforms the webhook covers — Instagram, TikTok, YouTube, Facebook.
  4. Turn on the alerts you want (below) and set their targets.
  5. Click Send test to receive a sample, then save.

You can edit, pause (the Enabled switch) or delete a webhook at any time. Any brand admin can manage webhooks.

Alerts

AlertFires whenSettingstype
Video view thresholdA video reaches the view count you set (default 10,000). It fires on the crossing, once per video.View threshold, fields to includevideo_view_threshold
Low-view alertA video is still below your view target more than 24 hours after it was posted.View target, fields to includevideo_view_underperform
Inactive creator alertA creator hasn't posted for longer than your window and their recent videos are all under your view target. One alert per creator; it can fire again after they post.Inactive for (hours, default 72), view target (default 1,000), recent videos (default 5)creator_inactive
Dead link alertA tracked video's link is confirmed dead — deleted by the creator, set to private, or removed or archived. A video that's only missing from the creator's profile feed doesn't trigger it.Fields to includevideo_unavailable
Handle change alertA creator's handle stops working — either they renamed the account (the alert includes the new handle) or the account is gone.—creator_handle_changed
Daily performance reportOnce a day, a summary of yesterday in your brand's timezone: views, likes, comments, saves, shares, videos posted, creators who posted, and the top videos.—daily_report

Selectable fields to include for video alerts: creator name, platform, view count, video URL, caption, thumbnail URL and posted date.

Delivery

  • Bloss checks for new alerts every hour; daily reports are sent once per day after your brand's data for that day is complete.
  • Each alert is sent once. A video alert is identified by the webhook, video, alert type and threshold — changing the threshold lets a video alert again.
  • Requests are POST with Content-Type: application/json and a 10-second timeout. Any 2xx response counts as delivered.
  • If your endpoint times out or returns a non-2xx status, the alert isn't marked as sent, so Bloss tries again on the next hourly run.

Requests aren't signed

Custom webhook requests don't carry a signature or secret header. Use a long, unguessable URL (for example with a random token in the path), accept only POST, and treat the payload as a notification — fetch anything sensitive from the Campaign API instead.

Custom payloads

Every payload has a type and a triggeredAt ISO timestamp. Video alerts include only the fields you selected (plus videoId).

{
  "type": "video_view_threshold",
  "brand": { "id": "brd_123", "name": "Acme Skincare" },
  "threshold": 10000,
  "video": {
    "videoId": "vid_456",
    "creatorName": "Maya Lee",
    "platform": "tiktok",
    "views": 10342,
    "videoUrl": "https://www.tiktok.com/@maya/video/123",
    "caption": "My morning routine",
    "thumbnailUrl": "https://…",
    "postedAt": "2026-10-10T15:04:00.000Z"
  },
  "triggeredAt": "2026-10-12T09:00:12.000Z"
}

The low-view alert has the same shape with "type": "video_view_underperform".

Was this page helpful?

Last reviewed Oct 13, 2026

Campaign pairs (per-post rows) GET

One row per video *pair* — a creator's post, or the 1–3 cross-posted videos that share a single payout — for the given cycles. This is the layer underneath `GET /campaign/summary` and `GET /campaign/tags`: per-pair `totalSpend` and `views` sum to the campaign figures those endpoints report for the same cycles. Each row carries the creator, the pair's tag ids, its money (`basePay` + `cpmBonus` = `totalSpend`), and a `videos` array with the platform, post URL, posted-at, and engagement of every video in the pair. Engagement comes from the latest snapshot inside the cycle window — the same rows the campaign totals count. A video with no in-cycle snapshot has `snapshotDate: null` and zeroed metrics, and is not counted by any campaign endpoint; `countedVideos` is how many of the pair's videos did count. `tagIds` filters which *pairs* come back (pair tags carry the money); each returned pair still reports all of its own videos. `groupIds` filters by the pair's **creator** instead — the creator groups from `GET /groups`. Filters compose as an AND (`groupIds` plus `tagIds` means both), while ids *within* one filter are ANY. Every row also carries `creator.groupIds`, so one unfiltered pass can be bucketed by group client-side. Results are ordered by `(updatedAt, pairId)` ascending and paged with the opaque `nextCursor`. Pass `updatedSince` with the largest `updatedAt` you have already stored to pull only what changed since — `updatedAt` moves whenever the pair is re-paired, re-assigned, or its payout is recalculated (which is what a view refresh triggers).

Was this page helpful?

Use this page with AI

View as MarkdownAsk ChatGPTAsk Claude

On this page