APIs / Social
A social network: users, posts, comments, likes and follows — the GraphQL one.
Eight hundred users, four thousand posts, eight thousand comments and the likes and follows between them. Deeply related, which is what GraphQL is for: a user, their posts, each post’s comments and their authors in one query. 25,800 records in all.
In Sonda: Import → From a URL with the OpenAPI address and the whole API lands as a project, one request per operation with example bodies. No keys, no headers to add. More on each protocol.
_note and X-Sondahub-Write: simulated. A GET afterwards will not find what you wrote.curl https://api.sondahub.com/v1/social
Every list answers { "data": [...], "meta": { "page", "limit", "total", "pages" } } with X-Total-Count and Link headers (next, prev, first, last). These options work on every collection and every nested route:
| Option | Meaning | Example |
|---|---|---|
page, limit | Paging, 1-based; limit 1–200, default 20. offset works too. | ?page=3&limit=50 |
sort | Comma list of fields, - for descending. Default id here. | ?sort=-id,id |
field=value | Equals. Booleans as true/false, null for missing. | ?id=1 |
_ne _gt _gte _lt _lte | Not equal and comparisons, on numbers, dates and strings. | ?id_gt=10 |
_like | Contains, case-insensitive. | ?username_like=an |
_in | Any of a comma list. | ?id_in=1,2,3 |
_null | true: missing; false: present. | ?email_null=true |
a.b=value | Inside a JSON field, dotted. | ?media.kind=… |
q | Search across the text fields. | ?q=alpine |
fields | Only these fields back. | ?fields=id,username |
expand | Embed related records. | ?expand=posts,comments |
A name that is not a field answers 400 and lists the fields. Writes answer 422 with one line per problem, 404 for a missing id, 405 with an Allow header for a verb a route does not take.
Members. 800 records — the file.
| Field | Type | Notes |
|---|---|---|
idread-only | int | Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed. |
created_atread-only | datetime | When the record was created (ISO 8601, UTC). |
updated_atread-only | datetime | When the record last changed. |
usernamerequired | string | Unique handle. |
display_namerequired | string | |
email | string | |
bio | text | |
avatar_url | string | A generated SVG served by the hub. |
location | string | |
website | string | |
verified | bool | |
private | bool | |
followers_countread-only | int | |
following_countread-only | int | |
posts_countread-only | int | |
joined_at | datetime |
Relations: posts → the posts whose author_id is this user; comments → the comments whose author_id is this user; likes → the likes whose user_id is this user; followers → the follows whose followee_id is this user; following → the follows whose follower_id is this user. Use ?expand=posts,comments,likes,followers,following to embed them, or the routes below.
curl "https://api.sondahub.com/v1/social/users?limit=3"
curl https://api.sondahub.com/v1/social/users/1
curl "https://api.sondahub.com/v1/social/users/1/posts?limit=5"
curl -X POST https://api.sondahub.com/v1/social/users \
-H "Content-Type: application/json" \
-d '{"username":"camila_fernandez","display_name":"A display name"}'
curl -X PATCH https://api.sondahub.com/v1/social/users/1 \
-H "Content-Type: application/json" \
-d '{"username":"Changed username"}'
curl -X DELETE https://api.sondahub.com/v1/social/users/1
What people write. hashtags is an array; filter with ?hashtags_like=coffee. 4,000 records — the file.
posts_count.| Field | Type | Notes |
|---|---|---|
idread-only | int | Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed. |
created_atread-only | datetime | When the record was created (ISO 8601, UTC). |
updated_atread-only | datetime | When the record last changed. |
author_idrequired | int → users | |
bodyrequired | text | |
hashtags | json string[] | |
media | json { kind, url, alt? }[] | |
visibility | enum | public followers private |
reply_to_id | int → posts | Set when the post is a reply. |
likes_countread-only | int | |
comments_countread-only | int | |
reposts_countread-only | int | |
language | string | |
published_at | datetime | |
edited_at | datetime |
Relations: author → one user through author_id; reply_to → one post through reply_to_id; comments → the comments whose post_id is this post; likes → the likes whose post_id is this post. Use ?expand=author,comments,likes,reply_to to embed them, or the routes below.
curl "https://api.sondahub.com/v1/social/posts?visibility=followers&expand=author&limit=3"
curl https://api.sondahub.com/v1/social/posts/1?expand=author
curl "https://api.sondahub.com/v1/social/posts/1/comments?limit=5"
curl -X POST https://api.sondahub.com/v1/social/posts \
-H "Content-Type: application/json" \
-d '{"author_id":1,"body":"A body","visibility":"public","language":"en"}'
curl -X PATCH https://api.sondahub.com/v1/social/posts/1 \
-H "Content-Type: application/json" \
-d '{"visibility":"followers"}'
curl -X DELETE https://api.sondahub.com/v1/social/posts/1
Comments on posts; a comment can answer another comment through parent_id. 8,000 records — the file.
comments_count; DELETE lowers it.| Field | Type | Notes |
|---|---|---|
idread-only | int | Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed. |
created_atread-only | datetime | When the record was created (ISO 8601, UTC). |
updated_atread-only | datetime | When the record last changed. |
post_idrequired | int → posts | |
author_idrequired | int → users | |
parent_id | int → comments | |
bodyrequired | text | |
likes_countread-only | int | |
flagged | bool |
Relations: post → one post through post_id; author → one user through author_id; parent → one comment through parent_id; replies → the comments whose parent_id is this comment. Use ?expand=post,author,parent,replies to embed them, or the routes below.
curl "https://api.sondahub.com/v1/social/comments?expand=post&limit=3"
curl https://api.sondahub.com/v1/social/comments/1?expand=post
curl "https://api.sondahub.com/v1/social/comments/1/replies?limit=5"
curl -X POST https://api.sondahub.com/v1/social/comments \
-H "Content-Type: application/json" \
-d '{"post_id":1,"author_id":1,"body":"A body"}'
curl -X PATCH https://api.sondahub.com/v1/social/comments/1 \
-H "Content-Type: application/json" \
-d '{"body":"Changed body"}'
curl -X DELETE https://api.sondahub.com/v1/social/comments/1
A user liking a post. POST one to like; DELETE it to unlike. 8,000 records — the file.
already_liked) and bumps the post’s likes_count; DELETE lowers it.| Field | Type | Notes |
|---|---|---|
idread-only | int | Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed. |
created_atread-only | datetime | When the record was created (ISO 8601, UTC). |
updated_atread-only | datetime | When the record last changed. |
user_idrequired | int → users | |
post_idrequired | int → posts |
Relations: user → one user through user_id; post → one post through post_id. Use ?expand=user,post to embed them, or the routes below.
curl "https://api.sondahub.com/v1/social/likes?expand=user&limit=3"
curl https://api.sondahub.com/v1/social/likes/1?expand=user
curl -X POST https://api.sondahub.com/v1/social/likes \
-H "Content-Type: application/json" \
-d '{"user_id":1,"post_id":1}'
curl -X PATCH https://api.sondahub.com/v1/social/likes/1 \
-H "Content-Type: application/json" \
-d '{}'
curl -X DELETE https://api.sondahub.com/v1/social/likes/1
follower_id follows followee_id. 5,000 records — the file.
pending; active follows move both users’ counters.| Field | Type | Notes |
|---|---|---|
idread-only | int | Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed. |
created_atread-only | datetime | When the record was created (ISO 8601, UTC). |
updated_atread-only | datetime | When the record last changed. |
follower_idrequired | int → users | |
followee_idrequired | int → users | |
status | enum | active pending blocked |
notifications | bool |
Relations: follower → one user through follower_id; followee → one user through followee_id. Use ?expand=follower,followee to embed them, or the routes below.
curl "https://api.sondahub.com/v1/social/follows?status=pending&expand=follower&limit=3"
curl https://api.sondahub.com/v1/social/follows/1?expand=follower
curl -X POST https://api.sondahub.com/v1/social/follows \
-H "Content-Type: application/json" \
-d '{"follower_id":1,"followee_id":1,"status":"active"}'
curl -X PATCH https://api.sondahub.com/v1/social/follows/1 \
-H "Content-Type: application/json" \
-d '{"status":"pending"}'
curl -X DELETE https://api.sondahub.com/v1/social/follows/1
The same stream two ways: the world's own activity, one tick a second, generated for your connection alone. Both push JSON text messages; SSE names each one with event: and numbers it with id:. ?topics=a,b narrows either.
| Topic | What arrives | How often |
|---|---|---|
posts | A new post from one of the seed users. | 5 s |
likes | Someone liking something. | 2 s |
wss://api.sondahub.com/v1/social/ws?topics=posts
> {"type":"hello","api":"social","topics":[…],"subscribed":[…]}
> {"type":"event","topic":"posts","api":"social","ts":"…","data":{…}}
< {"type":"subscribe","topics":["posts"]} # narrow to some topics
< {"type":"ping"} # → {"type":"pong"}
< anything else # → echoed back as {"type":"echo"}
curl -N "https://api.sondahub.com/v1/social/events?topics=posts"
retry: 3000
id: 1
event: posts
data: {"type":"event","topic":"posts",…}
One endpoint, https://api.sondahub.com/v1/social/graphql: POST {"query", "variables"} or GET ?query=. Introspection is on, so Sonda's GraphQL mode loads the schema; the SDL is a click away. Every collection is a paged query with the same filter, sort and q options as REST (operators as suffixes: price_lt), a by-id query, relation fields both ways, and create, update, replace and delete mutations — simulated like every write, with the note in extensions.
curl https://api.sondahub.com/v1/social/graphql -H "Content-Type: application/json" -d '{"query": "{ posts(limit: 3, sort: \"-id\", filter: { visibility: public }) { total data { id author_id body visibility author { username } comments(limit: 2) { id } } } }"}'
{
posts(limit: 3, sort: "-id", filter: { visibility: public }) {
total
data {
id author_id body visibility
author { username }
comments(limit: 2) { id }
}
}
}