Documentation
OpenCrater renders Blips in terminal sessions and pays maintainers per click. This is the complete reference — publishers first, then advertisers, then the SDK internals.
Quickstart (one command)
If you just want Blips in your own Claude Code / Codex / Antigravity sessions — or want to see exactly what your users would see:
npx opencrater on
The installer detects which CLIs you have, registers hooks for each (all events — rendering is gated separately, see placements), installs a local runtime under ~/.config/opencrater/runtime so hooks never race a cold npx cache, and prints the opt-out. Everything it does is undone by npx opencrater off.
Registering a package
- Sign in at opencrater.to/signup (GitHub, Google, or GitLab).
- Dashboard → packages → register: name, type (MCP server, CLI, agent, library, API service, SaaS, GitHub repo, and more), language, categories. Type and categories matter — they feed both targeting and Blips relevance.
- You get a serve key (
ock_…) — a public attribution token you can always view again on your dashboard. It attributes impressions to your package so you get paid; it cannot spend anything, so shipping it inside your installer is expected and safe. Rotate it any time. - Set a funding fallback URL (e.g. your GitHub Sponsors page) — it renders as the card whenever no campaign fills, so the slot always works for you.
- Wire your integration (SDK below, or hooks if your users run agent CLIs), pick your placements, and add a README line disclosing Blips and the opt-out.
npx -y -p opencrater opencrater-hook \ --key ock_YOUR_KEY --package your-package --host claude_code
Hosts & hook events
Cards render through each CLI's native hook system. The SDK registers all of a host's events as triggers; whether a given event renders is your placement selection. Event sets below are source-verified per host:
| host | hook system | recommended render events |
|---|---|---|
| claude_code | ~/.claude/settings.json hooks — 30 events (SessionStart, Stop, Notification, PreToolUse/PostToolUse, SubagentStart/Stop, TaskCreated/Completed, PreCompact/PostCompact, and more). | SessionStart · Stop · SessionEnd · Notification |
| codex | hooks.json — 8 events. The TUI repaints its whole frame at boot, so SessionStart cards are usually erased; render at Stop. | Stop |
| antigravity | ~/.gemini/config/hooks.json (Antigravity CLI `agy`) — named-hooks schema, 5 events: Stop, PreToolUse, PostToolUse, PreInvocation, PostInvocation. Tool/invocation events are gating, so the hook is wired fail-open; render at Stop (turn end). | Stop |
| copilot_cli | ~/.copilot/hooks/hooks.json — 11 events (sessionStart, agentStop, sessionEnd, notification, pre/postToolUse…). Verified firing + ANSI render in v1.0.62. Renders only when `copilot` runs in a real terminal; its GUI chat panel is a closed surface with no TTY to paint. | agentStop · sessionStart · sessionEnd · notification |
| grok_cli | ~/.grok/hooks/*.json — Claude-Code-format hooks, always trusted (no per-project trust prompt). 14 events (SessionStart, Stop, SessionEnd, Notification, pre/postToolUse, pre/postCompact…). Lifecycle events are written matcher-less. | SessionStart · Stop · SessionEnd · Notification |
| openclaw | In-process TypeScript plugin hooks only — no external hook can paint the terminal, so cards cannot render yet. Sponsorship is pending an external hook system. | — (coming soon) |
How rendering actually works: the hook is only a trigger. It spawns a detached painter that draws the card straight onto the terminal device as a top-right overlay — hosts capture hook stdout, so printing was never an option. The painter repaints through output storms, shows a live auto-dismiss countdown, and cleans up after itself. Concurrent hook bursts (an agent firing six tools at once) collapse to exactly one card via a machine-wide render slot.
Choosing placements
In the dashboard, each package selects which hook events may render, per host. Recommendations exist because attention has edges: session start and turn end are natural seams; PreToolUse fires constantly and would wear your users out. Selecting nothing keeps the recommended defaults. The serve response carries your selection to every installed SDK (allowedPlacements), cached per package + host.
Advertisers independently target placements — a card renders only where both your selection and their targeting agree.
Earnings & payouts
- You earn a share of every Blips shown on your surface and every confirmed click — clicks are the headline, impressions add a small per-view earning on top. Clicks confirm after the fraud window (pending → available).
- Dashboard → earnings shows impressions, clicks, CTR, dismissal rate, and revenue per package, with daily charts. High dismissal rates come with concrete advice — they usually mean too many placements or a mismatched audience.
- Withdraw available balance as USDC on Base or Ethereum. Small amounts auto-pay; larger ones process from the payout queue. Chain transactions are public and irreversible — check addresses.
- Your earnings can also fund your own campaigns directly (see below) — promote your package with the money it makes.
Campaign anatomy
A campaign is: a name (the card's “Sponsored ·” brand line — use your product name), a category (primary + optional secondary), a CPC bid, budgets (total, optional daily pace cap), targeting, and one creative. Create it at dashboard/promote — every input has inline help, a recommendation, and an example, plus a live terminal preview that renders exactly what ships, switchable between Claude Code, Codex, and Antigravity frames.
Lifecycle: draft → submit (funds lock into escrow) → in_review → approved → active → paused / edited (back to review) / cancelled (unspent escrow refunds instantly) / completed.
Blips formats (including audio)
| format | what renders | requirements |
|---|---|---|
| text | The boxed card: sponsored label, bold amber title, body, CTA pill. | Title ≤64 chars, body ≤200, https URL. |
| logo | Your mark as circular terminal pixel art, full card height beside the text. | Square, bold, high-contrast source. The pixel version is authored at upload — the preview shows exactly what renders. |
| image | A square pixel-art thumbnail beside the text. | Same as logo, minus the circle. |
| gif / video | Animates in capable terminals (iTerm2, WezTerm, Kitty); still or text fallback elsewhere. | Text fallback required. No strobing. |
| audio | A standalone audio spot with the text card. | ≤ 25 seconds (validated at upload). See caps below. |
Audio on any format
Any creative — even plain text — can carry an optional audio track that plays when the card renders. The card then shows a live waveform with a working pause/play control. Hard caps, enforced in the SDK: ≤ 25s, 40% volume by day / 20% at night (the user's local time), and at most two actual plays per 10 minutes per machine regardless of how often cards render. Keep it conversational — one calm sentence beats a jingle, and loud audio gets dismissed, reported, and rejected in review.
Targeting
| axis | meaning |
|---|---|
| package types | Where the Blips runs: MCP servers, CLIs, agents, libraries, SaaS products, GitHub repos… |
| categories | The kind of tools your audience maintains (databases, security, devops…). |
| languages | The package's implementation language. |
| placements | Pick the CLIs, then the exact session moments (hook events). The picker leads with the recommended few — selecting too many trips a warning, because it earns dismissals. |
| countries | Include and exclude lists; empty = worldwide. |
| keywords | What the developer is working on — matched against sanitized session topics by the recommendation engine. The form suggests keywords from your copy as you type. |
Empty axes mean “no constraint”. Relevance also flows the other way: the engine reads your title, body, categories, and keywords, so well-written copy targets itself.
Bidding & the auction
Your CPC is a bid, not a price tag. Each serve ranks eligible campaigns by bid × predicted CTR × relevance — a relevant Blips with a modest bid routinely beats an expensive irrelevant one. Relevance blends the session's sanitized topics, the install's decaying interest profile (7-day half-life), and the surface itself — the package's type and categories. Budget pacing spreads delivery across the day and the campaign's flight; dismissals feed back as a negative signal. Start at $0.15–$0.30 for developer tools and raise for volume.
Escrow billing
- Submit — the campaign's full budget moves from your balance into escrow locked to that campaign.
- Serve — clicks accrue against the campaign during the day, alongside a small flat per-impression fee for every Blips shown. The dashboard shows the accrued amount as your pending debit, with the next settlement time.
- Settle — once every 24 hours, accrued clicks and per-impression fees debit the escrow. Fraud-held clicks never bill.
- Cancel — any time. Today's accrued clicks settle immediately; the entire unspent remainder returns to your balance in the same transaction.
Review lifecycle & editing
Every creative is human-reviewed before serving (see the network policy for standards). Rejections come with a written reason you see verbatim; fix and resubmit from the campaign page — funding stays locked, no re-charge. Audio creatives are listened to in full before approval.
Editing a running campaign: the edit button on your campaign opens the same editor, but saving takes the campaign off the air immediately and back through review (a confirmation dialog spells this out first). Budget, stats, and clicks-so-far are untouched.
The SDK
| package | install | role |
|---|---|---|
| opencrater | npm i opencrater | TypeScript — the full implementation: hook trigger + detached terminal painter (overlay cards, media, audio, waveform controls). What `npx opencrater on` wires up. |
| opencrater | npx opencrater on | The zero-code installer — wires the SDK into every detected CLI (Claude Code, Codex, Antigravity). Works for a tool written in any language. |
Any card on a machine shares the same local files (state, cooldowns, audio caps), so it behaves like one polite machine no matter how many tools enable cards.
import { sponsor } from "opencrater";
await sponsor.show({
publisherKey: "ock_YOUR_KEY",
packageName: "your-tool",
placement: "SessionEnd",
});Commands
| command | what it does |
|---|---|
| npx opencrater on | Install hooks for every detected CLI + the local runtime. |
| npx opencrater off | Remove everything; opted-out machines send nothing — not even the install ID. |
| npx opencrater x | Dismiss the card currently on screen (works offline; records the dismissal; starts that Blips' 10-minute local block). |
| npx opencrater status | What's installed, current config, last card. |
Environment variables
| variable | effect |
|---|---|
| OPENCRATER_DISABLE=1 | Full opt-out for this shell/CI — no rendering, no requests. |
| OPENCRATER_MUTE=1 | Cards render, audio never plays. |
| OPENCRATER_FLOW=1 | Flow mode: cards print additively into the session instead of overlaying (fully non-destructive). |
| OPENCRATER_DEBUG=1 | Verbose stderr logging — including the exact sanitized topic list before any request. |
| NO_COLOR | Monochrome cards. |
Politeness rules (enforced in code)
| rule | window | scope |
|---|---|---|
| Quiet gap between any two cards | remote-config default | machine-wide, all packages and hosts |
| Same Blips never repeats | 5 minutes | per campaign, per machine (local file) |
| ✕-dismissed Blips stays gone | 10 minutes | per campaign, per machine (local file — never uploaded) |
| ⚑-reported Blips stays gone | forever | per campaign, per machine (local file — never uploaded) |
| Audio actually plays | max 2× per 10 minutes | machine-wide, shared across all SDKs |
| Audio volume | 40% day / 20% night (local time) | every play |
| Audio length | 25 seconds hard cap | validated at upload, clamped at playback |
| Card lifetime | auto-dismiss countdown (admin-set default) | every card |
Local files
Everything lives under ~/.config/opencrater/: state.json (install ID, caps, caches), blocked-ads.json (dismiss cooldowns), reported-ads.json (⚑-reported campaigns — permanent local blocks), recent-renders.json (repeat cooldowns), audio-plays.json (audio window), last-ad.json (replay), runtime/ (the local SDK copy hooks prefer over npx; self-updates daily). Delete the directory for a complete reset. None of these files are ever uploaded — the privacy policy documents each one.
Compute wallet
The same Blips that pay maintainers also pay you, the developer running the terminal — in AI compute instead of cash. See cards while you code, bank weekly compute, and when you hit your Claude or Codex limit, spend that compute to keep going. Attention in, compute out.
It's a loop: opencrater login links this machine to your wallet, the hook credits you for the cards you see, and opencrater claude runs your coding agent on the balance. Your balance lives on your compute wallet.
Earning compute
npm i -g opencraterthenopencrater login— opens a browser, you paste a one-time token; this machine is now linked to your wallet (the token never expires).opencrater onwires the hooks (and pins a fast local runtime). Keep coding — the cards that appear at natural pauses now credit you.- New accounts get a one-time starter grant the moment you log in, so you can try
opencrater claudeimmediately. - Each ISO week your earnings from the impressions + clicks you saw (capped, plus a starter for new devs) are paid into your available balance, which rolls over. Unused compute expires only after 30 days untouched (oldest-first).
Check it any time with opencrater balance or on the dashboard. If you're signed in, Blips attribution always goes to your dev wallet — it takes precedence over any publisher key in the installed hook.
Spending it · opencrater claude / codex / grok
When you hit your weekly Claude, Codex or Grok limit, launch that same agent on OpenCrater compute:
opencrater claude # launch Claude Code on your earned compute opencrater claude -c # resume the exact Claude session your limit cut off opencrater codex # launch Codex on your earned compute opencrater codex -c # resume your last Codex session opencrater grok # launch xAI's Grok CLI on your earned compute opencrater grok -c # continue your last Grok session
What it does
It launches your coding agent on your earned compute for that session only — nothing on disk is touched, nothing lingers when you quit, and there's no "use this API key?" prompt. All arguments pass through, so opencrater claude -c / opencrater codex -c resumes your last session. Each request draws from your balance; run dry mid-session and you'll get a clear "out of compute" — go earn more, or switch back to your subscription.
The compute cards
Four OpenCrater system cards (not Blips — they carry no advertiser and cost nothing) guide you through the loop. They render on their own cadence, deliberately independent of the Blips frequency:
| card | appears when | shows |
|---|---|---|
| Limit | your plan is out of capacity AND you have compute | the one command to continue, for the CLI you're in (e.g. opencrater claude -c / opencrater codex -c) |
| Live usage | you're running on OpenCrater compute | % of weekly compute left, every few turns |
| Backup | you have compute, not yet switched | a periodic heads-up that backup compute is ready |
| Depleted | your balance hits zero | when your plan limit resets + a nudge to earn more |
The limit/reset cards rely on the host writing its capacity state to disk. Claude Code does (so they're precise there); Codex only persists plan dates, so on Codex the backup/usage/depleted cards still work but the exact limit/reset cards don't fire.
Compute FAQ
Is this real money?
No — it's AI compute you spend on your coding sessions, not a cash balance you can withdraw. (Maintainer earnings are the separate, cash-in-USDC side.)
Does it change my normal Claude/Codex setup?
No. opencrater claude only sets env for the process it launches; your normal claude keeps using your subscription. Use earned compute deliberately, when you've hit your limit.
Is clicking my own cards fraud?
No — for the wallet, you are the intended audience; engaging with cards in your own session is the whole model. (Publishers earning from Blips shown to other people is the thing that's fraud-gated — a separate concern.)
Does my token expire?
No — device tokens don't expire. Run opencrater login once per machine.
Compute troubleshooting
opencrater claude says I'm not signed in
Run opencrater login on this machine. The CLI and the hook read the same state file at ~/.config/opencrater/state.json — if login worked but the hook still credits a publisher, make sure you're on opencrater@latest (older builds resolved that path inconsistently between shells).
The card / Claude says I'm out of compute
Your weekly balance is spent. Keep coding (with cards on) to earn more next grant, or switch back to your own subscription. Check opencrater balance.
My earnings credited the package, not me
The hook only switches to dev attribution when it sees your token. Confirm opencrater balance shows you signed in, update to opencrater@latest, then start a fresh session.
The live-usage % looks off or missing
On a brand-new account, before your first weekly grant settles, the HUD may omit the percentage and just show the dollar balance. It refreshes on its own every few turns while you're running on earned compute.
Troubleshooting
Clicking ✕ or a link pops a trust dialog in VS Code
VS Code asks once per domain for ⌘-clicked links. The ✕ and the audio pause button talk to 127.0.0.1 (already trusted), so they never prompt; for the CTA link, accept the one-time prompt for the sponsor's domain — or add opencrater.to in Settings → Workbench: Trusted Domains.
Codex asks to approve a hook on first launch
By design — Codex requires a one-time TUI approval for any new hook (its trusted-hash mechanism cannot be pre-approved by an installer). Approve once and it never asks again.
No card appears
- Frequency cap or cooldowns — the quiet gap applies machine-wide, repeats are blocked 5 minutes, dismissed Blips 10 minutes.
npx opencrater statusshows where you stand. - Placement gating — the event that fired may not be in the package's selected placements for that host.
- Codex at SessionStart — boot repaint erases overlays; Codex renders at Stop.
- Run with
OPENCRATER_DEBUG=1— the hook logs exactly why it stayed quiet.
A card got stuck or the terminal looks off
npx opencrater x clears the card and nudges the host to repaint its frame. Cards also hard-expire on their own a few seconds after the countdown regardless of state.
More questions? The FAQ covers everything people actually ask — opt-out, earnings, billing, audio rules, fraud, USDC: