Documentation

Everything you need to go from sign-in to a paying customer.

Getting started

  1. Sign in with Google at lumencredits.com/signin and create an app in the dashboard. Its slug becomes your customer site: your-slug.lumencredits.com.
  2. Connect provider keys on the app's Edit page — Gemini, OpenAI, Claude, and/or Soniox. Keys are stored encrypted and never exposed to your customers.
  3. Connect PayPal — your merchant Client ID, secret, and webhook ID. Point the PayPal webhook at https://lumencredits.com/api/_platform/tenant-paypal/webhook (one URL for all your apps). Customer payments land directly in your PayPal.
  4. Set pricing on the app's Pricing page — what each model costs your customers in credits (see below) — and create credit offers on the Offers page.
  5. Share your storefront — customers sign in with Google, buy credits with PayPal, and call your app.

Your customer storefront

Every app gets a hosted site at your-slug.lumencredits.com with sign-in, pricing, checkout, and account pages. On the app's Edit page you control the headline, tagline, hero image (PNG/JPEG/WebP, max 2 MB — also used as the social-share image), and a markdown description. Toggle "List in the public directory" to appear on Apps on platform.

Pricing: tokens, uses, and credits

You price each provider modality per token (usd_per_token) and define a human-friendly "use" (tokens_per_use + a unit name — e.g. 1500 tokens = one minute of audio). Customers see prices in credits: credits = USD × credit display rate, which you set per app.

Important: offer amounts (amount_audio_seconds etc.) are counted in your pricing uses — if your audio unit is a minute, an offer granting 10 hours is 600, not 36000. The dashboard Pricing page has an "Update all prices" button that applies platform-published provider cost tables (current tables), keeping your units untouched.

The metered API

Base URL: https://api.lumencredits.com. Your customers mint API keys on their storefront account page; your app sends them as Authorization: Bearer <key> (or x-api-key). Every call is metered per token against your prices and deducted from that customer's credit balance — you never meter anything yourself.

EndpointWhat it proxies
/gemini/v1beta/*, /gemini/v1/*Google Gemini REST (generateContent, streaming, images)
/gemini/voice (WebSocket)Gemini Live voice sessions (audio in/out, Opus or PCM)
/openai/v1/*OpenAI REST (chat completions, images)
/claude/v1/*Anthropic Claude REST (messages)
/soniox/v1/*, /soniox/stt, /soniox/ttsSoniox speech-to-text and text-to-speech (REST + realtime WebSocket)
/app/:slug/creditsThe calling customer's credit balance

Requests use the provider's native request/response format — point your existing SDK at the base URL above and swap the provider key for the customer's Lumen key. Working code: live API examples (sign-in required).

Letting users sign in from your app — device login

Device login gets a customer API key into your app without you ever handling passwords, and works everywhere — web, desktop, mobile, TVs, CLIs. Your app shows a link (or short code); the user approves it in their browser; your app receives the key over a server-sent-events stream.

The flow, step by step

  1. Generate a secret device_code in your app — at least 20 characters; use 32 random bytes, base64url-encoded. This is the credential that claims the key later, so make it truly random and never show it to anyone.
  2. Start the login:
    POST https://api.lumencredits.com/app/<slug>/device/start
    { "device_code": "<random>",
      "redirect_uri": "https://yourapp.example/welcome",   // optional
      "auto_redirect": true }                              // optional
    redirect_uri is where the approver's browser continues after approving. It must be on your app's allowed redirect URIs list (Edit page) — exactly like OAuth; a URI not on the list is rejected with 403. auto_redirect: true makes the login link carry &auto_redirect=1, so the browser continues there automatically instead of showing a "Continue" button.
    Response:
    { "user_code": "BCDF2345",
      "verification_uri": "https://lumencredits.com/apps/<slug>/device",
      "verification_uri_complete": "https://lumencredits.com/apps/<slug>/device?user_code=BCDF2345&auto_redirect=1",
      "interval": 5, "expires_in": 600 }
  3. Show the user the login link — open verification_uri_complete directly, render it as a QR code, or tell them to visit verification_uri and type the short user_code. The code expires after 10 minutes.
  4. The user approves on that page (Google sign-in). If you set a redirect_uri, their browser then continues to your app — immediately with auto_redirect, otherwise via a "Continue to the app →" link.
  5. Your app receives the key. Listen on SSE while you wait:
    GET https://api.lumencredits.com/app/<slug>/device/events?device_code=<random>
    event: approved   data: { "key": "lk_…", "key_prefix": "lk_ab…" }
    event: expired
    If the SSE connection drops, fall back to polling every interval seconds:
    POST https://api.lumencredits.com/app/<slug>/device/poll
    { "device_code": "<random>" }
    → { "status": "pending" } | { "status": "approved", "key": "lk_…" } | { "status": "claimed" } | { "status": "expired" }
  6. Store the lk_ key (e.g. localStorage / keychain) and use it for every metered API call and the voice socket. The key is delivered exactly once — a second poll returns claimed. Users can revoke keys from their storefront account page.

Security properties

Working end-to-end code: the live API example (sign-in required) logs in with this exact flow.

What Lumen Credits costs you

Your customers pay you directly via PayPal — no revenue share. You pay a small metered platform fee for hosted infrastructure and token counting; current rates, the free signup grant, and a worked example are on the Pricing page. Your platform balance and usage are on the dashboard Billing page.

Troubleshooting

Rejected API calls (missing key, unpriced model, upstream provider errors) are recorded per app — see the Errors tab on each app in the dashboard. Billing or setup questions: [email protected].