Conventions
Paths, ids, methods, paging, filters, errors and versions. The patterns that hold across the whole Rumoro API.
The API is at https://api.rumoro.dev/v1. Every resource in the reference follows the patterns on this page.
Resources and paths
Paths use plural nouns and one id, such as /v1/mentions/{id}, /v1/keywords/{id} or /v1/alerts/{id}. An id is a prefix followed by 32 hex characters.
| Prefix | Resource |
|---|---|
mm_ | mention |
aut_ | person |
kw_ | keyword |
grp_ | group |
vw_ | view |
seg_ | segment |
feed_ | alert rule |
dest_ | channel |
dlv_ | delivery |
att_ | attention item |
key_ | API key |
org_ | workspace |
An id from another workspace, or one that isn't valid, returns 404 and never 403.
Actions that aren't simple updates are POST requests on the resource, such as /v1/people/{id}/merge, /v1/people/{id}/split, /v1/alerts/{id}/test, /v1/alerts/{id}/run, /v1/channels/{id}/test, /v1/channels/{id}/rotate-secret and /v1/attention/{id}/dismiss.
Analytics come as fixed reports, /v1/analytics/summary, series, breakdown, share-of-voice and reviews. Each takes range (or from and to), keywordIds, platforms, timezone and compare, and returns its window. series and breakdown also take a by dimension.
Exports accept the same filters as their list. /v1/mentions/export.csv and export.json return up to 10,000 rows, /v1/people/export.csv up to 5,000.
Methods and status codes
| Method | Use | Success |
|---|---|---|
GET | Read one item or a list | 200 |
POST on a collection | Create | 201 and the new resource |
PATCH | Change some fields. Fields you leave out stay as they are, null clears one. | 200 and the resource |
DELETE | Delete | 204, no body |
POST action | Run an action | 200 and the result |
There are two exceptions. POST /v1/members/invitations returns 200 with the existing invitation if the address already has one, and POST /v1/billing/top-ups returns 200.
To change anything, use PATCH. For a mention, that includes ignoring, closing, assigning, snoozing and adding notes, all through PATCH /v1/mentions/{id}.
Envelopes
A single resource is returned as is. A list is wrapped in data with paging information.
{ "data": [ ... ], "nextCursor": "eyJ..." }On the last page nextCursor is null. For the next page, send it back as cursor with the same filters and sort. The cursor remembers the position in the sort order, not your filters.
People and keywords use limit and offset instead, and return a total.
{ "data": [ ... ], "total": 418 }Alerts, channels, views, segments, members and API keys come back as one full list.
Shapes
Related fields sit in groups, such as post, author, classification and triage on a mention, or reach, profile, stats and annotations on a person. A missing group is null, for example classification: null before scoring.
Numbers Rumoro calculates are under stats. What you and your team add is under triage or annotations. A mention shows its status (open, ignored, done), relevant and delivered, never Rumoro's internal processing steps.
Times are ISO 8601 in UTC, like "2026-10-04T08:21:37.512Z". Inputs such as since, until and snoozedUntil also accept epoch milliseconds.
Enum values are lowercase strings. The platforms are bluesky, hackernews, github, stackoverflow, devto, reddit, x, youtube, news, linkedin, tiktok and instagram, plus the review sites appstore, googleplay, trustpilot and googlemaps. A keyword's platforms lists where its term is searched ([] means nowhere) and never contains a review site. Reviews come from its reviewSources (Reviews).
Requests
Send JSON bodies with Content-Type: application/json, or you get 415 unsupported_media_type. A body can be up to 128 KiB (413 payload_too_large) and must arrive within 5 seconds (408 request_timeout).
Sending a create request twice creates two resources, so check before you retry. Delivery and digest actions outside the reference take a requestId (a UUID) in the body. Repeating it returns the first answer, and reusing it with a different body returns 409 request_conflict.
Query parameters
Names are camelCase and booleans are true or false. A list can be repeated or comma-separated, so ?tags=vip,customer is the same as ?tags=vip&tags=customer. Parameters you leave out don't filter anything, and unknown parameters are ignored.
Most filters come in three forms. The single form (platform=x), the list form, which matches any value (platforms=x,bluesky), and the not form, which excludes all of them (notPlatforms=news). The single and list forms can be combined. Different filters narrow each other, so platforms=x,bluesky¬Sentiments=negative means X or Bluesky, and nothing negative.
Mentions accept platforms, sentiments, intents, keywordIds, tags, languages, ratings and linkHosts, each with a not form, plus keywordKinds, groupIds and notGroupIds (groups). People accept platforms, tags and intents the same way, plus keywordKinds and neverKeywordKinds.
A list filter takes up to 50 values. tags and linkHosts take up to 20. More than that returns 400 validation_error.
OR across groups (anyOf)
To combine conditions with OR, give mentions an anyOf list of 1 to 10 groups. Each group can hold the same conditions as a saved view. A mention passes when at least one group matches, and your other filters still apply. Groups can't contain another anyOf, a time window or paging. An empty group, an empty anyOf or an unknown field returns 400.
On GET /v1/mentions and the exports, send anyOf as URL-encoded JSON. This finds negative Reddit posts or questions since September 27.
const { data: page } = await rumoro.searchMentions({
query: {
since: '2026-09-27T00:00:00Z',
anyOf: JSON.stringify([{ platforms: ['reddit'], sentiments: ['negative'] }, { intents: ['question'] }]),
},
});Saved views, alert rule filters and the MCP search_mentions tool take the same groups as plain JSON. This rule sends English or German mentions that show buying intent from accounts with 5,000 or more followers, or that are 1 star reviews.
{
"name": "Hot leads",
"mode": "instant",
"filter": {
"languages": ["en", "de"],
"anyOf": [
{ "intents": ["buy_intent"], "minFollowers": 5000 },
{ "ratings": [1] }
]
}
}Errors
Every error uses the same envelope with a stable code. See Errors.
{ "error": { "code": "not_found", "message": "Mention not found", "requestId": "4b0e7d21-..." } }API responses carry an X-Request-Id header, and errors repeat it as error.requestId. Include it when you contact support. You can send your own X-Request-Id of 8 to 64 characters (A-Z, a-z, 0-9, ., _, -) and it is returned unchanged. Other values are replaced.
Keys and scopes
Send Authorization: Bearer <credential> with an API key or OAuth token. A read credential can only make GET requests. Each credential works in one workspace, and GET /v1/whoami tells you which. See Authentication.
Rate limits
Each workspace can make 600 requests a minute. Responses carry X-RateLimit-* headers, and requests over the limit get 429 rate_limited. See Rate limits.
Webhooks
Every event has the same envelope.
{
"id": "dlv_...",
"event": "mention.matched",
"createdAt": "2026-10-04T08:21:37.512Z",
"alert": { "id": "feed_...", "name": "Pricing questions" },
"data": { }
}data is the resource as the API returns it. X-Mentions-Signature-V2 is v2= followed by the hex HMAC-SHA256 of <X-Mentions-Timestamp>.<raw body>, signed with your channel secret. Because the timestamp is signed, an old request can't be sent again. X-Mentions-Signature signs only the body and is kept for older code. See Webhooks.
Versions
All paths start with /v1. New endpoints, optional fields, filters and enum values are added to /v1 without notice, so ignore anything you don't recognize.
Changes that would break existing code come as a new version, /v2. Once /v2 is out, /v1 keeps working for at least six months. Endpoints that are going away will send Deprecation and Sunset headers, and the changelog will say what changed and how to move. Clients generated from the OpenAPI document follow the new version when you regenerate them.
Outside the reference
The dashboard's own endpoints for sign-in, setup and billing are not documented. A few endpoints you can call with a key have their own pages. These are connecting Slack and Telegram, and retrying or replaying deliveries (Webhooks). They wrap a single resource in { "data": ... }, page with { "data", "meta": { "nextCursor" } } and after, and return 202 when they queue work.