One endpoint. Give it a public post URL, get normalized engagement metrics as JSON. No signup, no API key.
Pulse is free right now — /metrics needs no payment, no key, no account. (Pulse also speaks x402, so an agent can pay per call in USDC if billing is ever enabled — but it's off.)
curl "https://pulse.walls.sh/metrics?url=https://www.youtube.com/watch?v=xWnqY2Mav4s"
{ "url": "https://www.youtube.com/watch?v=xWnqY2Mav4s", "platform": "youtube", "contentId": "xWnqY2Mav4s", "postType": "youtube", "views": 24772, "likes": 837, "comments": null, "viewsEstimated": false, "publishedAt": "2026-06-07T17:00:38.000Z", "title": "I Built Two Apps That Make $120K/Month", "author": "Starter Story", "thumbnail": "https://i.ytimg.com/vi/xWnqY2Mav4s/maxresdefault.jpg", "fetchedAt": "2026-06-08T21:00:00.000Z" }
| Name | Required | Description |
|---|---|---|
| url | yes | A public post URL on a supported platform. Share-style short links (vm.tiktok.com/…, tiktok.com/t/…, t.co/…) are resolved automatically; the response's url is the canonical post URL they pointed at. |
| Field | Type | Notes |
|---|---|---|
| platform | string | youtube · x · tiktok · bluesky · instagram · threads · linkedin |
| views | number | null | Real where the platform exposes it; otherwise estimated (see viewsEstimated) or null. |
| likes | number | null | Null when the platform hides it. |
| comments | number | null | Null when the platform hides it. |
| shares | number | null | Reshares — X retweets, TikTok shares, Bluesky reposts. Null where the platform doesn't expose it. |
| viewsEstimated | boolean | True when views was estimated from likes rather than read directly. |
| publishedAt | string | null | ISO-8601 publish date. |
| title | string | null | Post title / caption (truncated). |
| author | string | null | Channel / handle (e.g. @nasa). |
| thumbnail | string | null | A representative image URL for the post. |
| HTTP | error | Meaning |
|---|---|---|
| 400 | url_required / bad_url / unsupported_url | Missing, malformed, or unrecognized URL. |
| 402 | — | Payment required (x402), only if billing is on. Pay and retry; clients do this automatically. |
| 404 | content_unavailable | The post is deleted, private, or region-locked — not a server error. |
| 422 | login_required | This platform (Instagram/Threads/LinkedIn) only serves a logged-out wall to our reader — can't read it without a session. |
| 429 | rate_limited | Too many lookups from your IP this minute. Respect Retry-After and retry. Every response carries RateLimit-Limit / -Remaining / -Reset so you can self-throttle before hitting this. |
| 502 | fetch_failed | Upstream platform fetch failed; safe to retry. |
Account-level metrics from a profile URL — followers, following, post count, verified, avatar.
Live for YouTube (subscribers come abbreviated, e.g. "29.8M" → parsed), TikTok
(exact counts + total hearts), Instagram (exact counts), X (followers,
following, post count), and Bluesky (exact counts). Threads / LinkedIn profiles need a
login → login_required.
The growth curve of a post or a profile. Every fresh /metrics fetch records a
{ t, views, likes, comments } snapshot, and every fresh /profile fetch records
{ t, followers, posts } — so repeat lookups build a series over time. Returns
{ url, platform, kind, count, points }. An empty series just means the URL hasn't been fetched yet.
Polling? Add since=<ISO-8601 or unix ms> to get only the points after that moment —
the delta, not the whole series.
Need a whole set at once? Pass repeated url params (or a comma-separated
urls= list, max 50) and get them all in one request. Mixed batches welcome —
post URLs return post metrics, profile URLs return profile metrics. Order is preserved; each
item is either a metrics object or { url, error } — one bad URL never fails the batch.
{ "count": 2, "results": [ { "platform": "youtube", "views": 25275, … }, { "url": "…", "error": "content_unavailable" } ] }
Pulse is built to be found and used by agents: