API Reference

Base URL https://api.reviewintelligence.dev/v1 · local http://localhost:3000/v1. All responses are JSON and include an X-Wizer-Request-Id header plus X-RateLimit-* headers.

Quickstart

Run the API locally in mock mode (no credentials needed):

npm install
npm run dev          # boots on :3000 in mock mode
# authenticate with the dev key printed at startup:
curl localhost:3000/v1/analyze \
  -H "Authorization: Bearer rik_local_dev_key" \
  -H "Content-Type: application/json" \
  -d '{"text":"Great product, slow shipping","options":{"suggest_reply":true}}'

Authentication

Send your key as a bearer token. Keys are shown once and stored only as a hash.

Authorization: Bearer rik_live_xxx

Errors

Every error uses a stable envelope:

{ "error": { "code": "rate_limited", "message": "Too many requests", "request_id": "req_..." } }
HTTPcode
400invalid_request
401unauthorized
402quota_exceeded
404not_found
422unprocessable
429rate_limited
503ai_unavailable

Agent payments (x402)

Autonomous agents can pay per call in USDC with no account and no API key via the x402 protocol. This works on the REST /v1 routes only — the MCP servers and the dashboard still require a rik_/cik_ key. Live on Base mainnet.

Flow. An unauthenticated request returns 402 with payment requirements; an x402 client signs a gasless EIP-3009 payment and retries; the server verifies, runs the analysis, settles on-chain, then returns 200 + the result. The settlement transaction hash comes back in the PAYMENT-RESPONSE header (also mirrored as X-PAYMENT-RESPONSE).

$ curl -i -X POST https://api.reviewintelligence.dev/v1/analyze \
    -H "Content-Type: application/json" \
    -d '{"text":"Great product, slow shipping"}'

HTTP/1.1 402 Payment Required
payment-required: <base64 payment requirements>
{
  "x402Version": 2,
  "accepts": [ {
    "scheme":  "exact",
    "network": "eip155:8453",
    "asset":   "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo":   "0x14a129b3e3Bd154c974118299d75F14626A6157B",
    "amount":  "10090",
    "maxTimeoutSeconds": 300,
    "extra": { "name": "USD Coin", "version": "2" }
  } ]
}

Network Base mainnet (CAIP-2 eip155:8453) · Asset USDC 0x833589…2913 · Gasless — the facilitator sponsors gas, so the buyer needs zero ETH.

Pricing $0.01 per AU, $0.01 minimum per call. amount is USDC atomic units (6 decimals): 10090 = $0.0101. A short review analyze ≈ $0.01; a short contract analyze ≈ $0.12.

Any request carrying an Authorization header skips x402 and uses normal key auth — so a 402 here is a payment challenge (it carries the payment-required header), distinct from the quota_exceeded 402 an over-quota key receives.

Independently verified. The third-party scanner 402audit scores this endpoint on whether it's proprietary or a thin proxy — check it yourself:
402audit verdict for /v1/analyze

POST /v1/analyze · 1 AU + 1/4,000 chars

{ "text": "Checkout was fast but support never replied.",
  "rating": 3, "options": { "suggest_reply": true, "reply_tone": "professional" } }
{ "id": "...", "sentiment": { "score": -0.18, "label": "negative", "confidence": 0.81 },
  "emotion": "frustration", "topics": ["checkout speed","support"], "language": "en",
  "suggested_reply": "Thanks for the feedback...", "usage": { "au_cost": 1 } }

POST /v1/analyze/batch · 1 AU/review + 1/4,000 chars

Asynchronous. Returns 202 with a job id; poll /v1/jobs/:id or receive a signed webhook.

{ "reviews": [ { "external_id": "r1", "text": "Love it" } ], "webhook_url": "https://..." }
→ { "job_id": "...", "status": "queued", "review_count": 1, "estimated_au": 1 }

POST /v1/themes · 4 AU + 1/1,250 chars

{ "reviews": ["...","..."], "max_themes": 8 }
→ { "themes": [ { "label": "onboarding", "frequency": 14, "sentiment": -0.42, "examples": ["..."] } ] }

POST /v1/summarize · 6 AU + 1/1,250 chars

{ "reviews": ["...","..."], "audience": "product_team" }
→ { "summary": { "headline": "...", "highlights": [], "lowlights": [], "recommended_actions": [] } }

POST /v1/respond · 1 AU

{ "text": "Waited 40 minutes and the food was cold.", "tone": "apologetic" }
→ { "reply": "We're truly sorry...", "tone": "apologetic", "usage": { "au_cost": 1 } }

Projects & ingestion

POST /v1/projects                 { "name": "Acme", "store_text": true }
POST /v1/projects/:id/ingest      { "reviews": [ { "text": "..." } ] }

GET /v1/jobs/:id

{ "job_id": "...", "status": "completed", "result": { "reviews": [...], "aggregate": {...} } }

GET /v1/usage

{ "plan": "growth", "period": "2026-06", "included_au": 40000,
  "used_au": 12480, "remaining_au": 27520, "overage_au": 0,
  "rate_limit": { "limit_per_min": 240 } }

POST /v1/webhooks

Deliveries are signed: header X-Webhook-Signature: sha256=<hmac> over the raw body.

{ "url": "https://example.com/hooks/ria", "events": ["job.completed","job.failed"] }
→ { "id": "...", "signing_secret": "whsec_review_intelligence_...", "active": true }