Have an AI set up smidgen for you
This document is the source of truth for coding agents (Cursor, Claude Code, Copilot, Aider, and similar) that set up and manage smidgen for a human publisher.
Read this file completely before calling any API. Do not invent endpoints. Do not skip the human signup or approval steps.
Preferred path: npx @smidgendotio/cli (login, init, doctor). Raw HTTP is the fallback if the CLI cannot run.
- HTML version: https://smidgen.io/integrations/publisher-agents
- This markdown: https://smidgen.io/integrations/publisher-agents.md
- OpenAPI: https://smidgen.io/integrations/publisher-agents/openapi.json
- CLI: https://smidgen.io/integrations/publisher-agents (and GitHub
packages/cli) - Agent catalog: https://smidgen.io/.well-known/ai-catalog.json
- LLM index: https://smidgen.io/llms.txt
Two kinds of agents (do not mix them)
1. Paying agents (x402 buyers) discover paid URLs, receive HTTP 402, pay USDC, and retry. They never create a smidgen account. Guide: https://smidgen.io/integrations/agents 2. Publisher coding agents (you) help a human ship a paywall on their site. The human owns the account. You hold a delegated token after they approve you.
If you were asked to *pay* for content, stop and use https://smidgen.io/integrations/agents instead.
What you must never do
- Do not create a smidgen account. There is no signup API.
- Do not ask the publisher to paste a magic-link URL or session cookie into chat.
- Do not commit
smid_ag_orsmid_sk_tokens to git. Put them in ignored env files. - Do not change payout wallets on an existing project. The API rejects that. The publisher updates payouts in the dashboard.
- Do not use a Publisher API key (
smid_sk_) as an agent token. Those keys only sync WordPress rules for one project. - Do not log tokens.
Step 0 — Publisher creates the account
Ask the publisher to:
1. Open https://smidgen.io/login 2. Sign in with email (magic link) or a wallet (MetaMask on Base, or Phantom on Solana) 3. Confirm they can see https://smidgen.io/dashboard 4. Come back to you when that is done
Wait. Do not continue until they confirm they are signed in.
Free plan: 1 project, 5 paywall rules, one chain (Base or Solana). Plan limits return HTTP 403 with code PROJECT_LIMIT, RULE_LIMIT, or CHAIN_LIMIT.
Preferred — CLI (do this unless it cannot run)
npx @smidgendotio/cli login
npx @smidgendotio/cli init --name "Blog" --site https://example.com --evm-wallet 0xYourBaseAddress --path "/premium/*" --stack next
npx @smidgendotio/cli doctor --url https://example.com/premiumPackage: https://www.npmjs.com/package/@smidgendotio/cli
login runs RFC 8628 device authorization: it prints a URL + user code, the publisher clicks Authorize, and the token is stored in ~/.smidgen/credentials.json (not git). init creates the project and a paywall rule, writes .env.local (gitignored), and for --stack next writes middleware.ts if missing. doctor GETs the publisher URL as a bot and expects HTTP 402.
Ask for the site URL and the payout wallet before init. Stacks: next (default), html, wordpress (mints smid_sk_ into .env.local).
If npx cannot run, use the curl fallback below (or npm run smidgen from the smidgen git repo as a maintainer).
CLI reference
| Command | Purpose |
|---|---|
login | Device authorization. Publisher authorizes. Token → ~/.smidgen/credentials.json (90 days; revocable) |
init | Create project + rule; write .env.local; for next, write middleware.ts if missing |
doctor --url URL | GET URL as a bot; expect HTTP 402 |
whoami | Confirm the saved token |
logout | Delete the saved token |
init flags:
--name(required) — project name--site(required) — publisher origin, e.g.https://example.com--evm-wallet/--solana-wallet— payout addresses (at least one)--path— paywall path pattern (default/premium/*)--price-cents— USDC cents (default10)--stack—next(default) |html|wordpress--force— overwritemiddleware.tsif it exists--api— API origin (defaulthttps://smidgen.io)--json— machine-readable output (also onlogin/whoami/doctor)
Env: SMIDGEN_API_URL (API origin), SMIDGEN_AGENT_TOKEN (use instead of credentials file).
init never changes payout wallets on an existing project.
Fallback — device authorization (RFC 8628)
The publisher approves you in the browser. They never paste a secret into chat.
1a. Request a device code
curl -sS -X POST https://smidgen.io/api/v1/agent/device/code \
-H "Content-Type: application/json" \
-d '{"client_name":"Cursor"}'Example response:
{
"device_code": "high-entropy-secret-for-you-only",
"user_code": "WDJB-MJHT",
"verification_uri": "https://smidgen.io/device",
"verification_uri_complete": "https://smidgen.io/device?user_code=WDJB-MJHT",
"expires_in": 900,
"interval": 5
}Keep device_code secret (it is not the user code). Show the publisher verification_uri_complete and the user_code.
Codes expire in 15 minutes. Poll no faster than interval seconds or you get slow_down.
1b. Publisher approves
Tell the publisher, verbatim:
> Open this URL while signed into smidgen, confirm the code matches USER_CODE, and click Authorize this agent: VERIFICATION_URI_COMPLETE
If they are not signed in, the page sends them to login and returns to /device.
1c. Poll for the access token
curl -sS -X POST https://smidgen.io/api/v1/agent/device/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=DEVICE_CODE"JSON is also accepted: {"grant_type":"urn:ietf:params:oauth:grant-type:device_code","device_code":"DEVICE_CODE"}.
Poll every interval seconds until one of:
| HTTP | `error` | Meaning |
|---|---|---|
| 400 | authorization_pending | Not approved yet. Keep polling. |
| 400 | slow_down | You polled too fast. Wait longer, then continue. |
| 400 | expired_token | Start again from 1a. |
| 400 | access_denied | Publisher clicked deny. Stop. |
| 400 | invalid_grant | Bad or already-used device_code. |
| 200 | (none) | Success. Save access_token. |
Success body:
{
"access_token": "smid_ag_…",
"token_type": "Bearer",
"expires_in": 7776000,
"scope": "projects:read projects:write rules:write keys:write"
}Store access_token as SMIDGEN_AGENT_TOKEN in a local env file that is gitignored. The token is shown once. Default lifetime is 90 days. The publisher can revoke it at https://smidgen.io/dashboard/settings.
Alternative: dashboard token
If preferred, the publisher can open https://smidgen.io/dashboard/settings → Connect an agent → generate a token → paste smid_ag_ into your env. Same API after that. Prefer device flow so the secret never sits in the chat.
Step 2 — Confirm the token
curl -sS https://smidgen.io/api/v1/agent/me \
-H "Authorization: Bearer smid_ag_…"Expect user.plan and token.scopes. If 401, the token is wrong, expired, or revoked.
Step 3 — Create a project
You may set the payout wallet only when creating the project. Ask for the address USDC should go to (MetaMask 0x… on Base, and/or Phantom on Solana). You cannot change it later via this API.
curl -sS -X POST https://smidgen.io/api/v1/agent/projects \
-H "Authorization: Bearer smid_ag_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Blog",
"siteUrl": "https://example.com",
"evmEnabled": true,
"evmWallet": "0xYourBaseAddress",
"evmNetwork": "eip155:8453"
}'Solana instead (or in addition on Pro/Business):
{
"name": "Blog",
"siteUrl": "https://example.com",
"solanaEnabled": true,
"solanaWallet": "YourSolanaBase58Address",
"solanaNetwork": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
}Common networks:
- Base mainnet:
eip155:8453 - Base Sepolia:
eip155:84532 - Solana mainnet:
solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp - Solana devnet:
solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
Response project.id is the public id (smid_…). Use that in every later path. It is not a secret.
List projects: GET https://smidgen.io/api/v1/agent/projects
Update name, site URLs, or default price (not payouts):
curl -sS -X PATCH https://smidgen.io/api/v1/agent/projects/smid_PROJECT \
-H "Authorization: Bearer smid_ag_…" \
-H "Content-Type: application/json" \
-d '{"siteUrl":"https://example.com\nhttps://www.example.com","defaultPriceCents":10}'defaultPriceCents is USDC cents (10 = $0.10).
Step 4 — Paywall rules
curl -sS -X PUT https://smidgen.io/api/v1/agent/projects/smid_PROJECT/rules \
-H "Authorization: Bearer smid_ag_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Premium article",
"pathPattern": "/premium/*",
"selector": "premium-article",
"selectorType": "data-attribute",
"priceCents": 10,
"enabled": true,
"origin": "https://example.com"
}'selectorType is data-attribute, class, or css-selector. For the HTML snippet, mark content with data-x402-paywall="premium-article" matching selector.
List: GET https://smidgen.io/api/v1/agent/projects/smid_PROJECT/rules Delete: DELETE https://smidgen.io/api/v1/agent/projects/smid_PROJECT/rules/RULE_UUID
Then install the matching publisher integration so the publisher origin returns HTTP 402 (not smidgen.io): https://smidgen.io/integrations
Step 5 — WordPress Publisher API key (optional)
WordPress uses a different key (smid_sk_), bound to one project:
curl -sS -X POST https://smidgen.io/api/v1/agent/projects/smid_PROJECT/publisher-key \
-H "Authorization: Bearer smid_ag_…"Shown once. Paste into WordPress → Settings → smidgen.io with API URL https://smidgen.io and the project id. Then enable Paywall this content on posts (rules sync; you usually do not PUT rules by hand).
Scopes
Default device-flow tokens include:
projects:read— List and read your projectsprojects:write— Create projects and update site URLs / default price (not payout wallets after create)rules:write— Create, update, and delete paywall ruleskeys:write— Mint or rotate the WordPress Publisher API key (smid_sk_…)
There is no payouts:write scope. After create, payout changes are dashboard-only.
Security model (why this is safe)
- Identity: the publisher proves email or wallet at signup. You cannot mint users.
- Delegation: RFC 8628 device grant. The publisher sees the user code and scopes before authorize.
- Storage: tokens hashed SHA-256 at rest; raw value shown once; prefix only in the dashboard.
- Least privilege: no payout mutation, no billing, no account delete.
- Revocation: https://smidgen.io/dashboard/settings
- Rate limits on device code, polling, and API calls.
smid_ag_(you) vssmid_sk_(WordPress) vssmid_(public project id).
After setup
- Humans pay in the browser; bots pay via x402 on the publisher domain. Paying-agent snippets: https://smidgen.io/integrations/agents
- Catalog from rules:
/.well-known/ai-catalog.jsonon the publisher site. Hub catalog: https://smidgen.io/.well-known/ai-catalog.json - Coinbase Bazaar can list a URL after the first successful settle.
If anything 401s, stop and have the publisher revoke + re-approve. If 403 with a plan code, explain the Free-plan cap and the pricing page https://smidgen.io/pricing.