Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/rumoro-dev:rumoro-dev-billing-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Rumoro Billing API
version: 0.0.1
description: Social listening for developers and AI agents.
servers:
- url: https://api.rumoro.dev
tags:
- name: Billing
paths:
/v1/billing/top-ups:
post:
operationId: createTopUp
summary: Start a top-up
description: Returns a hosted checkout link with `amountCents` filled in. The buyer can change it there, from $20 to $5,000. The balance is credited within a minute of payment, and tracking paused for balance resumes right away. This call charges nothing by itself. `successUrl` must be on an origin this deployment trusts. Leave it out to return to the dashboard's billing page.
tags:
- Billing
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
amountCents:
type: integer
minimum: 2000
maximum: 500000
description: The amount to add in US cents, from 2000 to 500000. Checkout starts with it and the buyer can change it.
successUrl:
type: string
maxLength: 2000
format: uri
description: Page to return to after payment. It must be on an origin this deployment trusts, like the dashboard, and defaults to the dashboard's billing page.
required:
- amountCents
responses:
'200':
description: A checkout link with the amount filled in
content:
application/json:
schema:
type: object
properties:
url:
type: string
description: The Polar checkout link.
required:
- url
'400':
description: The amount is not valid, or successUrl is not allowed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: The credential is missing or not valid
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: There is no workspace owner to bill
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: The workspace started too many checkouts in this minute
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: This deployment has no billing set up
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/billing/wallet:
get:
operationId: getWallet
summary: Get the balance
description: Returns every detail of the prepaid balance. That covers the ledger total, pending mention charges, the effective balance used for pausing, the daily spend and days left, running and paused keywords, the cost of a day and of resuming, the welcome credit, the latest top-up, the top-up limits and the auto-recharge settings. `GET /v1/usage` gives a shorter version.
tags:
- Billing
security:
- bearerAuth: []
responses:
'200':
description: Wallet balance, daily spend and pause state
content:
application/json:
schema:
$ref: '#/components/schemas/Wallet'
'401':
description: The credential is missing or not valid
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/billing/ledger:
get:
operationId: listLedger
summary: List ledger entries
description: Shows the balance's history, latest first. Entries cover the welcome credit, top-ups, refunds, adjustments, and the daily keyword-day and mention debits. Debits carry their UTC settlement day and cumulative units. Cursor pages.
tags:
- Billing
security:
- bearerAuth: []
parameters:
- schema:
type: string
description: The `nextCursor` of the previous page. Do not parse it.
required: false
description: The `nextCursor` of the previous page. Do not parse it.
name: cursor
in: query
- schema:
type: integer
minimum: 1
maximum: 100
description: How many to return, from 1 to 100, 25 by default.
example: 25
required: false
description: How many to return, from 1 to 100, 25 by default.
name: limit
in: query
responses:
'200':
description: Ledger entries, latest first
content:
application/json:
schema:
$ref: '#/components/schemas/LedgerList'
'400':
description: The cursor is not valid
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: The credential is missing or not valid
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/billing/invoices:
get:
operationId: listInvoices
summary: List receipts
description: Returns the top-up orders, latest first, as Polar, the merchant of record, stores them. You get this workspace's orders among the billing customer's latest 100. No orders exist before the first top-up.
tags:
- Billing
security:
- bearerAuth: []
responses:
'200':
description: Receipts for paid orders. Empty before the first payment
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceList'
'401':
description: The credential is missing or not valid
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/billing/invoices/{id}/url:
get:
operationId: getInvoiceUrl
summary: Get a receipt link
description: For a paid order from GET /v1/billing/invoices, returns a receipt PDF URL that expires soon.
tags:
- Billing
security:
- bearerAuth: []
parameters:
- schema:
type: string
minLength: 1
description: Which paid order. Ids come from GET /v1/billing/invoices.
required: true
description: Which paid order. Ids come from GET /v1/billing/invoices.
name: id
in: path
responses:
'200':
description: Receipt PDF URL, valid briefly
content:
application/json:
schema:
type: object
properties:
url:
type: string
description: Receipt PDF URL, valid briefly.
required:
- url
'401':
description: The credential is missing or not valid
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: The receipt does not exist, or its PDF is not ready
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: No billing is set up
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
InvoiceList:
type: object
properties:
data:
type: array
items:
type: object
properties:
id:
type: string
description: Pass it to GET /v1/billing/invoices/{id}/url for the receipt.
createdAt:
type: string
description: Order date and time (ISO 8601).
status:
type: string
description: Polar's status for the order, such as paid or refunded.
paid:
type: boolean
description: True if the order is paid.
totalAmount:
type: integer
description: The amount charged including tax, in the smallest unit of `currency`.
currency:
type: string
description: The order's currency as an ISO 4217 code, such as usd.
billingReason:
type:
- string
- 'null'
description: Polar's reason for the order, such as purchase or subscription_cycle. Null when Polar gives none.
required:
- id
- createdAt
- status
- paid
- totalAmount
- currency
- billingReason
description: Most recent paid orders first. None until the first top-up.
required:
- data
Wallet:
type: object
properties:
balanceCents:
type: integer
description: The ledger balance, all credits minus all settled debits.
pendingCents:
type: integer
description: Cost of mentions matched after the last daily settlement. Not debited yet.
effectiveBalanceCents:
type: integer
description: balanceCents minus pendingCents. Pausing at zero and the check before adding keywords both use this number.
burnPerDayCents:
type: integer
description: Mean daily debit across the past 7 days, or the workspace's lifetime if shorter.
daysLeft:
type:
- integer
- 'null'
minimum: 0
description: effectiveBalanceCents over burnPerDayCents, rounded down. Null when burnPerDayCents is 0.
stopped:
type: boolean
description: True when tracking is paused because the balance ran out. It resumes after a top-up that covers one day of every keyword.
lowBalance:
type: boolean
description: True when tracking is running and the effective balance is 20 percent of the last credit or less. The low-balance email uses the same rule.
activeKeywords:
type: integer
minimum: 0
description: Keywords that are not muted.
autoMutedKeywords:
type: integer
minimum: 0
description: Keywords muted for low balance. A top-up restarts them.
nextDayCents:
type: integer
description: Next day's cost for the running keywords. Tracking stops if the effective balance drops below it.
resumeCostCents:
type: integer
description: Daily cost of every keyword, running or paused. Tracking restarts once the effective balance reaches this amount.
signupCredit:
type:
- object
- 'null'
properties:
amountCents:
type: integer
description: Whole US cents.
grantedAt:
type: string
description: UTC time in ISO 8601.
required:
- amountCents
- grantedAt
description: Welcome credit given to this workspace. Null when the user already got it in another workspace.
lastTopUpAt:
type:
- string
- 'null'
description: Latest paid top-up time, or null if there is none.
billingConfigured:
type: boolean
description: Whether top-ups work here. false when Polar isn't configured, which hides the top-up button.
minTopUpCents:
type: integer
description: The minimum top-up at checkout.
maxTopUpCents:
type: integer
description: The maximum for one top-up.
defaultTopUpCents:
type: integer
description: The amount the checkout starts with.
currency:
type: string
enum:
- USD
description: All amounts here are in US cents.
autoRecharge:
type: object
properties:
available:
type: boolean
description: Whether saved-card charging works on this deployment. The setting is hidden when false.
enabled:
type: boolean
description: When true, the saved card is charged automatically if the balance gets low.
thresholdCents:
type: integer
description: The card is charged when the effective balance falls below this.
amountCents:
type: integer
description: The amount each automatic charge adds, within the same limits as a manual top-up.
lastRunAt:
type:
- string
- 'null'
description: Time of the latest successful automatic charge.
lastError:
type:
- string
- 'null'
description: Error of the last failed automatic charge, cleared by a successful one.
required:
- available
- enabled
- thresholdCents
- amountCents
- lastRunAt
- lastError
required:
- balanceCents
- pendingCents
- effectiveBalanceCents
- burnPerDayCents
- daysLeft
- stopped
- lowBalance
- activeKeywords
- autoMutedKeywords
- nextDayCents
- resumeCostCents
- signupCredit
- lastTopUpAt
- billingConfigured
- minTopUpCents
- maxTopUpCents
- defaultTopUpCents
- currency
- autoRecharge
ErrorResponse:
type: object
properties:
error:
type: object
properties:
code:
type: string
enum:
- unauthorized
- forbidden
- read_only_key
- validation_error
- not_found
- invalid_cursor
- payload_too_large
- rate_limited
- duplicate_keyword
- insufficient_balance
- keyword_limit_reached
- billing_not_configured
- unknown_channel
- not_a_digest
- hourly_email_unsupported
- slack_not_connected
- slack_not_configured
- telegram_not_configured
- email_not_configured
- invalid_assignee
- classification_pending
- already_member
- last_owner
- duplicate_segment
- duplicate_view
- duplicate_group
- default_group
- default_group_context
- invalid_signature
- invalid_token
- upstream_unavailable
- internal_error
- unsupported_media_type
- request_timeout
- key_limit
- conflict
- no_billing_owner
- rule_disabled
- no_channels
- channel_disabled
- no_recipients
- recipient_suppressed
- confirmation_rate_limited
- confirmation_requires_resend
- email_test_rate_limited
- email_hourly_limit
- email_idempotency_expired
- email_transport_unavailable
- delivery_not_configured
- delivery_key_unavailable
- not_retryable
- not_replayable
- digest_has_replay
- digest_retry_expired
- delivery_request_incomplete
- request_conflict
- stale_version
- version_conflict
- already_classified
- keyword_inactive
- source_unavailable
- source_timeout
- invalid_host
- invalid_origin
- database_unavailable
- database_not_ready
- not_configured
description: A stable code for programs. Branch on it, not on the message. New codes may be added, so treat an unknown one as a general failure with the same status.
message:
type: string
description: A description for people. Its wording can change.
requestId:
type: string
description: This request's id, also sent in the X-Request-Id header. Include it when you contact support.
retryAfterSeconds:
type: integer
description: Seconds to wait before retrying, on rate_limited and other errors you can retry. Same value as the Retry-After header.
required:
- code
- message
description: Details of the error.
required:
- error
LedgerList:
type: object
properties:
data:
type: array
items:
type: object
properties:
id:
type: string
description: The ledger entry's id (led_...).
kind:
type: string
enum:
- signup_credit
- topup
- refund
- debit_keyword_days
- debit_mentions
- debit_comments
- adjustment
description: Type of ledger entry.
amountCents:
type: integer
description: Whole US cents. Credits are positive and debits negative.
day:
type:
- string
- 'null'
description: For debits, the last UTC day this entry settles (YYYY-MM-DD).
units:
type:
- integer
- 'null'
description: For debits, the running total of mentions or keyword-days settled up to and including this entry.
note:
type:
- string
- 'null'
description: Note attached to a credit or adjustment.
polarOrderId:
type:
- string
- 'null'
description: Polar order of a top-up or refund. Null otherwise.
createdAt:
type: string
description: UTC time in ISO 8601.
required:
- id
- kind
- amountCents
- day
- units
- note
- polarOrderId
- createdAt
description: Ledger entries, latest first.
nextCursor:
type:
- string
- 'null'
description: Cursor for the next page, or null when there are no more pages.
required:
- data
- nextCursor
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: An API key from POST /v1/api-keys. Keys start with ref_.
x-rumoro-errors:
- code: unauthorized
status: 401
source: user
retryable: false
description: The credential is missing or does not belong to a workspace.
fix: 'Send Authorization: Bearer ref_… with a key from /api-keys.'
- code: forbidden
status: 403
source: user
retryable: false
description: The credential works but is not allowed to do this.
- code: read_only_key
status: 403
source: user
retryable: false
description: A read-only key called an endpoint that writes.
fix: Create a key with write scope.
- code: validation_error
status: 400
source: user
retryable: false
description: The body or query is not valid. The message says which field.
- code: not_found
status: 404
source: user
retryable: false
description: Your workspace has nothing with this id. An id from another workspace also returns 404, never 403.
- code: invalid_cursor
status: 400
source: user
retryable: false
description: The cursor could not be read, or was issued for another sort. Start again from the first page.
- code: payload_too_large
status: 413
source: user
retryable: false
description: 'The body exceeds the endpoint limit (128 KiB for JSON). A 409 with this code: a delivery whose payload was too large cannot be retried or replayed.'
- code: rate_limited
status: 429
source: user
retryable: true
description: The workspace sent over 600 requests in a minute across all its keys and tokens, or reached an endpoint's own limit. Retry-After and error.retryAfterSeconds tell you when to try again.
fix: Wait Retry-After seconds and send the same request again. X-RateLimit-Remaining on every response says how much room is left.
- code: duplicate_keyword
status: 409
source: user
retryable: false
description: This group already has the term. Each group can hold a term once, and other groups can hold it too.
- code: insufficient_balance
status: 402
source: user
retryable: false
description: The balance cannot pay for one more keyword-day.
fix: Top up from Billing; tracking resumes on its own.
- code: keyword_limit_reached
status: 402
source: user
retryable: false
description: The workspace already runs 500 keywords, or has 500 that are not deleted.
- code: billing_not_configured
status: 503
source: system
retryable: false
description: No payment provider is set up on this deployment.
- code: unknown_channel
status: 400
source: user
retryable: false
description: An alert named a channel id that is not in this workspace.
- code: not_a_digest
status: 400
source: user
retryable: false
description: An action for digests was used on an instant alert.
- code: hourly_email_unsupported
status: 400
source: user
retryable: false
description: An hourly alert got an email channel, which could mean 24 emails a day. Use Slack, Telegram or a webhook, or send a daily digest by email.
- code: slack_not_connected
status: 409
source: user
retryable: false
description: Slack must be connected in Settings first. Returned as 404 by the Slack connection endpoints and 409 elsewhere.
- code: slack_not_configured
status: 503
source: system
retryable: false
description: No Slack app is set up on this deployment.
- code: telegram_not_configured
status: 503
source: system
retryable: false
description: No Telegram bot is set up on this deployment.
- code: email_not_configured
status: 503
source: system
retryable: false
description: This deployment has no email sender set up, so email destinations cannot be used.
- code: invalid_assignee
status: 400
source: user
retryable: false
description: The assignee is not in the workspace.
- code: classification_pending
status: 409
source: user
retryable: true
description: Relevance or sentiment feedback was sent before the classifier scored the mention.
- code: already_member
status: 409
source: user
retryable: false
description: The invited address already belongs to a member.
- code: last_owner
status: 409
source: user
retryable: false
description: The workspace would have no owner left after this removal.
- code: duplicate_segment
status: 409
source: user
retryable: false
description: Another segment in the workspace has this name.
- code: duplicate_view
status: 409
source: user
retryable: false
description: Another view in the workspace has this name.
- code: duplicate_group
status: 409
source: user
retryable: false
description: Another group in the workspace has this name or externalId.
- code: default_group
status: 409
source: user
retryable: false
description: The default group cannot be deleted. It holds keywords created without a group.
- code: default_group_context
status: 400
source: user
retryable: false
description: The default group uses the workspace's company profile, which you change with PATCH /v1/company. Only other groups can have their own description.
- code: invalid_signature
status: 401
source: user
retryable: false
description: An incoming webhook had no valid signature.
- code: invalid_token
status: 400
source: user
retryable: false
description: A signed link (unsubscribe, confirmation, preferences) was tampered with or is malformed.
- code: upstream_unavailable
status: 502
source: platform
retryable: true
description: An outside service such as Slack or Polar failed during the request. Retry with increasing waits.
- code: internal_error
status: 500
source: system
retryable: false
description: Something failed on our side; 502 when Telegram failed a bot lookup. The response carries a requestId; quote it to support.
- code: unsupported_media_type
status: 415
source: user
retryable: false
description: 'A body was sent without Content-Type: application/json.'
- code: request_timeout
status: 408
source: user
retryable: true
description: The body did not arrive within 5 seconds.
- code: key_limit
status: 409
source: user
retryable: false
description: The workspace already has 100 active keys. Revoke one first.
- code: conflict
status: 409
source: user
retryable: false
description: A resource with these values already exists.
- code: no_billing_owner
status: 404
source: user
retryable: false
description: There is no owner to bill in this workspace yet.
- code: rule_disabled
status: 409
source: user
retryable: false
description: The rule is turned off. Enable it before a test or a run.
- code: no_channels
status: 409
source: user
retryable: false
description: The rule has no destination to test.
- code: channel_disabled
status: 409
source: user
retryable: false
description: A destination is turned off. Enable it first.
- code: no_recipients
status: 409
source: user
retryable: false
description: An email destination needs a recipient before it can be turned on.
- code: recipient_suppressed
status: 409
source: user
retryable: false
description: The address bounced or complained, so no more email goes to it.
- code: confirmation_rate_limited
status: 429
source: user
retryable: true
description: 'Too many confirmation emails: wait a minute; at most three per address a day and twenty per workspace an hour.'
- code: confirmation_requires_resend
status: 409
source: user
retryable: false
description: A confirmation email is sent again with a resend, not a delivery retry.
- code: email_test_rate_limited
status: 429
source: user
retryable: true
description: More than five email tests on this destination this hour.
- code: email_hourly_limit
status: 409
source: user
retryable: false
description: The destination's hourly email limit is reached; the mention waits for the next daily digest.
- code: email_idempotency_expired
status: 409
source: user
retryable: false
description: The email's safe retry window passed. Check its receipts before an explicit replay, which may send it twice.
- code: email_transport_unavailable
status: 503
source: system
retryable: false
description: Email sending is not set up for this delivery on this deployment.
- code: delivery_not_configured
status: 503
source: system
retryable: false
description: Destinations that need a stored secret are not set up on this deployment.
- code: delivery_key_unavailable
status: 503
source: system
retryable: false
description: A destination's stored secret cannot be read on this deployment.
- code: not_retryable
status: 409
source: user
retryable: false
description: Only failed or blocked deliveries can be retried.
- code: not_replayable
status: 409
source: user
retryable: false
description: A delivery can be replayed once it has finished.
- code: digest_has_replay
status: 409
source: user
retryable: false
description: This digest delivery has a newer replay. Recover that one.
- code: digest_retry_expired
status: 409
source: user
retryable: false
description: The digest's six-hour retry window passed. Replay it instead.
- code: delivery_request_incomplete
status: 500
source: system
retryable: true
description: The saved outcome of a test could not be read. Read it again; don't send a new test.
- code: request_conflict
status: 409
source: user
retryable: false
description: This requestId was already used for another request. Retry the original, or use a new id.
- code: stale_version
status: 409
source: user
retryable: false
description: The resource changed since you read it. Read it again before saving.
- code: version_conflict
status: 409
source: user
retryable: true
description: The webhook's managed rules changed at the same time. Read it again and retry.
- code: already_classified
status: 409
source: user
retryable: false
description: The mention is already scored; there is nothing to retry.
- code: keyword_inactive
status: 409
source: user
retryable: false
description: The mention's keyword is paused. Resume it before retrying the score.
- code: source_unavailable
status: 502
source: platform
retryable: true
description: 'Live search: the platform didn''t answer (503 when it is rate limiting us).'
- code: source_timeout
status: 504
source: platform
retryable: true
description: 'Live search: the platform didn''t answer in time.'
- code: invalid_host
status: 403
source: user
retryable: false
description: 'MCP: the request''s Host is not this server''s.'
- code: invalid_origin
status: 403
source: user
retryable: false
description: 'MCP: the request''s Origin is not allowed.'
- code: database_unavailable
status: 503
source: system
retryable: true
description: A temporary database problem. Retry with backoff.
- code: database_not_ready
status: 503
source: system
retryable: false
description: The deployment's database needs maintenance; retrying won't help until it is done.
- code: not_configured
status: 503
source: system
retryable: false
description: This deployment has no database configured.