Overview
SocialSnap.io webhooks let you receive an HTTP POST to your own server whenever a new AI summary is generated for a channel you subscribe to — or triggered on-demand. The payload contains the full structured summary so you can pipe it into n8n, Make.com, Slack, a database, or any custom workflow. Webhooks also fire when you generate a social post via Transform Snap, delivering the formatted content immediately to your endpoint.
Real-time
Posted within seconds of a summary completing — channel or on-demand.
Signed
Every request is signed with HMAC-SHA256 so you can verify it came from us.
Full payload
The complete structured summary — every field, every section, one request.
Setup
Webhooks are available on the Builder plan. Configure your endpoint in your profile settings under the Webhook section.
- 1Navigate to Profile → Webhook.
- 2Enter your Endpoint URL — a publicly reachable HTTPS URL that accepts POST requests.
- 3Enter a Secret— a random string you choose (min 16 characters). Store it securely; you'll use it to verify the signature.
- 4Click Save, then use the Send Test button to verify your endpoint is reachable.
Events
All event types are delivered to the same webhook URL you configure in your profile. Use the event field to branch your handler logic:
summary.completedFired when a real summary finishes — either triggered automatically by a channel you subscribed to, or generated on-demand.
social_asset.generatedFired when you generate a social post via Transform Snap (X Thread, LinkedIn Post, or Newsletter Draft). The payload contains the platform, the generated content, and a reference back to the source summary.
summary.testFired when you click the "Send Test" button in your profile. The payload is a real summary but all string fields are replaced with synthetic test values so you can safely verify your endpoint without affecting production data.
Payload Schema
Every request body is a JSON object with a top-level envelope and a data object containing the full summary.
Top-level fields
| Field | Type | Description |
|---|---|---|
event | string | Event type — see Events above. |
timestamp | string (ISO 8601) | When the webhook was dispatched. |
data | object | The full summary object — see fields below. |
data fields
| Field | Type | Description |
|---|---|---|
id | string (uuid) | Unique ID of the summary. |
video_id | string | YouTube video ID (e.g. dQw4w9WgXcQ). |
video_title | string | Original title of the YouTube video. |
summary_title | string | AI-generated title for the summary. |
slug | string | null | URL slug used in the public summary link. |
url | string | null | Full public URL of the summary on SocialSnap.io. |
published_at | string (ISO 8601) | When the video was published on YouTube. |
channel_id | string (uuid) | Internal ID of the monitored channel. |
tldr | string | Short paragraph summary of the video. |
key_takeaways | string[] | Up to 7 key insights extracted from the video. |
category | string | AI-assigned topic category. |
chapters | { title, summary }[] | Major segments of the video, each titled and summarised. |
notable_quotes | { quote, speaker }[] | Memorable quotes with attributed speaker. |
glossary | { term, definition }[] | Technical terms with plain-English definitions. |
key_people | { name, role }[] | People mentioned in the video and their relevance. |
language | string (BCP 47) | Language code of the summary (e.g. en, fr, es). |
source | "channel" | "manual" | "test" | How the summary was triggered. |
created_at | string (ISO 8601) | When the summary record was created. |
Example payload — summary.completed
{
"event": "summary.completed",
"timestamp": "2026-06-06T14:32:01.000Z",
"data": {
"id": "uuid-of-the-summary",
"video_id": "dQw4w9WgXcQ",
"video_title": "The Original Video Title on YouTube",
"summary_title": "AI-Generated Summary Title",
"slug": "ai-generated-summary-title-abc123",
"url": "https://socialsnap.io/reads/ai-generated-summary-title-abc123",
"published_at": "2026-06-06T14:30:00.000Z",
"channel_id": "uuid-of-the-channel",
"tldr": "A short paragraph summarising the key point of the video.",
"key_takeaways": [
"First major insight from the video",
"Second major insight from the video"
],
"category": "Technology",
"chapters": [
{
"title": "Chapter Title",
"summary": "What this segment covers."
}
],
"notable_quotes": [
{
"quote": "Something memorable the speaker said.",
"speaker": "Speaker Name"
}
],
"glossary": [
{
"term": "Technical Term",
"definition": "Plain-English explanation."
}
],
"key_people": [
{
"name": "Person Name",
"role": "Their role or relevance in the video"
}
],
"language": "en",
"source": "channel",
"created_at": "2026-06-06T14:32:00.000Z"
}
}social_asset.generated payload
Sent when Transform Snap generates a social post. Shares the same top-level envelope (event, timestamp, data) and the same X-SocialSnap-Signature header.
| Field | Type | Description |
|---|---|---|
data.platform | "x-thread" | "linkedin" | "newsletter" | Which format was generated. |
data.content | string | The full generated text — tweets separated by --- for X threads. |
data.source.id | string (uuid) | ID of the source summary. |
data.source.slug | string | null | Slug of the source summary. |
data.source.video_title | string | Original YouTube video title. |
data.source.url | string | Public URL of the source summary on SocialSnap.io. |
{
"event": "social_asset.generated",
"timestamp": "2026-06-06T14:32:01.000Z",
"data": {
"platform": "x-thread",
"content": "🚨 87% of consumers are cutting spend...",
"source": {
"id": "uuid-of-the-summary",
"slug": "ai-generated-summary-title-abc123",
"video_title": "The Original Video Title on YouTube",
"url": "https://socialsnap.io/reads/ai-generated-summary-title-abc123"
}
}
}Signature Verification
Every request includes an X-SocialSnap-Signature header. The value is sha256=<hex> — an HMAC-SHA256 of the raw request body using the secret you configured.
timingSafeEqual / hmac.compare_digest) to prevent timing attacks.Code Examples
Minimal receiver examples that verify the signature and handle the event.
Node.js (Express)
import { createHmac } from 'crypto'
// Express example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-socialsnap-signature']
const expected = 'sha256=' + createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex')
if (signature !== expected) {
return res.status(401).send('Invalid signature')
}
const event = JSON.parse(req.body)
if (event.event === 'summary.completed') {
console.log('New summary:', event.data.url)
// your logic here
} else if (event.event === 'social_asset.generated') {
console.log('New', event.data.platform, 'post for:', event.data.source.video_title)
// your logic here
}
res.sendStatus(200)
})Python (Flask)
import hmac, hashlib
from flask import Flask, request, abort
app = Flask(__name__)
WEBHOOK_SECRET = os.environ['WEBHOOK_SECRET']
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-SocialSnap-Signature', '')
expected = 'sha256=' + hmac.new(
WEBHOOK_SECRET.encode(),
request.data,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
abort(401)
event = request.get_json()
if event['event'] == 'summary.completed':
print('New summary:', event['data']['url'])
# your logic here
elif event['event'] == 'social_asset.generated':
print('New', event['data']['platform'], 'post for:', event['data']['source']['video_title'])
# your logic here
return '', 200No-code tools
If you're using n8n, Make.com, or Zapier: create a Webhook trigger node/module, paste the URL into your SocialSnap.io profile, and set your secret. These platforms expose the raw body and headers so you can run the HMAC check in a Code node if needed — or skip verification if the endpoint is already protected.
Delivery & Retries
Webhooks are dispatched with a 10-second timeout. Your endpoint must respond with any 2xx status within that window.
If the request times out or your server returns a non-2xx response, the delivery is logged as failed. There are currently no automatic retries — use the Send Test button in your profile to re-trigger a delivery for debugging purposes.
Keep your handler fast — acknowledge the request immediately with a 200 and process the payload asynchronously if needed.
Testing
Use the Send Test button in Profile → Webhook to POST a summary.test event to your endpoint. The payload is structurally identical to a real summary.completed event and is fully signed — so your verification code runs against it exactly as it would in production.
For local development, expose your server with a tunnel tool like ngrok or localtunnel, then paste the tunnel URL as your endpoint.
Ready to build? Upgrade to Builder.
Webhooks, priority processing, and early access to new features.
View Pricing