Webhooks
Receive new articles at your own URL with webhooks. Choose your filters once, and APITube sends matching articles as HTTP POST requests.
What is a webhook?
To create a webhook, choose:
- a URL to deliver to, and
- a set of filters — the same parameters as
/v1/news/everything(language, category, source, sentiment, entities, dates, and more).
Whenever a newly indexed article matches those filters, APITube sends it to your URL with an HTTP POST.
Use cases:
- Real-time monitoring for a brand, competitor, topic, or person
- Breaking-news alerts into Slack, Telegram, or email
- Sending new articles to your application
- Triggering automations (Zapier / Make / n8n) on matching coverage
Benefits:
- Receive articles without repeatedly checking the API
- Same filtering power as
/v1/news/everything - Signed payloads (HMAC-SHA256) so you can verify authenticity
- Automatic retries with longer waits between attempts
- Full delivery logs in the dashboard
Creating a webhook
Webhooks are created and managed in the dashboard (Webhooks page):
- Click Create webhook.
- Choose the API key the deliveries are billed to.
- Enter the destination URL (HTTPS recommended — payloads contain article data).
- Build the filters with the same controls as the API Playground (leave empty to receive every new article).
- On creation you are shown the signing secret once — copy and store it. It is used to verify delivery signatures and is never shown again.
A new webhook starts with the latest articles and then sends new ones as they become available. Test it first with an api_test_ key. Test deliveries contain preview text and use no quota.
Plan limits
The number of webhooks you can have is limited by your subscription plan (counted across your whole account):
| Plan | Webhooks |
|---|---|
| Free | 1 |
| Starter | 5 |
| Basic | 5 |
| Professional | 20 |
| Corporate | 100 |
Delivery format
Each delivery is an HTTP POST to your URL:
POST https://your-app.example.com/webhook
Content-Type: application/json
X-Webhook-Signature: sha256=<hmac>
X-Webhook-Id: 42
X-Webhook-Timestamp: 1718800000{
"event": "articles.new",
"webhook_id": 1,
"delivered_at": "2026-06-19T12:00:00.000Z",
"articles": [
{
"id": 3036291250,
"title": "…",
"source": { "domain": "reuters.com" }
}
]
}Each article in articles has the same fields as /v1/news/everything. Up to 100 articles are delivered per request.
| Header | Description |
|---|---|
X-Webhook-Signature | sha256=<hmac> — HMAC-SHA256 signature (see below) |
X-Webhook-Id | ID of the webhook subscription (matches webhook_id in the request body) |
X-Webhook-Delivery-Id | Unique ID of this delivery attempt — use it to de-duplicate retries of the same batch |
X-Webhook-Timestamp | Unix timestamp (seconds) when the delivery was sent |
Return a 2xx status to confirm delivery. Any other status, or no response within 30 seconds, triggers a retry.
Verifying the signature
Every request is signed with HMAC-SHA256 over timestamp + "." + rawBody, using your webhook's signing secret. Verify it before processing the request body.
import crypto from 'node:crypto';
function verifyWebhook(secret, signature, timestamp, rawBody) {
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + rawBody)
.digest('hex');
return signature === `sha256=${expected}`;
}
app.post('/webhook', (req, res) => {
const ok = verifyWebhook(
process.env.WEBHOOK_SECRET,
req.headers['x-webhook-signature'],
req.headers['x-webhook-timestamp'],
JSON.stringify(req.body),
);
if (!ok) return res.status(401).send('Invalid signature');
const { articles } = req.body;
console.log(`Received ${articles.length} articles`);
res.status(200).send('OK');
});
import hmac
import hashlib
def verify_webhook(secret, signature, timestamp, raw_body):
expected = hmac.new(
secret.encode(),
(timestamp + '.' + raw_body).encode(),
hashlib.sha256,
).hexdigest()
return signature == f'sha256={expected}'
Retries & statuses
If delivery fails, APITube retries with the following delays:
| Attempt | Delay |
|---|---|
| 1 | 1 minute |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 12 hours |
After 5 failed attempts the delivery is marked failed. After 3 consecutive failed deliveries the webhook is automatically disabled — re-enable it from the dashboard once your endpoint is healthy.
A webhook subscription has one of three statuses:
| Status | Meaning |
|---|---|
active | Delivering matching articles |
paused | Paused by you — no deliveries until resumed |
disabled | Auto-disabled after 3 consecutive failed deliveries |
You can review every delivery (status, attempts, response code, error) in the dashboard, and re-send a delivery manually.
Managing webhooks via the API
Create webhooks in the dashboard. To view or manage existing webhooks through the API, send your key in X-API-Key.
# List your webhooks
curl -H "X-API-Key: YOUR_API_KEY" https://api.apitube.io/v1/webhooks
# Get one
curl -H "X-API-Key: YOUR_API_KEY" https://api.apitube.io/v1/webhooks/1
# Update url / filters / status (active | paused)
curl -X PATCH -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"status":"paused"}' https://api.apitube.io/v1/webhooks/1
# Delete
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" https://api.apitube.io/v1/webhooks/1The required scopes are webhooks:read (for GET) and webhooks:write (for PATCH / DELETE).
Billing
Creating or managing a webhook is free. Each delivered article costs 1 point (charged to the key the webhook was created with). Deliveries made with a test key are masked and not billed.