lullad
v0.1.8
Published
Turn agent wait time into LLM credits with rewarded sponsor messages
Downloads
1,051
Maintainers
Readme
Lullad — Earn Tokens While Your Agent Thinks
Your coding agent sits idle while it's thinking. Lullad turns that waiting line into one clickable sponsored line of text. View it or click it, earn token rewards, and spend them on LLM calls through our own gateway.
繁體中文 Running the platform yourself? See the deployment guide. Advertising on Lullad? See the advertiser guide. Administering a Lullad deployment? See the admin guide.
How it works
- An ad shows up only while your agent is thinking or executing — Claude Code uses a hook-gated bottom status line, OpenCode refreshes a short-lived plugin toast while busy, and Codex uses native turn hooks to control a working-only wrapper row.
- You view or click it. A view needs a few seconds of real, verified dwell time; a click needs to actually load the advertiser's landing page. Bots and replayed requests earn nothing — see What you earn below.
- The reward lands in your ledger as points, denominated so that 500,000 points = $1.
- You provision a gateway account in the User Portal and your points sync into real LLM quota.
- You point your agent's
base_urlat the gateway and spend that quota on actual model calls, same as any OpenAI-compatible endpoint.
The advertiser pays for the ad slot; you get paid in usable LLM credit for your attention; we keep the difference between ad revenue and what it costs us to supply those credits.
Quick start
# 1. Start login — the CLI opens a browser and shows a one-time code
npx lullad@latest login --api-base https://lullad.com
# 2. Sign up / sign in and approve the matching code in the browser
# The CLI finishes binding automatically; no token copy/paste is needed.
# 3. Wire it into your CLI of choice (see table below)
npx lullad@latest install claude-code --yes
# 4. Check your balance
npx lullad@latest status
# Show the built-in command guide, including complete uninstall instructions
npx lullad@latest help
npx lullad@latest help uninstall
# Check for a newer release and update a globally installed CLI
lullad updateOn interactive, user-facing commands, Lullad checks npm for a new CLI release at most once every 24 hours. Network failures stay silent; when a newer version exists, the CLI prints a one-line prompt to run lullad update. If you use npx, run commands as npx lullad@latest ... instead—there is no global installation to replace.
Every install has a dry-run (omit --yes to preview), backs up whatever it's about to touch, and can be fully reversed:
npx lullad@latest uninstall claude-code --yes # restores the previous status line and spinner settings
npx lullad@latest uninstall opencode --yes # removes the plugin, restores backup if one exists
npx lullad@latest uninstall codex --yes # removes only Lullad's Codex lifecycle hooksUninstall only removes Lullad's status line and lifecycle hooks; the previous status line, spinner preferences, and unrelated hooks are restored or preserved.
Early AdLine builds can be migrated safely with lullad migrate: a valid ~/.adline/config.json is copied to owner-only ~/.lullad/config.json without overwriting a current config. Verify with lullad status, then remove the old directory manually if desired. Chrome extension upgrades retain the same deviceToken storage key and prompt for a fresh Portal token only when the old credential is invalid or revoked.
Which CLI are you using?
| Platform | Command | How it works |
|---|---|---|
| Claude Code | lullad install claude-code --yes | Hook-gated bottom status line; visible only while Claude is working |
| OpenCode | lullad install opencode --yes | Plugin: refreshes a short-lived toast only while the session is busy |
| Codex | lullad install codex --yes, then lullad-run -- codex | Native turn hooks control the working-only wrapper row |
| Others (Gemini CLI, Aider, and other terminal CLIs) | lullad install others | Generic PTY wrapper with working-state detection |
Not on a CLI? The Chrome extension does the same thing inside Claude, ChatGPT, Gemini, and Grok's web apps — it watches for each site's own thinking/generating indicator and turns it into the same rewarded ad line, same balance, same gateway.
What you earn
- A verified ad view pays a small reward (subject to a minimum dwell time and a daily cap per user).
- A verified ad click pays a larger reward (also daily-capped).
- There's also a hard daily total cap across all reward types, so a single user can't out-earn the ad revenue funding them.
- Rewards only count if they're real: a replayed or bot-like event earns nothing (see the deployment guide for how that's enforced).
lullad status shows your running balance in both points and its dollar equivalent.
Invite a friend, both earn
Run lullad invite to get your personal invite link. When the invitee has actually watched enough ads to prove they're using the product (default: ten verified impressions, ~$0.002 of attention), you both get a one-time referral bonus (defaults to $0.05 each in ledger points). Rewards go through the same rules engine as ad views/clicks — same daily caps, same anti-fraud, so the loop is naturally throttled:
lullad invite # prints your invite URL + code
lullad login --invite <code> # browser login with referral attachedWhy deferred: paying at signup is trivially gameable (create fake accounts, cash out). Gating on real ad-watching means the referrer only earns when the invitee genuinely engages, and the invitee's own signup bonus is unlocked by the same act.
Spending your rewards
Rewards convert into quota on our LLM gateway (built on New API). Provision it in the User Portal to create the account, sync your balance, and receive an API key. The Portal shows usage and spend and lets you reveal or replace the key; you never log in to the gateway itself.
Wave 1 model lineup: the Codex family. More model families will come online as additional supply pools are added.
Why a gateway instead of just handing you an API key?
Your reward balance is just points in our ledger — it isn't, by itself, something you can spend anywhere. The gateway is what turns "points" into actually-usable, metered LLM access:
- Your points balance is enforced request-by-request. The gateway deducts quota as you use it, converted 1:1 from your points. That's what makes "you earn tokens, you spend tokens" a real constraint instead of an honor system.
- You never see or need real upstream credentials. Behind the gateway we run a two-tier supply (a subscription-based primary pool with an automatic pay-per-token fallback if it's ever unavailable) — you get one scoped API key with a quota ceiling, and it fails over transparently on our side. A leaked key of yours can't drain shared upstream accounts, because it was never one.
- Zero integration work. The gateway speaks the standard OpenAI-compatible API, so wiring it up is just changing your agent's
base_url— no new SDK, no special client.
Wiring Codex / Claude Code to the gateway
Open the User Portal first to provision the gateway and reveal or rotate its API key. Detailed usage logs are available there too; no gateway web login is involved. Everywhere you see <gateway-url> / <gateway-key>, substitute those two values.
Remember: wave 1 serves the Codex + gpt-5 series from ChatGPT Pro subscriptions. Available model IDs: gpt-5.3-codex-spark (the flagship Codex model), gpt-5.4-mini / gpt-5.4 / gpt-5.5 / gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna, plus gpt-image-{1,1.5,2} and codex-auto-review. There's no real Claude model behind the gateway yet, whichever client you point at it.
Sanity-check the key with a raw curl before wiring it into any CLI — it's an OpenAI-compatible Chat Completions endpoint:
curl <gateway-url>/v1/chat/completions \
-H "Authorization: Bearer <gateway-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.3-codex-spark",
"messages": [{"role": "user", "content": "say hi in five words"}]
}'A 401 means the key is wrong or expired; a no available channel ... under group error means the gateway account isn't in the default group yet (see the New API deployment notes).
Codex CLI
New API's OpenAI-compatible channel speaks the Chat Completions wire format, not the Responses API Codex defaults to — set wire_api = "chat" or requests will fail. Add a provider block to ~/.codex/config.toml:
[model_providers.lullad]
name = "Lullad Gateway"
base_url = "<gateway-url>/v1"
env_key = "LULLAD_GATEWAY_KEY"
wire_api = "chat"
model_provider = "lullad"
model = "gpt-5.3-codex-spark"export LULLAD_GATEWAY_KEY=<gateway-key>
codexClaude Code
Claude Code only ever speaks the Anthropic Messages API, so this only works if your New API deployment has the Claude-Messages-compatible endpoint enabled (a New API/Calcium-Ion feature — check your gateway's docs/version if the request 404s). Point ANTHROPIC_BASE_URL at the gateway root (no /v1) and pick one of the Codex-family model IDs above as ANTHROPIC_MODEL:
// ~/.claude/settings.json
{
"env": {
"ANTHROPIC_BASE_URL": "<gateway-url>",
"ANTHROPIC_AUTH_TOKEN": "<gateway-key>",
"ANTHROPIC_MODEL": "gpt-5.3-codex-spark",
"ANTHROPIC_SMALL_FAST_MODEL": "gpt-5.4-mini"
}
}This is separate from lullad install claude-code — that command only wires up the working-only sponsored status line (how you earn); the env block above is how you spend what you earned.
