PRE-LAUNCH DOCUMENTATION
Build a useful scan.
QR images and structured payloads over HTTPS. Choose the authentication method for where your code runs.
Choose your path
- Server: use your secret
kv_live_key from an environment variable. Working image/payload endpoints are below. - Browser on this site: open the signed-in QR quickstart. No permanent API key needed.
- Your own website: needs its exact origin approved and Google sign-in configured. Not enabled automatically. CORS is not authentication.
- Android or iOS: the identity-token route is designed for signed-in clients. App registration and real-device verification are still required. No ready SDK or universal mobile support is claimed.
Access is limited to two approved Google identities. The account gate is not a public developer launch. Open the dashboard once to initialize your approved account.
Server quickstart
Create a key in the dashboard, copy it once into a server secret or environment variable, then dismiss it. Never paste the key into HTML, an APK, chat, a URL, screenshots or source control.
In the commands below, set KOVIO_API_KEY privately in your server environment. The example contains no working credential.
curl https://kovio-developers.n97485211.workers.dev/v1/qr \
-H "Authorization: Bearer $KOVIO_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"text":"Hello from Kovio","format":"png","size":320}' \
--output qr.pngNode.js18+ server example:
const r = await fetch(
'https://kovio-developers.n97485211.workers.dev/v1/qr', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KOVIO_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({text:'Hello from Kovio', format:'png', size:320})
});
if (!r.ok) throw new Error(`Kovio ${r.status}: ${await r.text()}`);
await (await import('node:fs/promises')).writeFile(
'qr.png', new Uint8Array(await r.arrayBuffer())
);Use the same pattern from Python, Java, Go or any HTTPS-capable server. Those language integrations have not each been independently tested. Do not blindly retry a POST after an uncertain network failure: a completed request may already have consumed quota. Idempotency keys are not implemented.
HTML and browser integration
The hosted quickstart demonstrates a real browser request. It uses Firebase Google sign-in, obtains the current user's short-lived identity token, and calls the client endpoint. The token authenticates the person, not a permanent shared application secret.
// After Firebase Google sign-in in the configured project:
const idToken = await auth.currentUser.getIdToken();
const r = await fetch('/client/v1/qr', {
method:'POST',
headers:{Authorization:`Bearer ${idToken}`, 'Content-Type':'application/json'},
body:JSON.stringify({text:'Hello from my page', format:'png', size:320})
});
if (!r.ok) throw new Error(`Kovio ${r.status}`);
const image = await r.blob();The snippet assumes Firebase has already been initialized and Google sign-in completed; it is not a complete standalone login implementation. The hosted page loads its SDK bundle and stylesheet from this same site. Downloading only its HTML does not turn it into an offline app.
For your own host, provide the exact HTTPS origin (scheme, host and port) for approval and configure the sign-in domain. Local development needs an explicitly approved localhost origin. A downloaded file:// page has an opaque/null origin and is not enabled. Do not work around this with mode:'no-cors' or by embedding a server key.
Only the client image/payload routes are intended for client CORS. Dashboard key-management endpoints remain restricted to the dashboard origin. Tokens stay in the authentication session; never log, share or put them in request URLs. A stolen token can still be abused during its lifetime. Short-lived does not mean public.
Android and other native clients
Use the platform's supported Google/Firebase sign-in flow, then obtain a fresh Firebase ID token and send it through HTTPS Bearer authentication to /client/v1/qr or /client/v1/payload. Do not ship a permanent kv_live_ key in the app package. CORS is a browser rule, not protection against native clients.
Before claiming Android readiness we need the app's package identity, signing certificate registration and a physical-device test. This release does not register a new app, ship an Android SDK, or prove native sign-in works. The same distinction applies to iOS. System/browser-based authorization is preferable to collecting Google credentials inside a custom WebView.
Endpoint reference
Image: POST /v1/qr for server keys; POST /client/v1/qr for verified user tokens. JSON in; image/png or image/svg+xml out.
text: nonempty string, at most1600 UTF-8 bytes. Character count can differ from byte count.- Or
payload: a structured payload object. Do not send both text and payload. format:pngorsvg, defaultsvg.size: integer128-1024, default320.errorCorrection:L,M,Q,H, defaultM. Dense data may need more pixels or a lower correction level.
{"payload":{"type":"url","url":"https://example.com"},
"format":"svg","size":512,"errorCorrection":"M"}Encoded text only: POST /v1/payload or POST /client/v1/payload. Returns JSON, not an image:
Request: {"type":"url","url":"https://example.com"}
Response: {"text":"https://example.com/"}Payload builders include text, URL, Wi-Fi, email, phone, SMS, vCard, geo and UPI. UPI only encodes supplied data; it does not verify the payee or any payment. Use the image endpoint with payload when you want a QR image in one call.
Requests must use Content-Type: application/json. Body limit4096bytes. Unknown fields and URL query strings are rejected. Images are generated per request; this API does not host a persistent QR image URL or store an editable destination.
Errors and free limits
Errors are JSON: {"error":"machine_readable_code"}. Read HTTP status and the error code together. Do not send raw credentials or personal payloads when asking for help.
- 400: malformed JSON, unsupported fields, invalid size/format or payload.
- 401: missing/expired/invalid identity or API key. Sign in again for client calls; check/reissue the server key privately for server calls.
- 403: account not approved, disallowed origin, or account not initialized. A CORS error in a browser may hide the response body.
- 404/405: wrong route/query or method. Generation endpoints accept POST.
- 409: active key limit when creating a key.
- 422: content too dense or image too small for the encoded data.
- 429: request, account, signup, AI or global free limit. Inspect the error code. The response includes
Retry-After:60, but a daily limit will not reset in one minute. - 503: temporarily unavailable. Health status alone is not a database, billing or readiness guarantee.
Accepted generation calls share100/account/day and10/minute across server keys and client identities;5,000/day globally. Daily counters reset at00:00 UTC. Extra attempt guards can reject requests sooner. Two active server keys/account,30-day expiry, at most5 key creations/day. Signups remain closed except the two approved accounts. No payment, paid fallback, uptime promise or automatic upgrade.
Successful image/payload responses include X-RateLimit-Remaining for the account's remaining daily quota. Per-request IDs, full SDKs, webhook delivery and idempotent retry storage are not implemented. They should not be inferred from other providers' docs.
Security and privacy checklist
- Shared an HTML file containing a real key? Disable sharing and revoke that key. Masked dots do not protect source code. Do not send the key to support.
- Use HTTPS. Keep server keys in server-side secret storage. Restrict application access separately from CORS.
- OpenAI's API docs likewise require standard keys to stay server-side. Its special Realtime ephemeral-token flow is a useful pattern, not a feature Kovio copied or a paid integration Kovio enabled.
- API QR text goes to Kovio for rendering. AI help is separate and sends chat messages to Cloudflare Workers AI. Do not send secrets to chat. Gmail reporting is not connected.
- Inspect and scan generated codes before relying on them, especially payment/contact details. No scanner or destination-safety guarantee is implied.
References: OpenAI API overview, Firebase ID tokens, Native app authorization, CORS/null origins.