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:

terminal
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

  1. Sign in at opencrater.to/signup (GitHub, Google, or GitLab).
  2. 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.
  3. 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.
  4. 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.
  5. 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.
your installer or postinstall (example)
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:

hosthook systemrecommended 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
codexhooks.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
openclawIn-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)

formatwhat rendersrequirements
textThe boxed card: sponsored label, bold amber title, body, CTA pill.Title ≤64 chars, body ≤200, https URL.
logoYour 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.
imageA square pixel-art thumbnail beside the text.Same as logo, minus the circle.
gif / videoAnimates in capable terminals (iTerm2, WezTerm, Kitty); still or text fallback elsewhere.Text fallback required. No strobing.
audioA 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

axismeaning
package typesWhere the Blips runs: MCP servers, CLIs, agents, libraries, SaaS products, GitHub repos…
categoriesThe kind of tools your audience maintains (databases, security, devops…).
languagesThe package's implementation language.
placementsPick 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.
countriesInclude and exclude lists; empty = worldwide.
keywordsWhat 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

  1. Submit — the campaign's full budget moves from your balance into escrow locked to that campaign.
  2. 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.
  3. Settle — once every 24 hours, accrued clicks and per-impression fees debit the escrow. Fraud-held clicks never bill.
  4. 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

packageinstallrole
opencraternpm i opencraterTypeScript — the full implementation: hook trigger + detached terminal painter (overlay cards, media, audio, waveform controls). What `npx opencrater on` wires up.
opencraternpx opencrater onThe 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.

TypeScript
import { sponsor } from "opencrater";

await sponsor.show({
  publisherKey: "ock_YOUR_KEY",
  packageName: "your-tool",
  placement: "SessionEnd",
});

Commands

commandwhat it does
npx opencrater onInstall hooks for every detected CLI + the local runtime.
npx opencrater offRemove everything; opted-out machines send nothing — not even the install ID.
npx opencrater xDismiss the card currently on screen (works offline; records the dismissal; starts that Blips' 10-minute local block).
npx opencrater statusWhat's installed, current config, last card.

Environment variables

variableeffect
OPENCRATER_DISABLE=1Full opt-out for this shell/CI — no rendering, no requests.
OPENCRATER_MUTE=1Cards render, audio never plays.
OPENCRATER_FLOW=1Flow mode: cards print additively into the session instead of overlaying (fully non-destructive).
OPENCRATER_DEBUG=1Verbose stderr logging — including the exact sanitized topic list before any request.
NO_COLORMonochrome cards.

Politeness rules (enforced in code)

rulewindowscope
Quiet gap between any two cardsremote-config defaultmachine-wide, all packages and hosts
Same Blips never repeats5 minutesper campaign, per machine (local file)
✕-dismissed Blips stays gone10 minutesper campaign, per machine (local file — never uploaded)
⚑-reported Blips stays goneforeverper campaign, per machine (local file — never uploaded)
Audio actually playsmax 2× per 10 minutesmachine-wide, shared across all SDKs
Audio volume40% day / 20% night (local time)every play
Audio length25 seconds hard capvalidated at upload, clamped at playback
Card lifetimeauto-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.

Earned compute is paid out weekly and rolls over — unused compute is reclaimed only if it sits untouched for 30 days. Between payouts, what you've earned shows as pending and becomes spendable at the next weekly grant. It's a backup for when your own subscription runs out — not a replacement for it.

Earning compute

  1. npm i -g opencrater then opencrater login — opens a browser, you paste a one-time token; this machine is now linked to your wallet (the token never expires).
  2. opencrater on wires the hooks (and pins a fast local runtime). Keep coding — the cards that appear at natural pauses now credit you.
  3. New accounts get a one-time starter grant the moment you log in, so you can try opencrater claude immediately.
  4. 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:

terminal
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:

cardappears whenshows
Limityour plan is out of capacity AND you have computethe one command to continue, for the CLI you're in (e.g. opencrater claude -c / opencrater codex -c)
Live usageyou're running on OpenCrater compute% of weekly compute left, every few turns
Backupyou have compute, not yet switcheda periodic heads-up that backup compute is ready
Depletedyour balance hits zerowhen 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

  1. Frequency cap or cooldowns — the quiet gap applies machine-wide, repeats are blocked 5 minutes, dismissed Blips 10 minutes. npx opencrater status shows where you stand.
  2. Placement gating — the event that fired may not be in the package's selected placements for that host.
  3. Codex at SessionStart — boot repaint erases overlays; Codex renders at Stop.
  4. 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:

Read the FAQ →