API reference
Generated from the API's OpenAPI document (https://api.brrrain.fun/openapi.json); do not edit by hand.
Base URL: https://api.brrrain.fun. Authenticate with Authorization: Bearer <API key> (brrr_…) or a bearer session from POST /v1/auth/near. Token amounts are strings in token units (1 token = 10^18 units). Power amounts are numbers.
auth
Sign in with a NEAR signature (NEP-413), no transaction.
POST /v1/auth/challenge
Starts a sign-in: returns the message and nonce to sign with NEP-413.
Pass referral_code from a /r/<code> link; it binds on the account's first sign-in only.
Auth: none.
Request body:
| Field | Type | Meaning |
|---|---|---|
account_id | string | The NEAR account signing in. |
referral_code | string or null (optional) | A referral code from a /r/<code> link. It binds only on the account's first sign-in. |
Answer 200: Challenge
Errors: 400, 429.
POST /v1/auth/logout
Ends the current session.
Auth: a bearer session or the site's cookie (an API key is refused).
Answer 204
Errors: 401.
POST /v1/auth/near
Finishes a sign-in with the NEP-413 signature of a full-access key of the account.
session: "bearer" returns session_token for agents; session: "cookie" sets the site's cookie and returns csrf_token.
Auth: none.
Request body:
| Field | Type | Meaning |
|---|---|---|
account_id | string | The account the challenge was issued to. |
nonce | string | The nonce from the challenge, base64. |
public_key | string | ed25519:<base58>: the full-access key that signed. |
session | cookie | bearer |
signature | string | base64 ed25519 signature of the NEP-413 payload. |
Answer 200: SignInResponse
Errors: 401.
account
Your balance, Power and usage.
GET /v1/me
The account's token balance and Power today: given, spent, held by running requests, left, and when it refreshes.
Auth: API key, bearer session or the site's cookie.
Answer 200: Me
Errors: 401.
GET /v1/usage
The account's requests, newest first: model, key, tokens, Power charged. No prompts or answers are kept. Only for a session signed in with the account's NEAR key: an API key cannot read the account's history.
Auth: a bearer session or the site's cookie (an API key is refused).
- query
before(optional): string or null — Only events before this time (paging: pass the lastcreated_at). - query
limit(optional): integer or null — At most 200.
Answer 200: UsageEvent[]
Errors: 401.
GET /v1/usage/days
The account's Power day by day, newest first: what it got and what it used. Only for a session signed in with the account's NEAR key.
Auth: a bearer session or the site's cookie (an API key is refused).
- query
days(optional): integer or null — Days back from today, at most 90 (default 30).
Answer 200: PowerDay[]
Errors: 401.
keys
API keys for your agents. Managed with a signed-in session.
GET /v1/keys
Lists the account's API keys (never the keys themselves).
Auth: a bearer session or the site's cookie (an API key is refused).
Answer 200: ApiKey[]
Errors: 401.
POST /v1/keys
Creates an API key. The key is in secret, shown this once; only its hash is kept.
Auth: a bearer session or the site's cookie (an API key is refused).
Request body:
| Field | Type | Meaning |
|---|---|---|
daily_cap_power | number or null (optional) | The most Power this key may spend a day; leave out for the account's whole quota. |
name | string |
Answer 200: CreatedKey
Errors: 400, 401.
DELETE /v1/keys/{id}
Revokes a key at once.
Auth: a bearer session or the site's cookie (an API key is refused).
- path
id: string
Answer 204
Errors: 404.
PATCH /v1/keys/{id}
Renames a key or changes its daily cap (null removes the cap).
Auth: a bearer session or the site's cookie (an API key is refused).
- path
id: string
Request body:
| Field | Type | Meaning |
|---|---|---|
daily_cap_power | number or null (optional) | A new cap, or null to remove it. Leave the field out to keep the cap. |
name | string or null (optional) |
Answer 200: ApiKey
Errors: 404.
openai
OpenAI-compatible inference.
POST /v1/chat/completions
An OpenAI chat completion, streaming or not.
The request's maximum cost is reserved from today's Power before it runs and the real cost is charged when it ends. Leave out max_tokens and the most you can afford (up to a default) is used; a max_tokens you cannot afford is refused with affordable_max_tokens. Every answer carries x-brrrain-power-remaining and x-brrrain-power-reset-at.
Auth: API key, bearer session or the site's cookie.
Request body: An OpenAI chat completion request. max_tokens is set for you when left out.
Answer 200: The completion, or an SSE stream when stream is true
Errors: 402 (quota_exhausted or max_tokens_too_high), 403 (no_tokens), 404 (model_not_found), 429, 503.
GET /v1/models
The models you can use, with prices in Power per million tokens and per typical message.
Auth: none.
- query
include_unavailable(optional): boolean — Also list the models NEAR AI does not serve right now (available: false); they cannot be called.
Answer 200: ModelList
airdrop
Airdrop waves, referral bonuses and claim vouchers.
GET /v1/airdrop
The account's airdrop: each published wave it is in, with its amount, rank and what it is in it for.
Auth: API key, bearer session or the site's cookie.
Answer 200: Airdrop
Errors: 401.
POST /v1/airdrop/card
Shares the account's airdrop card: from now on its link shows the account's total and what it is in the airdrop for. Nothing is public before.
Auth: a bearer session or the site's cookie (an API key is refused).
Answer 200: CardShared
Errors: 401, 404.
DELETE /v1/airdrop/card
Hides the account's airdrop card again: its link stops showing anything.
Auth: a bearer session or the site's cookie (an API key is refused).
Answer 204
Errors: 401.
GET /v1/claims
What the account is owed in each wave and of its referral rewards, what it already claimed, and a signed voucher for the rest of each.
Send claim(drop, total, register, signature) to contract_id with attach_yocto and gas from the voucher, one wave at a time.
Auth: API key, bearer session or the site's cookie.
Answer 200: Claims
Errors: 401, 503.
GET /v1/referrals
The account's referral code and link, its invitees and the bonuses they earned it.
Auth: API key, bearer session or the site's cookie.
Answer 200: Referrals
Errors: 401.
POST /v1/referrals/check
Checks on chain, now, whether the caller's invitees claimed their airdrop, and grants the bonuses due (the worker also does this every few minutes). The site calls it when the browser saw an invitee's claim; nothing is taken from the caller but the trigger. At most one check per account every 20 s.
Auth: API key, bearer session or the site's cookie.
Answer 200: RewardsCheck
Errors: 401, 503.
public
Public numbers, no sign-in.
GET /v1/public/card/{code}
A shared airdrop card, by its owner's code (the link <site>/drop/<code>).
Auth: none.
- path
code: string
Answer 200: DropCard
Errors: 404.
GET /v1/public/card/{code}/card.png
A shared airdrop card as an image (PNG, 1200×630), for social previews.
Auth: none.
- path
code: string
Answer 200: The shared airdrop card, 1200×630
Errors: 404.
GET /v1/public/config
The economics constants and contract ids the site shows.
Auth: none.
Answer 200: PublicConfig
GET /v1/public/days
The day history: budget, spending, holders, Power per million tokens.
Auth: none.
- query
limit(optional): integer or null — Days back from today, at most 366.
Answer 200: DayView[]
POST /v1/public/helper
The site's helper: answers a question about BRRRAIN (no sign-in, no tokens).
Auth: none.
Request body:
| Field | Type | Meaning |
|---|---|---|
messages | HelperMessage[] | The conversation so far, oldest first, ending with the user's question. |
stream | boolean (optional) | Stream the answer as server-sent events, each data: a JSON object: {"delta": text} to append, {"replace": text} to show instead of everything so far, then {"done": true, "refused": bool}, or {"error": message} if the answer broke off. |
Answer 200: HelperAnswer — The answer; with stream: true, server-sent events (see HelperRequest.stream)
Errors: 400 (invalid_request), 404 (helper_unavailable), 429 (rate_limited).
GET /v1/public/leaderboard
The accounts that invited the most friends. Third-level accounts (x.wallet.near) are not counted as friends: a bot or a wallet service makes them by the hundred, and they would buy a place here. They still earn their referrer its bonus (that needs a claim, which a new account does not have).
Auth: none.
Answer 200: Leaderboard
GET /v1/public/stats
Today's budget, the latest contract readings (token, pot, market, distributor) and the pot against the token's value.
Auth: none.
Answer 200: Stats
GET /v1/public/usage
AI served: requests, tokens and accounts since launch, today, by model and by day.
Auth: none.
- query
days(optional): integer or null — Days of history, newest first, at most 366.
Answer 200: UsageView
GET /v1/public/waves
The published waves, newest first, with what each gave and what was claimed.
Auth: none.
Answer 200: WaveInfo[]
Answer shapes
Challenge
| Field | Type | Meaning |
|---|---|---|
expires_at | string | |
message | string | Sign exactly this text. |
nonce | string | 32 bytes, base64: the NEP-413 nonce. |
recipient | string | The NEP-413 recipient. |
SignInResponse
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
csrf_token | string or null (optional) | Cookie sessions: send in the x-csrf-token header on every POST, PATCH and DELETE. |
expires_at | string | |
first_sign_in | boolean | The account signed in for the first time. |
referred_by | string or null (optional) | Who referred the account, if a referral bound. |
session_token | string or null (optional) | Bearer sessions: send as Authorization: Bearer <token>. |
Me
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
ai_use_30d | number or null (optional) | The share of its quota the account spent over the last 30 closed days (0 to 1); null without a quota in them. The lock's suggestion of what AI share to keep starts from it. |
balance | string | Token units held now. |
day | string | |
holds_enough | boolean | |
key | KeyPower or null (optional) | |
power_left | number | |
power_reserved | number | |
power_spent | number | |
power_today | number | Power for today: given, spent, held by running requests, left. |
power_tomorrow_estimate | number or null (optional) | Tomorrow's Power if nothing else changes: today's budget per token and the balance stay; before trading, at most tomorrow's cap. |
resets_at | string |
UsageEvent
| Field | Type | Meaning |
|---|---|---|
completion_tokens | integer or null (optional) | |
created_at | string | |
id | string | |
key_id | string or null (optional) | |
model | string | |
power | number | |
prompt_tokens | integer or null (optional) | |
status | string | |
stream | boolean |
PowerDay
| Field | Type | Meaning |
|---|---|---|
day | string | |
power_given | number | Power the account got for the day. |
power_spent | number | Power its requests used that day. |
requests | integer |
ApiKey
| Field | Type | Meaning |
|---|---|---|
created_at | string | |
daily_cap_power | number or null (optional) | |
hint | string | The key's first characters. |
id | string | |
last_used_at | string or null (optional) | |
name | string |
CreatedKey
| Field | Type | Meaning |
|---|---|---|
created_at | string | |
daily_cap_power | number or null (optional) | |
hint | string | The key's first characters. |
id | string | |
last_used_at | string or null (optional) | |
name | string | |
secret | string | The key itself. Shown once; we keep only its hash. |
ModelList
| Field | Type | Meaning |
|---|---|---|
data | ModelEntry[] | |
default_model | string or null (optional) | |
object | string | Always list. |
Airdrop
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
card_link | string or null (optional) | The link to the account's public airdrop card, once it shared it with POST /v1/airdrop/card; null before. |
eligible | boolean | In at least one published wave. |
total | string | Token units, every wave together. |
waves | WaveEntry[] | The published waves the account is in, oldest first. |
CardShared
| Field | Type | Meaning |
|---|---|---|
image | string | The card's image, 1200×630. |
link | string | <site>/drop/<code>: the card's page, which also invites. |
Claims
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
referral | Claim | |
waves | WaveClaim[] | The published waves the account is in, oldest first; each is claimed on its own. |
Referrals
| Field | Type | Meaning |
|---|---|---|
airdrop_bonus_bps | integer | The airdrop bonus, basis points of each invitee's airdrop, paid on top of it. |
airdrop_bonus_max_invitees | integer or null (optional) | |
bonus_total | string | Token units earned from referrals, in total. |
code | string | |
invitees | Invitee[] | |
link | string | <site>/r/<code>. |
referred_by | string or null (optional) |
RewardsCheck
| Field | Type | Meaning |
|---|---|---|
checked | boolean | false when this account was checked less than 20 seconds ago (nothing was read). |
granted | integer | Airdrop referral bonuses this check granted. |
DropCard
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
categories | string[] | What it is in the airdrop for, every wave together. |
referral_link | string | |
top_percent | number or null (optional) | "Top N %" by the total over every wave; only within the top 10 %. |
total | string | Token units, every published wave together. |
waves | string[] | The titles of the published waves it is in, oldest first. |
PublicConfig
| Field | Type | Meaning |
|---|---|---|
carry_weights | integer[] | How unspent budget is carried into the next three days. |
day_boundary_utc | string | Days refresh at 00:00 UTC. |
default_model | string or null (optional) | |
distributor_contract | string or null (optional) | |
helper_enabled | boolean | The site's helper answers (POST /v1/public/helper). |
lock_contract | string or null (optional) | The BRRRAIN lock (null before it is deployed). |
long_reserve_share | number | |
max_concurrent_per_account | integer | Requests one account may run at once. |
max_daily_quota_drop | number | The most a token's quota falls from one day to the next, once trading is open. |
max_daily_quota_drop_before_trading | number | The same before trading opens. |
max_keys_per_account | integer | |
min_token_balance | string | Token units an account must hold to use the API. |
network | string | |
pot_contract | string or null (optional) | |
power_usd | number | USD per Power. |
quota_cap_daily_growth | number | How much the cap grows a day. |
quota_cap_per_1m_usd | number or null (optional) | Before trading: the first day's cap, USD a day per one million tokens (null: no cap). |
quota_excluded_accounts | string[] | Accounts whose tokens earn no quota. |
rate_limit_per_key_per_min | integer | Requests per minute per API key (or per session). |
referral_airdrop_bps | integer | The referrer's bonus, basis points of each wave an invitee claims; the waves are /v1/public/waves. |
reserve_release_days | integer | |
session_ttl_secs | integer | How long a sign-in session lasts. |
snapshot_at_utc | string | Balances are read once a day at this UTC time ("23:45"). |
token_contract | string |
DayView
| Field | Type | Meaning |
|---|---|---|
base_budget_usd | number | |
cap_per_1m_usd | number or null (optional) | The day's cap: USD per one million tokens. null: no cap. |
carry_usd | number | |
closed | boolean | |
day | string | |
fresh_usd | number | USD amounts. |
holders | integer | |
power_per_1m_tokens | number or null (optional) | Power per one million tokens held (at most the cap). |
promised_usd | number | |
release_usd | number | |
reserve_usd | number | |
spent_usd | number | |
trading | boolean | Trading was open when the day opened; before it, the airdrop rules. |
unspent_usd | number or null (optional) |
HelperAnswer
| Field | Type | Meaning |
|---|---|---|
answer | string | |
refused | boolean | The question was declined (off topic or suspicious); answer says so. |
Leaderboard
| Field | Type | Meaning |
|---|---|---|
referrers | LeaderRow[] | By friends invited. No amounts: nobody sees what another account got. |
Stats
| Field | Type | Meaning |
|---|---|---|
accounts_signed_in | integer | |
chain | object | The latest reading of each contract: token, pot, market, distributor, lock, and the team's own stake in the farm (team_stake: account_id, staked, yoctoNEAR). |
credits | Credits or null (optional) | |
holders_total | integer | Accounts that received BRRRAIN from an airdrop wave or referral rewards (their claim landed). |
pot_vs_fdv | number or null (optional) | NEAR in the pot ÷ the token's fully diluted value in NEAR (above 1: the pot is worth more than the token). |
resets_at | string | |
today | DayView or null (optional) |
UsageView
| Field | Type | Meaning |
|---|---|---|
days | UsageDay[] | Newest first, every day since since (days with nothing served included). |
models | UsageModel[] | Since launch, most tokens first. |
since | string or null (optional) | The first day anything was served; null before that. |
today | UsageTotals | |
total | UsageTotals | |
updated_at | string |
WaveInfo
| Field | Type | Meaning |
|---|---|---|
about | string | |
accounts | integer | |
budget | string or null (optional) | From the distributor (the worker's last reading); null before the first. |
claim_until | string or null (optional) | |
claimed | string or null (optional) | |
closed | boolean or null (optional) | |
id | string | |
published_at | string | |
snapshot_block | integer | |
title | string | |
total | string | Token units: what the wave gives in all. |
KeyPower
| Field | Type | Meaning |
|---|---|---|
daily_cap_power | number or null (optional) | null: no cap, the key can spend all the account's Power. |
name | string | |
power_left | number | What this key can still spend today. |
power_spent | number | Spent today by this key, and held by its running requests. |
ModelEntry
| Field | Type | Meaning |
|---|---|---|
available | boolean | NEAR AI serves it now. Only ?include_unavailable=true lists models that are not. |
context_length | integer | |
created | integer | |
id | string | |
max_output_tokens | integer or null (optional) | |
name | string | |
object | string | Always model. |
owned_by | string | |
price | ModelPrice | |
private | boolean | Runs in a TEE with attestation (NEAR AI's private models). |
reasoning | boolean | It can think before it answers (some such models always do, GLM among them). The thinking is billed as output tokens and counts against max_tokens: give it room (1 000 or more), or a short max_tokens can end before any answer text. |
WaveEntry
| Field | Type | Meaning |
|---|---|---|
about | string | |
amount | string | Token units. |
categories | string[] | What the account is in this wave for (memecoins, merit, …), never how much each counted. |
of | integer | Accounts in this wave. |
percentile_bps | integer | 10000 = the top account of the wave. |
rank | integer | |
snapshot_block | integer | |
title | string | |
wave | string | The wave's id, also its drop on the distributor. |
Claim
| Field | Type | Meaning |
|---|---|---|
after_first | boolean | Claim a wave first: that claim registers the wallet on the token. |
claimable | string | owed − claimed. |
claimed | string | What the distributor already paid. |
owed | string | |
voucher | Voucher or null (optional) |
WaveClaim
| Field | Type | Meaning |
|---|---|---|
after_first | boolean | Claim the wave that registers the wallet first (the one with a voucher); then this one opens. |
claim_until | string or null (optional) | The end of the wave's claim window. |
claimable | string | owed − claimed. |
claimed | string | What the distributor already paid of this wave. |
owed | string | |
state | claimable | claimed |
title | string | |
voucher | Voucher or null (optional) | |
wave | string |
Invitee
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
bound_at | string | |
earned | boolean | The friend claimed a wave and earned the referrer a bonus. How much per friend is not shown: it would tell what the friend got. |
LeaderRow
| Field | Type | Meaning |
|---|---|---|
account_id | string | |
invitees | integer | Friends it invited; sub-accounts of sub-accounts (x.wallet.near) are not counted. |
ChainReading
| Field | Type | Meaning |
|---|---|---|
updated_at | string | |
value | object |
Credits
| Field | Type | Meaning |
|---|---|---|
earned_usd | number | USD the farm has credited, ever. |
left_usd | number | earned − spent. |
read_on | string | The day of the latest farm reading. |
spent_usd | number | USD spent on holders' AI, ever (requests running now included). |
UsageDay
| Field | Type | Meaning |
|---|---|---|
accounts | integer | |
cum_accounts | integer | |
cum_requests | integer | |
cum_tokens | integer | |
day | string | |
new_accounts | integer | Accounts served that day for the first time. |
requests | integer | |
tokens | integer |
UsageModel
| Field | Type | Meaning |
|---|---|---|
model | string | |
name | string | |
requests | integer | |
share | number | Its share of all tokens, 0..1. |
tokens | integer |
UsageTotals
| Field | Type | Meaning |
|---|---|---|
accounts | integer | Distinct accounts served. |
cached_tokens | integer | |
completion_tokens | integer | |
models | integer | Distinct models served. |
prompt_tokens | integer | |
requests | integer | |
requests_with_usage | integer | Of requests, those with a usage report: the token counts cover only these. |
tokens | integer | Prompt plus completion tokens. |
ModelPrice
| Field | Type | Meaning |
|---|---|---|
cached_input_per_1m | number or null (optional) | Power per million cached input tokens, when the model prices them. |
input_per_1m | number | Power per million input tokens. |
output_per_1m | number | |
typical_message | number | Power for a typical message (1 500 tokens in, 650 out). |
Voucher
| Field | Type | Meaning |
|---|---|---|
attach_yocto | string | yoctoNEAR to attach to claim: the distributor's claim fee (0.001 NEAR), plus the token's storage deposit when register. |
contract_id | string | The distributor to call. |
drop | string | claim arguments: drop, total, register, signature. |
gas | string | Gas to attach, in units. |
register | boolean | |
signature | string | |
total | string |
WaveState
Errors
Every error has the OpenAI shape {"error": {"message", "type", "code", "param"}}; read code, follow the message. Some carry more fields: affordable_max_tokens, resets_at, available_power. 429 and 503 carry Retry-After.
code | What to do |
|---|---|
invalid_request | Fix the request as the message says; do not retry it unchanged. |
invalid_api_key | The key is missing, unknown or revoked. Ask your human for a key, or create one (sign-in.md). |
session_expired | Sign in again (sign-in.md). |
csrf_token_missing | Browser sessions only: send the sign-in's csrf_token in x-csrf-token. Agents use a bearer token instead. |
signin_failed | Read the message: the signature, the key (it must be a full-access key of the account) or the challenge (request a new one) is wrong. |
no_tokens | The account holds less than 1 BRRRAIN. Tell your human; do not buy on your own unless told to. |
quota_exhausted | Stop. Power refills at resets_at (00:00 UTC). Tell your human or wait; never retry in a loop. A cheaper model may still fit. |
max_tokens_too_high | Resend with max_tokens at most affordable_max_tokens, or leave it out. |
model_not_found | Pick a model from GET /v1/models. |
rate_limited | Wait Retry-After seconds, then retry once. |
upstream_unavailable | Temporary. Wait Retry-After seconds and retry a few times with growing pauses. |
day_not_open | Today's Power is being computed just after 00:00 UTC. Retry after Retry-After seconds. |
key_limit_reached | The account has the most keys allowed. Revoke one it no longer uses. |
not_found | The path or the object does not exist; check it against this file. |
airdrop_not_eligible | This account is not in the airdrop. |
claims_unavailable | Claims are not open or are paused. Try again later; the total owed is kept. |
referral_invalid | The referral code does not exist. Check the link, or sign in without it. |
helper_unavailable | The site's helper is off. It is for people on the site; an agent uses the API with its own key. |
internal_error | Our failure. Retry once; if it repeats, report the reference in the message. |