Tinylytics + n8n
Use n8n with Tinylytics through the same building blocks every other HTTP client uses: outbound webhooks and the API. There is no official Tinylytics n8n community node yet. You wire the built-in Webhook, HTTP Request, and Code nodes yourself.
What works today
| Goal | How |
|---|---|
| React when a site goes down or recovers | Tinylytics webhook → n8n Webhook trigger (monitor_down, monitor_up) |
| React to live hits, kudos, or custom events | Tinylytics webhook → n8n Webhook trigger (new_hit, new_kudo, new_event) |
| React when an AI insight is generated | Tinylytics webhook → n8n Webhook trigger (new_insight) |
| React to content-monitoring issues | Tinylytics webhook → n8n Webhook trigger (content_issue) |
| Pull analytics on a schedule | n8n Schedule + HTTP Request against /api/v1 |
| Verify webhook authenticity | HMAC over the raw body using X-Signature |
Webhooks require an active paid subscription. API keys are available from Account Settings → API Access. Prefer webhooks over tight polling when you can — API requests are rate limited.
Sample workflows
Import these into n8n (⋯ menu → Import from File), then follow the sticky notes in each workflow.
| Workflow | Download | What it does |
|---|---|---|
| Receive webhooks | receive-webhooks.json | Verifies X-Signature, routes core webhook events, formats a message field you can send onward |
| Daily top paths | daily-top-paths.json | Calls GET /sites/:id/hits?grouped=true&group_by=path for yesterday and builds a short summary |
| Poll uptime | poll-uptime.json | Calls GET /sites/:id/uptime on a timer; prefer webhooks for real downtime alerts |
The sample workflows stop at a formatted message (or equivalent). Connect Slack, email, Discord, Linear, or any other n8n node yourself — Tinylytics does not ship those credentials.
1. Receive Tinylytics webhooks in n8n
Requirements
- Paid Tinylytics plan
- An n8n instance with a public HTTPS URL (Tinylytics blocks localhost and private network URLs)
- Webhook platform set to Generic (not Discord)
- Wrap content left off for the sample expressions
If you only need Discord downtime embeds, Tinylytics already has a native Discord webhook platform — you do not need n8n for that path.
Steps
- Import receive-webhooks.json (or recreate the flow below).
- Open the Tinylytics Webhook node, activate the workflow, and copy the Production URL.
- In Tinylytics go to Account Settings → Webhooks, create a webhook with that URL, select the event types you want, and save.
- Copy the signing secret into the Verify Signature Code node (
SIGNING_SECRET). - Use Send Test on the webhook edit screen. You should see a successful delivery and a workflow execution in n8n.
Signature verification
Tinylytics signs the exact JSON body with your webhook signing secret and sends:
X-Signature: sha256=<hex HMAC SHA-256 digest>
Also sent: X-Tinylytics-Event, X-Tinylytics-Delivery, X-Tinylytics-Timestamp.
In n8n:
- Enable Raw Body on the Webhook node (required — the signature is over the raw bytes, not re-serialized JSON).
- Verify with a Code node using the binary raw body, for example:
const crypto = require('crypto');
const SIGNING_SECRET = 'your-signing-secret';
const headers = $input.item.json.headers || {};
const signature = String(headers['x-signature'] || '');
const rawBody = await this.helpers.getBinaryDataBuffer(0, 'data');
const expected = 'sha256=' + crypto.createHmac('sha256', SIGNING_SECRET).update(rawBody).digest('hex');
const sigBuf = Buffer.from(signature);
const expBuf = Buffer.from(expected);
if (sigBuf.length !== expBuf.length || !crypto.timingSafeEqual(sigBuf, expBuf)) {
throw new Error('Invalid Tinylytics webhook signature');
}
return { json: $input.item.json.body };
Treat deliveries as at-least-once. Store X-Tinylytics-Delivery, or hit.id / kudo.uid / analytics_event.id / insight.id / check.id, if duplicate handling matters.
Full payload shapes are documented in Webhooks.
Event types (core)
| Event | When it fires |
|---|---|
monitor_down |
Uptime monitor reports the site down |
monitor_up |
Uptime monitor reports recovery |
new_hit |
An accepted live hit (script, pixel, or API create/batch) |
new_kudo |
An accepted browser kudo, API kudo, or verified Webmention like |
new_event |
An accepted custom analytics event (script or API create/batch) |
new_insight |
A new AI insight record is created |
content_issue |
Content monitoring records a new/changed broken link or mixed content issue |
Ignored paths, ignored visitors, spam-suppressed writes, imports, seeds, and similar non-live writes do not emit hit/kudo/custom-event webhooks. See Webhooks.
2. Call the Tinylytics API from n8n
Auth
Authorization: Bearer tly-ro-your-api-key
Accept: application/json
Use a read-only key (tly-ro-...) for GET workflows. Use a full-access key (tly-fa-...) only when you intentionally write hits, events, kudos, signals, sites, or groups.
Create keys under Account Settings → API Access. Base URL: https://tinylytics.app/api/v1.
Smoke test
HTTP Request node:
- Method:
GET - URL:
https://tinylytics.app/api/v1/me - Header:
Authorization: Bearer tly-ro-...
A valid key returns HTTP 200 with your account payload.
Useful read endpoints for automation
| Endpoint | Notes |
|---|---|
GET /me |
Validate the key |
GET /sites |
List sites and ids |
GET /sites/:id/hits |
Raw or grouped hits (grouped=true, `group_by=path\ |
GET /sites/:id/kudos |
Kudos list |
GET /sites/:id/leaderboard |
All-time path leaderboard |
GET /sites/:id/uptime |
Subscription + uptime enabled on the site |
GET /sites/:id/content |
Subscription + content monitoring |
GET /sites/:id/insights |
Subscription |
GET /sites/:id/signals |
Subscription + insights enabled on the site |
Date query params use YYYY-MM-DD. Analytics ranges default to UTC day boundaries; pass time_zone=user to use your account timezone. Details: API docs.
Example: yesterday’s top paths
GET https://tinylytics.app/api/v1/sites/SITE_ID/hits
?grouped=true
&group_by=path
&start_date=YYYY-MM-DD
&end_date=YYYY-MM-DD
&time_zone=user
&per_page=10
That is what daily-top-paths.json calls. Grouped-by-path rows include views (and unique_views when unique hits are enabled).
What is not available
Be explicit about gaps so you do not build workflows that can never fire:
| Missing today (core product) | Workaround |
|---|---|
| Official Tinylytics n8n node / OAuth app | Use Webhook + HTTP Request as documented here |
| GET list endpoint for custom analytics events | Events are write-only via the API (POST /sites/:id/events); use the new_event webhook for push |
| Webhook when a scheduled email report is sent | No equivalent push event |
| Native Slack webhook platform | Send Generic webhooks to n8n, then use n8n’s Slack node |
Troubleshooting
| Problem | What to check |
|---|---|
| Tinylytics rejects the webhook URL | URL must be public HTTP(S). Localhost / private IPs are blocked |
| No deliveries | Paid plan active? Webhook active? Event type selected? |
| Signature always fails | Raw Body enabled? Secret pasted correctly? Verify against raw bytes, not JSON.stringify(body) |
| Test works, live hits do not | Hit may be ignored, spam-suppressed, imported, or otherwise non-live — see Webhooks |
API 401 |
Wrong or revoked key; header must be Authorization: Bearer … |
API 403 on uptime/insights/content |
Active subscription required; some features must also be enabled on the site |
Uptime poll returns 404 |
Uptime is not enabled for that site |
| Discord-shaped payload in n8n | Use the Generic webhook platform for n8n |