# Kreward External API — LLM Reference Base URL: https://api.kreward.net/v1 Auth: Authorization: Bearer (kw_pub_... or kw_sk_...) Content-Type: application/json ## Keys - PUBLIC key (kw_pub_...): safe in frontend JS. Enroll only. Domain-restricted. - SECRET key (kw_sk_...): server-side only. Full access. Never expose in frontend. ## Endpoints ### GET /v1/ping — health check (no auth) curl https://api.kreward.net/v1/ping Response: { "ok": true, "service": "kreward-api", "version": 1, "ts": "..." } ### GET /v1/me — account info (public or secret) curl https://api.kreward.net/v1/me -H "Authorization: Bearer kw_sk_SECRET" Response: { "ok": true, "merchant": { "name", "slug", "plan", "card_type" }, "key": { "type", "label", "created_at", "last_used_at", "request_count" } } ### POST /v1/enroll — enroll customer + wallet QR (public or secret) Body: email (string, optional), name (string, optional) If email omitted: returns { mode: "anonymous", enrollment_url, qr_code }. With email: { ok, mode: "with_email", customer: { email, name, is_new }, card: { id, type, balance, status, stamps_collected?, stamps_total? }, wallet: { ios_url, android_url, qr_ios, qr_android } } Tip: Display qr_ios/qr_android as tag — no file storage needed. ### GET /v1/customer?email= — query balance (secret only) Query: email (required) Response: { ok, customer: { email, name, card_id, status, created_at, last_seen_at }, card: { type, balance, stamps_collected?, stamps_total?, progress_pct? } } ### POST /v1/transaction — add or deduct points/stamps (secret only) Body: email (required), delta (non-zero integer, |delta| <= 100000), note (optional) Response: { ok, transaction_id, delta, balance_before, balance_after, card_type, stamps_collected?, stamps_total? } ### POST /v1/redeem — claim a reward tier (secret only) Tiers are milestones identified by their "at" threshold (see GET /v1/customer). Claiming a tier marks it redeemed; it does NOT spend balance — EXCEPT redeeming the final stamp milestone (at == stamps_total) on a stamps card, which loops the card (balance := overflow, milestones re-arm). Body: email (required), at (positive integer — the tier threshold to claim) Response: { ok, redeemed_at, looped, redeemed_tiers, balance_before, balance_after, card_type } ## Error format All errors return JSON: { "error": "error_code", "message"? } HTTP 400 Bad request (missing_email, invalid_at, no_such_tier, not_unlocked, already_redeemed, invalid_delta) | 401 missing/invalid key 403 plan_required / origin_not_allowed / secret_key_required HTTP 404 not_found | 429 rate_limited (100/min) | 500 internal_error ## Security - Never put secret key in frontend code. Use environment variables. - Restrict public key by allowed origins in the API dashboard. - Revoke and regenerate keys immediately if compromised. - HTTPS only. Rate limit: 100 req/min per key. ## Plans API requires Growth (HK$450/month) or Enterprise plan. Dashboard: https://kreward.net/dashboard/api