Skip to content

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):

  1. Click Create webhook.
  2. Choose the API key the deliveries are billed to.
  3. Enter the destination URL (HTTPS recommended — payloads contain article data).
  4. Build the filters with the same controls as the API Playground (leave empty to receive every new article).
  5. 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.
TIP

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):

PlanWebhooks
Free1
Starter5
Basic5
Professional20
Corporate100

Delivery format ​

Each delivery is an HTTP POST to your URL:

http
POST https://your-app.example.com/webhook
Content-Type: application/json
X-Webhook-Signature: sha256=<hmac>
X-Webhook-Id: 42
X-Webhook-Timestamp: 1718800000
json
{
    "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.

HeaderDescription
X-Webhook-Signaturesha256=<hmac> — HMAC-SHA256 signature (see below)
X-Webhook-IdID of the webhook subscription (matches webhook_id in the request body)
X-Webhook-Delivery-IdUnique ID of this delivery attempt — use it to de-duplicate retries of the same batch
X-Webhook-TimestampUnix 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.

javascript
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');
});
python
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:

AttemptDelay
11 minute
25 minutes
330 minutes
42 hours
512 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:

StatusMeaning
activeDelivering matching articles
pausedPaused by you — no deliveries until resumed
disabledAuto-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.

bash
# 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/1

The 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.