sondahub

sondahub / JSONPlaceholder alternative

A JSONPlaceholder alternative for when six resources are not enough

Still free, still no key — with 78,076 related records across seven domains, writes that are validated like a real server's and are there when you read them back, and every protocol a modern client speaks.

Why people move on from JSONPlaceholder

JSONPlaceholder is the classic free fake REST API, and for a first fetch call it is perfect: six resources — 100 posts, 500 comments, 100 albums, 5,000 photos, 200 todos, 10 users — with writes faked. Projects outgrow it when they need more data than ten users, data shaped like their own domain, errors to handle, or a protocol other than REST.

JSONPlaceholdersondahub
Records6,010 in 6 resources78,076 in 37 collections
DomainsPosts, comments, albums, photos, todos, usersE-commerce, IoT, banking, social, helpdesk, flights, a company directory
WritesFakedValidated, run through real rules, and there on the next read (a session token, no database)
Errors to handle—400, 404, 405, 409, 422 with field details; any status on demand
QueryingFilter by field, nested routesOperators, search, sorting, paging metadata, sparse fields, expand
OpenAPI documents—One per API
GraphQL—Seven schemas with introspection
gRPC-Web / Connect—A protobuf service per API, .proto files included
WebSocket / SSE / MQTT—Live streams, an echo, a broker
MCP server for AI agents—https://api.sondahub.com/mcp
Auth testing—Basic, Digest, API key, Bearer, JWT, SigV4, OAuth 2, SAML, SCIM
Chaos, rate limits, webhooks—On any endpoint, by header

Counts for JSONPlaceholder are from its own guide. Both are free; use whichever fits.

Where things are

JSONPlaceholdersondahubNote
/posts/v1/social/posts4,000 posts with author_id, hashtags, media, likes and comment counts
/posts/1/comments/v1/social/posts/1/commentsThe same nested route, paged
/comments/v1/social/comments8,000 comments, threaded through parent_id
/users/v1/social/users800 users — or the customers of the Store, Bank and Helpdesk APIs
/users/1/posts/v1/social/users/1/postsNested route
/posts?userId=1/v1/social/posts?author_id=1Filters work on every field, with operators
/todos/v1/helpdesk/ticketsThe nearest thing to a task list: tickets with a status that moves open → closed
/albums, /photos/v1/utils/image/png?w=600&h=400No albums; images are drawn on demand (PNG or SVG), and users have generated avatars

The same fetch, before and after

// before
const posts = await fetch('https://jsonplaceholder.typicode.com/posts?userId=1').then(r => r.json())

// after — the list is in .data, the paging in .meta
const { data: posts, meta } = await fetch('https://api.sondahub.com/v1/social/posts?author_id=1&limit=10')
  .then(r => r.json())
Try it
curl "https://api.sondahub.com/v1/social/posts?author_id=1&limit=3&expand=author"

Questions

Is sondahub a drop-in replacement for JSONPlaceholder?

No — the paths and field names differ (snake_case, author_id rather than userId), and lists come wrapped as {"data": [...], "meta": {...}} rather than as a bare array. The mapping above covers the usual routes; a fetch wrapper that returns .data covers the rest.

Is it free like JSONPlaceholder?

Yes: no key, no signup, CORS open. And open source under MIT, so it can run on your own machine or in CI.

Do writes persist?

On JSONPlaceholder, no: it fakes them. On sondahub, yes — for whoever sends them. It validates each write, runs the real rules and answers like a real server (201, or 422 naming each wrong field), and hands back an X-Sondahub-Session token; requests that carry it see the write. There is still no database: the state travels with the client. How.