Brought to you by Yaro67Log in · Register
Rocoto
Make it yours · Post it loud

Rocoto API

Version 1 · read-only · JSON

Build apps, widgets and sites that show Rocoto's content to people. The API gives you the posts, comments, pathways and profiles that the key's owner could see on the site, as plain JSON.

Attribution is required

If you use the Rocoto API, or anything you get from it, in a website, app, widget or any other project, you must credit Rocoto and link to the site's official address, https://www.rocoto.space. Put the credit where people can see it: next to the content you show, or on your app's About or credits screen. For example:

Powered by Rocoto - https://www.rocoto.space

Link to the official address above, not to a copy or mirror, and do not suggest that Rocoto made, runs or endorses your project. If you break this rule, or the other rules on this page, your keys may be switched off without notice. Making or using a key means you accept this condition.

No bots. No scrapers.

Bots, scrapers and any other automated collecting are banned. The API exists so that an app or site can show Rocoto's content to a person who asked to see it, at that moment. You may not use the API, a key, or the website itself to:

  • run a bot, crawler, spider or scraper, or any program that fetches content on its own schedule rather than because a person asked for it;
  • copy, download in bulk, archive, mirror, index or re-publish Rocoto's posts, comments, pictures, files or profiles;
  • build a dataset, a search index, a database or a backup of Rocoto's content, or use anything from Rocoto to train, test or feed an AI or machine-learning model;
  • work around the limits: several keys or accounts for one project, shared keys, rotating addresses, a false User-Agent, or asking again and again after a limit has been reached;
  • collect people's names, pictures or other details for a list, profiling, advertising, spam or sale.

This is a condition of getting a key, you accept it when you make one, and it is part of Rocoto's Terms of Use. A key that breaks it is switched off, the account that made it can be locked or deleted, and Rocoto may take the further steps the law allows, including a claim for damages. Rocoto's content belongs to the people who posted it.

To keep the rule honest the API also defends itself. Every key gets a daily share of 1,000 requests and 2,000 items, which is plenty for an app that shows content and far too little to copy the site; a key that keeps asking after it is used up is switched off automatically; and programs that identify as scrapers, crawlers or automated browsers, or send no User-Agent at all, are refused. Send a User-Agent that names your app, for example MyApp/1.0 (+https://example.com).

Quick start

  1. Log in, then open Settings → Developer API and make a key. It looks like rk_... and is shown once, so copy it right away.
  2. Send it with every request, in the Authorization header.
curl -H "Authorization: Bearer rk_YOUR_KEY" \
     "https://www.rocoto.space/api/v1/posts?limit=5"

Using a key

Limits

Each key may make 30 requests per minute and has a daily share of 1,000 requests and 2,000 items (every post, comment, pathway or profile in an answer is one item). The day ends at midnight UTC. Over the per-minute limit you get 429 with rate_limited: wait a little and try again. Over the daily share you get 429 with quota_exceeded until tomorrow, and a key that keeps asking is switched off. Every answer says what is left in X-Rocoto-Quota-Items-Remaining and X-Rocoto-Quota-Requests-Remaining. Lists give at most 50 items per request.

Endpoints

All paths start with https://www.rocoto.space/api/v1. Every endpoint except the index needs a key.

RequestWhat it returns
GET /A short description of the API and its endpoints (no key needed).
GET /meThe person the key belongs to.
GET /statsHow many members, posts and pathways Rocoto has.
GET /postsPosts, newest first. Options: limit (1-50, default 20), before (a post id: only older ones), pathway (a pathway's name), author (a username), sort (new, or hot for what is trending now; hot has no paging).
GET /posts/{id}One post.
GET /posts/{id}/commentsThe post's comments, oldest first. Options: limit, after (a comment id: only newer ones).
GET /pathwaysPathways (communities) that are not archived. Options: limit, offset.
GET /pathways/{name}One pathway.
GET /users/{username}A profile: name, picture, join date, badges and bio. A friends-only profile shows "private": true and no bio unless you are friends.
GET /users/{username}/postsThe same as /posts?author={username}.
GET /search?q={text}Up to 20 people, pathways and posts matching the text.

Paging

Lists answer with {"data": [...], "next_before": 123}. Pass that number back as before to get the next, older page when a person scrolls on; when it is null there are no more. Paging counts against your daily share, so do not page through everything. Comments use next_after and after in the same way, pathways use next_offset and offset.

Example answer

GET /api/v1/posts?limit=1

{
  "data": [{
    "id": 482,
    "url": "https://www.rocoto.space/post/482",
    "title": null,
    "content": "Spring planting calendar, free to print.",
    "pathway": "Gardening",
    "pathway_url": "https://www.rocoto.space/pathway/Gardening",
    "author": {
      "username": "Maya",
      "profile_url": "https://www.rocoto.space/profile/Maya",
      "profile_pic": "https://www.rocoto.space/static/media/profile/Maya/pic/1a2b3c.png",
      "badges": []
    },
    "created_at": "2026-10-06T12:34:56+00:00",
    "edited_at": null,
    "likes": 12,
    "comments": 3,
    "pinned": false,
    "attachment": {"type": "pdf", "url": "https://www.rocoto.space/static/media/post/482/9f8e7d.pdf", "name": "Spring planting calendar.pdf", "size": 183422},
    "youtube_mode": "video"
  }],
  "next_before": 481
}

Attachment type is one of image, audio, video, pdf or file. Dates are ISO 8601 in UTC. Pictures and files are normal web addresses you can show or download.

Code examples

Python

import requests

API = "https://www.rocoto.space/api/v1"
headers = {"Authorization": "Bearer rk_YOUR_KEY", "User-Agent": "MyApp/1.0 (+https://example.com)"}

# Show the 10 newest posts of a pathway when a person opens that screen of your app
reply = requests.get(f"{API}/posts", headers=headers, params={"pathway": "Main", "limit": 10})
reply.raise_for_status()
for post in reply.json()["data"]:
    print(post["author"]["username"], post["content"][:60])

JavaScript

const reply = await fetch("https://www.rocoto.space/api/v1/pathways/Main", {
  headers: { Authorization: "Bearer rk_YOUR_KEY" },   // a browser sends its own User-Agent
});
if (!reply.ok) throw new Error((await reply.json()).error.message);
const { data } = await reply.json();
console.log(data.name, data.members, "members");

Errors

Errors have a matching HTTP status and a JSON body: {"error": {"code": "not_found", "message": "There is no such post."}}

StatuscodeMeaning
400bad_parameterA parameter is missing or not valid.
401missing_key / invalid_keyNo key was sent, or it is wrong or revoked.
404not_foundIt does not exist, or you may not see it.
403automation_not_allowedA scraper, crawler or automated browser (or no User-Agent at all). Not allowed.
429rate_limitedToo many requests in a minute; wait and retry.
429quota_exceededThe key's daily share is used up; it resets at midnight UTC.

Version 2: apps that act for a person

Version 2 lets an app (a phone app, a desktop client) read the feed and, if the person allows it, post, comment, like and report as that person. The person signs in on rocoto.space and approves the app; your app never sees their password. Version 1 and personal keys keep working as before.

1. Register your app in Settings > Developer apps: a name, the exact return addresses (https://..., http://127.0.0.1:port/... or your own scheme such as myapp://oauth). You get a client_id. A new app is in development mode: up to 25 people, and only you can give it permission to post.

2. Send the person to https://www.rocoto.space/oauth/authorize (in a browser or web view) with response_type=code, client_id, redirect_uri, scope (space-separated), a random state, and PKCE: code_challenge = base64url(SHA-256(verifier)) with code_challenge_method=S256. After they press Allow you get ?code=...&state=... at your return address.

3. Swap the code for tokens: POST https://www.rocoto.space/oauth/token (form fields) with grant_type=authorization_code, code, redirect_uri, client_id, code_verifier. The answer has an access_token (ra_..., 30 minutes) and a refresh_token (rr_...). When the access token expires, send grant_type=refresh_token, refresh_token, client_id and store the new pair: every refresh token works once, and showing an old one again cancels the whole chain. POST /oauth/revoke with token and client_id signs out.

4. Call the API with Authorization: Bearer ra_... and a User-Agent that names your app. Everything is under /api/v2, answers are JSON (plain text, never HTML), lists use cursors and return at most 50 items. What the person cannot see answers 404, like something that does not exist.

ScopeLets the app
read:publicRead public posts, comments, pathways and profiles
read:feedRead the person's feed and notifications
write:postsCreate and delete the person's own posts (pictures, polls, quotes)
write:commentsComment, reply, and delete the person's own comments
write:reactionsLike and unlike, vote in polls
write:safetyReport content, block and unblock people
CallScope
GET /api/v2/meany
GET /api/v2/feed?sort=new|hot|friends&before=read:feed
GET /api/v2/pathways, /pathways/{name}/postsread:public
GET /api/v2/users/{name}, /users/{name}/postsread:public
GET /api/v2/posts/{id}, /posts/{id}/comments?after=read:public
POST /api/v2/posts (JSON or multipart with image; send an Idempotency-Key header so a retry cannot post twice)write:posts
DELETE /api/v2/posts/{id}write:posts
POST /api/v2/posts/{id}/comments, DELETE /api/v2/comments/{id}write:comments
PUT|DELETE /api/v2/posts/{id}/like, /comments/{id}/like, POST /posts/{id}/votewrite:reactions
GET /api/v2/notifications, POST /notifications/readread:feed
POST /api/v2/reports, PUT|DELETE /blocks/{name}write:safety

Limits per person and app: 600 requests an hour, 20 new posts, 100 comments and 20 reports a day, 300 likes an hour, 2,000 items returned a day while the app is in development (higher once it is reviewed). Posts and comments made through an app show via its name. People can remove an app any time in Settings > Connected apps, and apps that break the rules are switched off.

Please be kind

Rocoto · Your Social Media Network
Privacy · Terms · API · Contact · Cookie settings