{"openapi":"4.0.0-candidate","info":{"title":"toolfactory API","version":"0.1.0","description":"Credit-metered cloud tools (subtitle transcription, and more)."},"paths":{"api/health":{"requests":{"health":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}},"required":["ok","service"],"additionalProperties":false}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Liveness check.","tags":["System"],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"one Worker request, static JSON"}],"estimateMicroUsd":1,"lever":"free-liveness"}}}},"api/auth/get-session":{"requests":{"getSession":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"anyOf":[{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"}},"required":["id"],"additionalProperties":false}},"required":["user"],"additionalProperties":false},{"type":"null"}]}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The current Better Auth session, or null when signed out.","tags":["Session"],"x-suluk-access":{"requires":"anyone"},"x-suluk-store":{"key":"session","ttl":300,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"~2 session/user row reads"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/credits":{"requests":{"getCredits":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["balance"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's credit balance.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Credits"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"credits","ttl":300,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"SUM(delta) ledger aggregation"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/credits/transactions":{"requests":{"listTransactions":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"delta":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reason":{"type":"string"},"createdAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amountCents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","delta","reason","createdAt","amountCents"],"additionalProperties":false}}},"required":["transactions"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's recent credit ledger (grants, subscription credits, and usage debits), newest first.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Credits"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"transactions","ttl":30,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"recent ledger rows by user, limit 10"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/logs":{"requests":{"getLogs":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"series":{"type":"array","items":{"type":"object","properties":{"t":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["t","count","credits"],"additionalProperties":false}},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"type":{"type":"string","enum":["grant","usage"]},"op":{"type":"string"},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"keyName":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","at","type","op","credits","keyName"],"additionalProperties":false}},"range":{"type":"string","enum":["1d","7d","30d"]},"error":{"type":"string"}},"required":["series","events","range"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's Activity, queryable Splunk-style: a bucketed event timeseries + matching ledger events. `q` filters by type=grant|usage, op (=/!=/~contains), and credits (numeric); `range` picks the window (1d/7d/30d).","parameterSchema":{"query":{"type":"object","properties":{"q":{"type":"string","maxLength":200,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"range":{"type":"string","enum":["1d","7d","30d"]}},"additionalProperties":false}},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Activity"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"logs","ttl":30,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"hourly group-by aggregation + recent-usage select"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/billing/packs":{"requests":{"getPacks":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"packs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"priceCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"label":{"type":"string"}},"required":["id","credits","priceCents","label"],"additionalProperties":false}}},"required":["packs"],"additionalProperties":false}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Available credit packs (server-authoritative pricing).","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"ip"},"tags":["Billing"],"x-suluk-access":{"requires":"anyone"},"x-suluk-store":{"key":"packs","ttl":3600},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"static CREDIT_PACKS JSON, zero I/O"}],"estimateMicroUsd":1,"lever":"rate-limit"}}}},"api/billing/plans":{"requests":{"getPlans":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"plans":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"priceCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"label":{"type":"string"}},"required":["id","name","credits","priceCents","label"],"additionalProperties":false}}},"required":["plans"],"additionalProperties":false}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Available subscription plans (server-authoritative pricing) — recurring monthly credits at the subsidized rate.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"ip"},"tags":["Billing"],"x-suluk-access":{"requires":"anyone"},"x-suluk-store":{"key":"plans","ttl":3600},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"static SUB_PLANS JSON, zero I/O"}],"estimateMicroUsd":1,"lever":"rate-limit"}}}},"api/billing/checkout":{"requests":{"checkout":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Start a Stripe Checkout for a CUSTOM credit top-up (amount in cents, $1–$1000); returns the hosted checkout URL.","contentType":"application/json","contentSchema":{"type":"object","properties":{"amountCents":{"type":"integer","minimum":100,"maximum":100000}},"required":["amountCents"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"stripe","basis":"per-call","microUsd":0,"description":"checkout/sessions create is free; 2.9%+30¢ lands on the webhook"}],"estimateMicroUsd":1,"lever":"rate-limit"}}}},"api/billing/payment-config":{"requests":{"getPaymentConfig":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"publishableKey":{"type":"string"}},"required":["publishableKey"],"additionalProperties":false}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Stripe publishable key for the on-site Payment Element (non-secret, public).","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"ip"},"tags":["Billing"],"x-suluk-access":{"requires":"anyone"},"x-suluk-store":{"key":"paymentConfig","ttl":3600},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"static publishable key from env, zero I/O"}],"estimateMicroUsd":1,"lever":"rate-limit"}}}},"api/billing/payment-intent":{"requests":{"createPaymentIntent":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"clientSecret":{"type":"string"},"breakdown":{"type":"object","properties":{"subtotalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"taxCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["subtotalCents","taxCents","totalCents","credits"],"additionalProperties":false}},"required":["clientSecret","breakdown"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Create a PaymentIntent for an ON-SITE credit top-up (Payment Element + in-page 3DS). Pay X → get Y: returns the client secret + the breakdown (the charge, any sales tax on top, the total, and the credits you'll receive — already net of the processing fee). Credit lands on the webhook.","contentType":"application/json","contentSchema":{"type":"object","properties":{"amountCents":{"type":"integer","minimum":100,"maximum":100000},"useDefaultCard":{"type":"boolean"}},"required":["amountCents"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"ensure-customer lookup/persist"},{"source":"stripe","basis":"per-call","microUsd":0,"description":"customer + payment_intent create are free; the 2.9%+30¢ lands on the charge"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/billing/payment-health":{"requests":{"getPaymentHealth":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"alert":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["subscription_past_due","autotopup_failed"]},"message":{"type":"string"}},"required":["kind","message"],"additionalProperties":false},{"type":"null"}]}},"required":["alert"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's CURRENT billing problem (a failed subscription renewal or a declined auto-top-up) needing action, or null when healthy. Drives the persistent alert shown in the billing tab, the sidebar, and the header so the user can fix it (update card / cancel subscription / turn off auto-top-up) from anywhere.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"paymentHealth","ttl":60,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"payment_alert lookup"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/keys":{"requests":{"getApiKeys":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"start":{"anyOf":[{"type":"string"},{"type":"null"}]},"scopes":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"expiresAt":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"lastUsed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"creditsUsed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"subtreeCreditsUsed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"creditLimit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"rateLimitSharePct":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"parentKeyId":{"anyOf":[{"type":"string"},{"type":"null"}]},"depth":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","name","start","scopes","enabled","expiresAt","lastUsed","creditsUsed","subtreeCreditsUsed","creditLimit","rateLimitSharePct","parentKeyId","depth"],"additionalProperties":false}}},"required":["keys"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"API keys with per-key usage + their place in the delegation tree — name, masked prefix, granted scopes, last used, own + POOLED-subtree credits used vs the key's PAID limit, its % share of the free rate-limit allowance, expiry, revoked state, parent key, and depth. A signed-in user sees all their keys; a caller holding `keys:provision` sees only the subtree it minted. (Caps are edited via /api/auth/api-key/*; children are minted via provisionKey and revoked via revokeKey.)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["API keys"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"apiKeys","ttl":30,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"apikey rows + per-key usage join + lineage"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/keys/provision":{"requests":{"provisionKey":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"key":{"type":"string"},"keyId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"creditLimit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"rateLimitSharePct":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["key","keyId","scopes","creditLimit","rateLimitSharePct"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Mint a CHILD API key. The caller (a signed-in user, or a key/MCP connection holding `keys:provision`) may request a name, a SUBSET of scopes, and per-key credit/rate caps; the server CLAMPS each to the caller's own effective grant — a child can never out-scope or out-spend an ancestor (caps are min/∩ up the chain, and the child's spend pools into every ancestor's cap). Returns the plaintext key ONCE. Revoking the parent cascade-revokes the child.","contentType":"application/json","contentSchema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"scopes":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","maxLength":64,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"creditLimit":{"anyOf":[{"type":"integer","minimum":1,"maximum":1000000},{"type":"null"}]},"rateLimitSharePct":{"anyOf":[{"type":"integer","minimum":1,"maximum":100},{"type":"null"}]},"expiresInDays":{"anyOf":[{"type":"integer","minimum":1,"maximum":3650},{"type":"null"}]},"parentKeyId":{"anyOf":[{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},{"type":"null"}]}},"required":["name","scopes"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["API keys"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["apiKeys"],"onSuccess":"Child key created."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":3,"description":"parent-chain read + createApiKey insert + lineage row"}],"estimateMicroUsd":4,"lever":"rate-limit"}}}},"api/keys/revoke":{"requests":{"revokeKey":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"},"revoked":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","revoked"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Cascade-revoke an API key — soft-disables the key AND every child key it provisioned, transitively. A signed-in user may revoke any of their own keys; a caller holding `keys:provision` may revoke only a key inside its own subtree. Returns how many keys were disabled.","contentType":"application/json","contentSchema":{"type":"object","properties":{"keyId":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["keyId"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["API keys"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["apiKeys"],"onSuccess":"Key revoked."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"subtree select + cascade disable update"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/mcp/connections":{"requests":{"getMcpConnections":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"connections":{"type":"array","items":{"type":"object","properties":{"clientId":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"scopes":{"type":"array","items":{"type":"string"}},"creditLimit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"rateLimitSharePct":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"creditsUsed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expiresAt":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"createdAt":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["clientId","name","scopes","creditLimit","rateLimitSharePct","creditsUsed","expiresAt","createdAt"],"additionalProperties":false}}},"required":["connections"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's MCP OAuth connections — the apps they authorized via the MCP authorization flow, with granted tool scopes, the per-connection PAID credit cap + free-tier share, usage, and expiry. (Authorized via /api/auth/mcp/*; this is the usage-joined read.)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["MCP"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"mcpConnections","ttl":30,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"oauth grant rows + per-connection usage join"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/mcp/connections/update":{"requests":{"updateMcpConnection":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Set an MCP connection's per-connection credit cap / free-tier share, and/or narrow its granted scopes (the live token updates immediately).","contentType":"application/json","contentSchema":{"type":"object","properties":{"clientId":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"creditLimit":{"anyOf":[{"type":"integer","minimum":1,"maximum":1000000},{"type":"null"}]},"rateLimitSharePct":{"anyOf":[{"type":"integer","minimum":1,"maximum":100},{"type":"null"}]},"scopes":{"maxItems":20,"type":"array","items":{"type":"string","maxLength":64,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}}},"required":["clientId"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["MCP"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["mcpConnections"],"onSuccess":"Connection updated."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"cap sidecar upsert + live token/consent scope rewrite"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/mcp/connections/revoke":{"requests":{"revokeMcpConnection":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Revoke an MCP connection — its token stops working immediately.","contentType":"application/json","contentSchema":{"type":"object","properties":{"clientId":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["clientId"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["MCP"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["mcpConnections","apiKeys"],"onSuccess":"Connection revoked."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"delete token + consent + cap sidecar"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/billing/purchase-quote":{"requests":{"getPurchaseQuote":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"subtotalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"taxCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["subtotalCents","taxCents","totalCents","credits"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Quote an on-site top-up of `amountCents` WITHOUT charging: returns the credits you'll receive (already net of the processing fee), any sales tax added on top, and the total due — the SAME breakdown the PaymentIntent will use, so a one-click Pay matches exactly. Drives the live preview in the Add-credits dialog.","parameterSchema":{"query":{"type":"object","properties":{"amountCents":{"type":"integer","minimum":100,"maximum":100000}},"required":["amountCents"],"additionalProperties":false}},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"customer lookup"},{"source":"stripe","basis":"per-call","microUsd":3,"description":"default-card resolve (methods + customer) + tax calculation"}],"estimateMicroUsd":5,"lever":"rate-limit"}}}},"api/billing/setup-intent":{"requests":{"createSetupIntent":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"clientSecret":{"type":"string"}},"required":["clientSecret"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Create a $0 SetupIntent to vault a card on-site ('Add card'). Returns the client secret the Payment Element confirms.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"ensure-customer lookup/persist"},{"source":"stripe","basis":"per-call","microUsd":0,"description":"setup_intent create is free ($0 card vault)"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/billing/subscribe":{"requests":{"subscribe":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"clientSecret":{"type":"string"}},"required":["clientSecret"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Subscribe to a plan ONE-CLICK on the saved default card (recurring credits at the subscriber rate). Returns the first invoice's client secret for in-page confirmation; credits land on invoice.paid.","contentType":"application/json","contentSchema":{"type":"object","properties":{"planId":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["planId"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"ensure-customer + record subscription"},{"source":"stripe","basis":"per-call","microUsd":0,"description":"price find/create + subscription create are free; the fee lands on the first invoice"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/billing/subscription":{"requests":{"getSubscription":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"subscription":{"anyOf":[{"type":"object","properties":{"planId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string"},"currentPeriodEnd":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cancelAtPeriodEnd":{"type":"boolean"},"paidCeilingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["planId","status","currentPeriodEnd","cancelAtPeriodEnd","paidCeilingCents"],"additionalProperties":false},{"type":"null"}]}},"required":["subscription"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's CURRENT subscription (plan id · status · period end · pending cancel · the cycle's paid ceiling — the highest plan price already charged this cycle, below/at which a plan change defers to next renewal), or null when none.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"subscription","ttl":60,"revalidateOnFocus":true},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"subscription-id lookup"},{"source":"stripe","basis":"per-call","microUsd":1,"description":"subscription retrieve"}],"estimateMicroUsd":3,"lever":"rate-limit"}},"cancelSubscription":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Schedule the subscription to cancel at the period end (cancel:true) or resume it (cancel:false). Access continues until the period ends.","contentType":"application/json","contentSchema":{"type":"object","properties":{"cancel":{"type":"boolean"}},"required":["cancel"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["subscription","paymentHealth"],"onSuccess":"Subscription updated."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"subscription-id lookup"},{"source":"stripe","basis":"per-call","microUsd":1,"description":"subscription update (cancel/resume)"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/billing/subscription-plan":{"requests":{"changePlan":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"kind":{"type":"string","enum":["upgrade","downgrade"]},"clientSecret":{"anyOf":[{"type":"string"},{"type":"null"}]},"currentPeriodEnd":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["kind","clientSecret","currentPeriodEnd"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Switch the active subscription to another plan, decided against the cycle's PAID CEILING. ABOVE the ceiling = an immediate prorated upgrade (only the difference ABOVE the ceiling is charged to the saved card now; returns a clientSecret only if that charge needs 3DS) that grants the matching prorated credits. AT OR BELOW the ceiling = a deferred change that takes effect at the next renewal (currentPeriodEnd) with no charge — so changing back to a plan you already paid for this cycle never re-charges.","contentType":"application/json","contentSchema":{"type":"object","properties":{"planId":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["planId"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"subscription-id lookup"},{"source":"stripe","basis":"per-call","microUsd":3,"description":"status retrieve + price find/create + subscription re-price"}],"estimateMicroUsd":5,"lever":"rate-limit"}}}},"api/billing/refund-quote":{"requests":{"getRefundQuote":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"netCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"eligible":{"type":"boolean"}},"required":["credits","netCents","eligible"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Estimate a credit refund (buyback) WITHOUT executing: pass `credits` to quote a specific amount (omit to quote the whole balance, capped at it). Returns the credits being quoted, the net cash you'd receive (a flat rate below the cheapest you can buy, minus Stripe fees — always less than you paid), and whether enough refundable payment remains to process it.","parameterSchema":{"query":{"type":"object","properties":{"credits":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"additionalProperties":false}},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"balance + customer lookup"},{"source":"stripe","basis":"per-call","microUsd":2,"description":"charges list (refundable headroom)"}],"estimateMicroUsd":5,"lever":"rate-limit"}}}},"api/billing/refund":{"requests":{"refundCredits":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"refundedCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"creditsRefunded":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["refundedCents","creditsRefunded"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Refund (buy back) credits for cash to your original card(s): pass `credits` to refund a specific amount (omit to refund the whole balance, capped at it) at a flat rate below the cheapest acquisition price, minus Stripe fees — so you receive less than you paid. Stripe caps each refund at what was charged. Does not cancel a subscription.","contentType":"application/json","contentSchema":{"type":"object","properties":{"credits":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"requestId":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":10,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"balance + ledger debit"},{"source":"stripe","basis":"per-call","microUsd":3,"description":"charges list + refund(s) across charges"}],"estimateMicroUsd":6,"lever":"rate-limit"}}}},"api/billing/portal":{"requests":{"portal":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"404":{"status":404,"description":"Not found","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Open the Stripe billing portal to manage/cancel a subscription. Returns the portal URL.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":20,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"billing_account lookup"},{"source":"stripe","basis":"per-call","microUsd":0,"description":"billing portal session create is free"}],"estimateMicroUsd":2,"lever":"rate-limit"}}}},"api/billing/methods":{"requests":{"listPaymentMethods":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"methods":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"brand":{"type":"string"},"last4":{"type":"string"},"expMonth":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"line1":{"anyOf":[{"type":"string"},{"type":"null"}]},"line2":{"anyOf":[{"type":"string"},{"type":"null"}]},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"region":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"isDefault":{"type":"boolean"}},"required":["id","brand","last4","expMonth","expYear","name","line1","line2","city","region","postalCode","country","isDefault"],"additionalProperties":false}}},"required":["methods"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"List the signed-in user's saved cards (each with its billing address); empty until they have a Stripe customer.","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":60,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"paymentMethods","ttl":60},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"customer lookup"},{"source":"stripe","basis":"per-call","microUsd":2,"description":"list payment methods + customer"}],"estimateMicroUsd":4,"lever":"rate-limit"}}}},"api/billing/auto-topup":{"requests":{"getAutoTopup":{"method":"get","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"enabled":{"type":"boolean"},"thresholdCredits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amountCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["enabled","thresholdCredits","amountCents"],"additionalProperties":false}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"The signed-in user's auto top-up config (enabled · threshold credits · amount).","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"key":"autoTopup","ttl":60},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"config select"}],"estimateMicroUsd":2,"lever":"rate-limit"}},"updateAutoTopup":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Enable/disable + configure auto top-up. Enabling requires a saved default card.","contentType":"application/json","contentSchema":{"type":"object","properties":{"enabled":{"type":"boolean"},"thresholdCredits":{"type":"integer","minimum":1,"maximum":100000},"amountCents":{"type":"integer","minimum":100,"maximum":100000}},"required":["enabled","thresholdCredits","amountCents"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["autoTopup","paymentHealth"],"onSuccess":"Auto top-up updated."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1,"description":"upsert"},{"source":"stripe","basis":"per-call","microUsd":1,"description":"default-card check when enabling"}],"estimateMicroUsd":3,"lever":"rate-limit"}}}},"api/billing/methods/default":{"requests":{"setDefaultPaymentMethod":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"404":{"status":404,"description":"Not found","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Set one of the user's saved cards as the default for invoices.","contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["id"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["paymentMethods","paymentHealth"],"onSuccess":"Default card updated."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1},{"source":"stripe","basis":"per-call","microUsd":2,"description":"ownership list + customer update"}],"estimateMicroUsd":4,"lever":"rate-limit"}}}},"api/billing/methods/delete":{"requests":{"deletePaymentMethod":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"404":{"status":404,"description":"Not found","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"429":{"status":429,"description":"Too many requests","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Remove (detach) one of the user's saved cards.","contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["id"],"additionalProperties":false},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":30,"key":"principal"},"security":[{"sessionCookie":[]}],"tags":["Billing"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-store":{"invalidates":["paymentMethods","paymentHealth"],"onSuccess":"Card removed."},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":1},{"source":"stripe","basis":"per-call","microUsd":2,"description":"ownership list + detach"}],"estimateMicroUsd":4,"lever":"rate-limit"}}}},"api/transcribe":{"requests":{"transcribe":{"method":"post","responses":{"200":{"status":200,"contentType":"text/plain","contentSchema":{"type":"string","description":"the subtitle file"}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"402":{"status":402,"description":"Payment required","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"413":{"status":413,"description":"Error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"502":{"status":502,"description":"Bad gateway","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Transcribe audio/video to subtitles (SRT/VTT) via Whisper on Workers AI. Auth + credit-gated.","contentType":"multipart/form-data","contentSchema":{"type":"object","properties":{"file":{"type":"string","description":"the audio/video file (multipart upload)","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"format":{"description":"output subtitle format (default srt)","type":"string","enum":["srt","vtt","ass","ssa","sbv","lrc"]}},"required":["file"],"additionalProperties":false},"security":[{"sessionCookie":[]}],"tags":["Tools"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"workers-ai-whisper","basis":"per-unit","microUsd":450,"description":"per audio-minute (dominant cost); the user pays 1 credit/minute"},{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"balance read + debit write"}],"estimateMicroUsd":2250,"lever":"credit"}}}},"api/subtitle/convert":{"requests":{"convertSubtitle":{"method":"post","responses":{"200":{"status":200,"contentType":"application/json","contentSchema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"description":"the per-file id echoed from the request (for mapping results back)","type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["done","error","skipped"]},"content":{"description":"the converted subtitle text (present when status=done)","type":"string"},"error":{"description":"why a file was not converted/charged (parse detail, out_of_credits, or key_limit)","type":"string"},"charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"credits debited for THIS file (0 on error/skip/replay)"}},"required":["name","status","charged"],"additionalProperties":false},"description":"the per-file outcome, in input order"},"totalCharged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"credits debited across the batch"},"replayed":{"type":"boolean","description":"true when the whole batch was a retry that moved no new money"}},"required":["results","totalCharged","replayed"],"additionalProperties":false,"description":"per-item bulk-conversion result"}},"400":{"status":400,"description":"Bad request","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"401":{"status":401,"description":"Unauthorized","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"402":{"status":402,"description":"Payment required","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"403":{"status":403,"description":"Forbidden","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}},"500":{"status":500,"description":"Internal server error","contentType":"application/problem+json","contentSchema":{"$ref":"#/components/schemas/ProblemDetails"}}},"summary":"Bulk-convert subtitle files between formats (srt/vtt/ass/ssa/sbv/smi/lrc/sub). Auth + credit-gated (1 credit per converted file). Per-item + idempotent on a batch requestId + per-file id (a retry never double-charges).","contentType":"application/json","contentSchema":{"type":"object","properties":{"to":{"type":"string","enum":["srt","vtt","ass","ssa","sbv","lrc"]},"from":{"type":"string","enum":["srt","vtt","ass","ssa","sbv","lrc","smi","sub"]},"requestId":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"files":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"name":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"content":{"type":"string","minLength":1,"maxLength":1000000,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["name","content"],"additionalProperties":false}}},"required":["to","files"],"additionalProperties":false},"security":[{"sessionCookie":[]}],"tags":["Tools"],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"components":[{"source":"compute","basis":"per-unit","microUsd":2,"description":"per file: BOM-aware decode + parse + serialize (regex/text, no I/O); the user pays 1 credit/file (a credit-charged tool feature — see TOOL_FEATURE_OPS)"},{"source":"compute","basis":"per-call","microUsd":1},{"source":"d1","basis":"per-call","microUsd":2,"description":"balance read + debit write"}],"estimateMicroUsd":3,"lever":"credit"}}}},"api/auth/sign-in/social":{"requests":{"socialSignIn":{"method":"post","responses":{"200":{"status":200,"description":"Success - Returns session details (idToken branch) or an authorize URL (redirect branch)","contentType":"application/json","contentSchema":{"type":"object","description":"Returns session details when idToken is provided, or an authorize URL otherwise","properties":{"token":{"type":"string"},"user":{"type":"object","$ref":"#/components/schemas/User"},"url":{"type":"string"},"redirect":{"type":"boolean"}},"required":["redirect"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Sign in with a social provider","tags":["Sign in"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"callbackURL":{"type":"string","description":"Callback URL to redirect to after the user has signed in","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"newUserCallbackURL":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"errorCallbackURL":{"type":"string","description":"Callback URL to redirect to if an error happens","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"provider":{"anyOf":[{"type":"string","enum":["apple","atlassian","cognito","discord","facebook","figma","github","microsoft","google","huggingface","slack","spotify","twitch","twitter","dropbox","kick","linear","linkedin","gitlab","tiktok","reddit","roblox","salesforce","vk","zoom","notion","kakao","naver","line","paybin","paypal","polar","railway","vercel","wechat"]},{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}]},"disableRedirect":{"type":"boolean","description":"Disable automatic redirection to the provider. Useful for handling the redirection yourself"},"idToken":{"type":"object","properties":{"token":{"type":"string","description":"ID token from the provider","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"nonce":{"type":"string","description":"Nonce used to generate the token","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"accessToken":{"type":"string","description":"Access token from the provider","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"refreshToken":{"type":"string","description":"Refresh token from the provider","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"expiresAt":{"type":"number","description":"Expiry date of the token","maximum":1000000000000,"minimum":-1000000000000},"user":{"type":"object","properties":{"name":{"type":"object","properties":{"firstName":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"lastName":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false},"email":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"description":"The user object from the provider. Only available for some providers like Apple.","additionalProperties":false}},"required":["token"],"additionalProperties":false},"scopes":{"type":"array","items":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"description":"Array of scopes to request from the provider. This will override the default scopes passed.","maxItems":1000},"requestSignUp":{"type":"boolean","description":"Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider"},"loginHint":{"type":"string","description":"The login hint to use for the authorization code request","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"additionalData":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["provider"],"additionalProperties":false},"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/callback/{id}":{"requests":{"getOperation":{"method":"get","responses":{"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"tags":["Sign in"],"security":[{"bearerAuth":[]}],"parameterSchema":{"path":{"type":"object","properties":{"id":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["id"],"additionalProperties":false}},"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"summary":"Better Auth — callback {id} (Sign in)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}},"postOperation":{"method":"post","responses":{"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"tags":["Sign in"],"security":[{"bearerAuth":[]}],"parameterSchema":{"path":{"type":"object","properties":{"id":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["id"],"additionalProperties":false}},"contentType":"application/json","contentSchema":{"type":"object","properties":{"code":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"error":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"device_id":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"error_description":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"state":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"user":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false},"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"summary":"Better Auth — callback {id} (Sign in)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/sign-out":{"requests":{"signOut":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"success":{"type":"boolean"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Sign out the current user","tags":["Session"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{},"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/update-session":{"requests":{"updateSession":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"session":{"type":"object","$ref":"#/components/schemas/Session"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Update the current session","tags":["Session"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","propertyNames":{"type":"string","description":"Field name must be a string"},"additionalProperties":{}},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/update-user":{"requests":{"updateUser":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"user":{"type":"object","$ref":"#/components/schemas/User"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Update the current user","tags":["Account"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the user","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"image":{"type":["string","null"],"description":"The image of the user","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/delete-user":{"requests":{"deleteUser":{"method":"post","responses":{"200":{"status":200,"description":"User deletion processed successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the operation was successful"},"message":{"type":"string","enum":["User deleted","Verification email sent"],"description":"Status message of the deletion process"}},"required":["success","message"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Delete the user","tags":["Account"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"callbackURL":{"type":"string","description":"The callback URL to redirect to after the user is deleted","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"password":{"type":"string","description":"The user's password. Required if session is not fresh","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"token":{"type":"string","description":"The deletion verification token","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/list-sessions":{"requests":{"listUserSessions":{"method":"get","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"array","items":{"$ref":"#/components/schemas/Session"}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"List all active sessions for the user","tags":["Session"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/revoke-session":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"status":{"type":"boolean","description":"Indicates if the session was revoked successfully"}},"required":["status"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Revoke a single session","tags":["Session"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"token":{"type":"string","description":"The token to revoke","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["token"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/revoke-sessions":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"status":{"type":"boolean","description":"Indicates if all sessions were revoked successfully"}},"required":["status"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Revoke all sessions for the user","tags":["Session"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{},"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/revoke-other-sessions":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"status":{"type":"boolean","description":"Indicates if all other sessions were revoked successfully"}},"required":["status"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Revoke all other sessions for the user except the current one","tags":["Session"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{},"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/link-social":{"requests":{"linkSocialAccount":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"url":{"type":"string","description":"The authorization URL to redirect the user to"},"redirect":{"type":"boolean","description":"Indicates if the user should be redirected to the authorization URL"},"status":{"type":"boolean"}},"required":["redirect"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Link a social account to the user","tags":["Sign in"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"callbackURL":{"type":"string","description":"The URL to redirect to after the user has signed in","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"provider":{"anyOf":[{"type":"string","enum":["apple","atlassian","cognito","discord","facebook","figma","github","microsoft","google","huggingface","slack","spotify","twitch","twitter","dropbox","kick","linear","linkedin","gitlab","tiktok","reddit","roblox","salesforce","vk","zoom","notion","kakao","naver","line","paybin","paypal","polar","railway","vercel","wechat"]},{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}]},"idToken":{"type":"object","properties":{"token":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"nonce":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"accessToken":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"refreshToken":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"scopes":{"type":"array","items":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"maxItems":1000}},"required":["token"],"additionalProperties":false},"requestSignUp":{"type":"boolean"},"scopes":{"type":"array","items":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"description":"Additional scopes to request from the provider","maxItems":1000},"errorCallbackURL":{"type":"string","description":"The URL to redirect to if there is an error during the link process","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"disableRedirect":{"type":"boolean","description":"Disable automatic redirection to the provider. Useful for handling the redirection yourself"},"additionalData":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["provider"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/list-accounts":{"requests":{"listUserAccounts":{"method":"get","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"providerId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"accountId":{"type":"string"},"userId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":["id","providerId","createdAt","updatedAt","accountId","userId","scopes"]}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"List all accounts linked to the user","tags":["Sign in"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/delete-user/callback":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"User successfully deleted","contentType":"application/json","contentSchema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the deletion was successful"},"message":{"type":"string","enum":["User deleted"],"description":"Confirmation message"}},"required":["success","message"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Callback to complete user deletion with verification token","tags":["Account"],"security":[{"bearerAuth":[]}],"parameterSchema":{"query":{"type":"object","properties":{"token":{"type":"string","description":"The token to verify the deletion request","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"callbackURL":{"type":"string","description":"The URL to redirect to after deletion","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false}},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/unlink-account":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"status":{"type":"boolean"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Unlink an account","tags":["Sign in"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"providerId":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"accountId":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["providerId"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/refresh-token":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Access token refreshed successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"tokenType":{"type":"string"},"idToken":{"type":"string"},"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"accessTokenExpiresAt":{"type":"string","format":"date-time"},"refreshTokenExpiresAt":{"type":"string","format":"date-time"}}}},"400":{"status":400,"description":"Invalid refresh token or provider configuration"},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Refresh the access token using a refresh token","tags":["Sign in"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"providerId":{"type":"string","description":"The provider ID for the OAuth provider","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"accountId":{"type":"string","description":"The account ID associated with the refresh token","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"userId":{"type":"string","description":"The user ID associated with the account","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["providerId"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/get-access-token":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"A Valid access token","contentType":"application/json","contentSchema":{"type":"object","properties":{"tokenType":{"type":"string"},"idToken":{"type":"string"},"accessToken":{"type":"string"},"accessTokenExpiresAt":{"type":"string","format":"date-time"}}}},"400":{"status":400,"description":"Invalid refresh token or provider configuration"},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Get a valid access token, doing a refresh if needed","tags":["Sign in"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"providerId":{"type":"string","description":"The provider ID for the OAuth provider","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"accountId":{"type":"string","description":"The account ID associated with the refresh token","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"userId":{"type":"string","description":"The user ID associated with the account","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["providerId"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/account-info":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"image":{"type":"string"},"emailVerified":{"type":"boolean"}},"required":["id","emailVerified"]},"data":{"type":"object","properties":{},"additionalProperties":true}},"required":["user","data"],"additionalProperties":false}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Get the account info provided by the provider","tags":["Sign in"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/ok":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"API is working","contentType":"application/json","contentSchema":{"type":"object","properties":{"ok":{"type":"boolean","description":"Indicates if the API is working"}},"required":["ok"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Check if the API is working","tags":["System"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/error":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"Success","contentType":"text/html","contentSchema":{"type":"string","description":"The HTML content of the error page"}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Displays an error page","tags":["System"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/api-key/create":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"API key created successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier of the API key"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"name":{"type":["string","null"],"description":"Name of the API key"},"prefix":{"type":["string","null"],"description":"Prefix of the API key"},"start":{"type":["string","null"],"description":"Starting characters of the key (if configured)"},"key":{"type":"string","description":"The full API key (only returned on creation)"},"enabled":{"type":"boolean","description":"Whether the key is enabled"},"expiresAt":{"type":["string","null"],"format":"date-time","description":"Expiration timestamp"},"referenceId":{"type":"string","description":"ID of the reference owning the key"},"lastRefillAt":{"type":["string","null"],"format":"date-time","description":"Last refill timestamp"},"lastRequest":{"type":["string","null"],"format":"date-time","description":"Last request timestamp"},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Metadata associated with the key"},"rateLimitMax":{"type":["number","null"],"description":"Maximum requests in time window"},"rateLimitTimeWindow":{"type":["number","null"],"description":"Rate limit time window in milliseconds"},"remaining":{"type":["number","null"],"description":"Remaining requests"},"refillAmount":{"type":["number","null"],"description":"Amount to refill"},"refillInterval":{"type":["number","null"],"description":"Refill interval in milliseconds"},"rateLimitEnabled":{"type":"boolean","description":"Whether rate limiting is enabled"},"requestCount":{"type":"number","description":"Current request count in window"},"permissions":{"type":["object","null"],"additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Permissions associated with the key"}},"required":["id","createdAt","updatedAt","key","enabled","referenceId","rateLimitEnabled","requestCount"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Create a new API key for a user","tags":["API keys"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"configId":{"type":"string","description":"The configuration ID to use for the API key. If not provided, the default configuration will be used.","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"name":{"type":"string","description":"Name of the Api Key","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"expiresIn":{"type":["number","null"],"description":"Expiration time of the Api Key in seconds","maximum":1000000000000,"minimum":-1000000000000},"prefix":{"type":"string","description":"Prefix of the Api Key","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"remaining":{"type":["number","null"],"description":"Remaining number of requests. Server side only","maximum":1000000000000,"minimum":-1000000000000},"metadata":{},"refillAmount":{"type":"number","description":"Amount to refill the remaining count of the Api Key. server-only. Eg: 100","maximum":1000000000000,"minimum":-1000000000000},"refillInterval":{"type":"number","description":"Interval to refill the Api Key in milliseconds. server-only. Eg: 1000","maximum":1000000000000,"minimum":-1000000000000},"rateLimitTimeWindow":{"type":"number","description":"The duration in milliseconds where each request is counted. Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset. server-only. Eg: 1000","maximum":1000000000000,"minimum":-1000000000000},"rateLimitMax":{"type":"number","description":"Maximum amount of requests allowed within a window. Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset. server-only. Eg: 100","maximum":1000000000000,"minimum":-1000000000000},"rateLimitEnabled":{"type":"boolean","description":"Whether the key has rate limiting enabled. server-only. Eg: true"},"permissions":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Permissions of the Api Key."},"userId":{"type":"string","description":"User Id of the user that the Api Key belongs to. server-only. Eg: \"user-id\"","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"organizationId":{"type":"string","description":"Organization Id of the organization that the Api Key belongs to. Eg: 'org-id'","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/api-key/get":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"API key retrieved successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","description":"ID"},"name":{"type":["string","null"],"description":"The name of the key"},"start":{"type":["string","null"],"description":"Shows the first few characters of the API key, including the prefix. This allows you to show those few characters in the UI to make it easier for users to identify the API key."},"prefix":{"type":["string","null"],"description":"The API Key prefix. Stored as plain text."},"userId":{"type":"string","description":"The owner of the user id"},"refillInterval":{"type":["number","null"],"description":"The interval in milliseconds between refills of the `remaining` count. Example: 3600000 // refill every hour (3600000ms = 1h)"},"refillAmount":{"type":["number","null"],"description":"The amount to refill"},"lastRefillAt":{"type":["string","null"],"format":"date-time","description":"The last refill date"},"enabled":{"type":"boolean","description":"Sets if key is enabled or disabled","default":true},"rateLimitEnabled":{"type":"boolean","description":"Whether the key has rate limiting enabled"},"rateLimitTimeWindow":{"type":["number","null"],"description":"The duration in milliseconds"},"rateLimitMax":{"type":["number","null"],"description":"Maximum amount of requests allowed within a window"},"requestCount":{"type":"number","description":"The number of requests made within the rate limit time window"},"remaining":{"type":["number","null"],"description":"Remaining requests (every time api key is used this should updated and should be updated on refill as well)"},"lastRequest":{"type":["string","null"],"format":"date-time","description":"When last request occurred"},"expiresAt":{"type":["string","null"],"format":"date-time","description":"Expiry date of a key"},"createdAt":{"type":"string","format":"date-time","description":"created at"},"updatedAt":{"type":"string","format":"date-time","description":"updated at"},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Extra metadata about the apiKey"},"permissions":{"type":["string","null"],"description":"Permissions for the api key (stored as JSON string)"}},"required":["id","userId","enabled","rateLimitEnabled","requestCount","createdAt","updatedAt"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Retrieve an existing API key by ID","tags":["API keys"],"security":[{"bearerAuth":[]}],"parameterSchema":{"query":{"type":"object","properties":{"configId":{"type":"string","description":"The configuration ID to use for the API key lookup. If not provided, the default configuration will be used.","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"id":{"type":"string","description":"The id of the Api Key","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false}},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/api-key/update":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"API key updated successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","description":"ID"},"name":{"type":["string","null"],"description":"The name of the key"},"start":{"type":["string","null"],"description":"Shows the first few characters of the API key, including the prefix. This allows you to show those few characters in the UI to make it easier for users to identify the API key."},"prefix":{"type":["string","null"],"description":"The API Key prefix. Stored as plain text."},"userId":{"type":"string","description":"The owner of the user id"},"refillInterval":{"type":["number","null"],"description":"The interval in milliseconds between refills of the `remaining` count. Example: 3600000 // refill every hour (3600000ms = 1h)"},"refillAmount":{"type":["number","null"],"description":"The amount to refill"},"lastRefillAt":{"type":["string","null"],"format":"date-time","description":"The last refill date"},"enabled":{"type":"boolean","description":"Sets if key is enabled or disabled","default":true},"rateLimitEnabled":{"type":"boolean","description":"Whether the key has rate limiting enabled"},"rateLimitTimeWindow":{"type":["number","null"],"description":"The duration in milliseconds"},"rateLimitMax":{"type":["number","null"],"description":"Maximum amount of requests allowed within a window"},"requestCount":{"type":"number","description":"The number of requests made within the rate limit time window"},"remaining":{"type":["number","null"],"description":"Remaining requests (every time api key is used this should updated and should be updated on refill as well)"},"lastRequest":{"type":["string","null"],"format":"date-time","description":"When last request occurred"},"expiresAt":{"type":["string","null"],"format":"date-time","description":"Expiry date of a key"},"createdAt":{"type":"string","format":"date-time","description":"created at"},"updatedAt":{"type":"string","format":"date-time","description":"updated at"},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Extra metadata about the apiKey"},"permissions":{"type":["string","null"],"description":"Permissions for the api key (stored as JSON string)"}},"required":["id","userId","enabled","rateLimitEnabled","requestCount","createdAt","updatedAt"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Update an existing API key by ID","tags":["API keys"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"configId":{"type":"string","description":"The configuration ID to use for the API key lookup. If not provided, the default configuration will be used.","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"keyId":{"type":"string","description":"The id of the Api Key","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"userId":{"type":"string","description":"The id of the user which the api key belongs to. server-only. Eg: \"some-user-id\"","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"name":{"type":"string","description":"The name of the key","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"enabled":{"type":"boolean","description":"Whether the Api Key is enabled or not"},"remaining":{"type":"number","description":"The number of remaining requests","maximum":1000000000000,"minimum":-1000000000000},"refillAmount":{"type":"number","description":"The refill amount","maximum":1000000000000,"minimum":-1000000000000},"refillInterval":{"type":"number","description":"The refill interval","maximum":1000000000000,"minimum":-1000000000000},"metadata":{},"expiresIn":{"type":["number","null"],"description":"Expiration time of the Api Key in seconds","maximum":1000000000000,"minimum":-1000000000000},"rateLimitEnabled":{"type":"boolean","description":"Whether the key has rate limiting enabled."},"rateLimitTimeWindow":{"type":"number","description":"The duration in milliseconds where each request is counted. server-only. Eg: 1000","maximum":1000000000000,"minimum":-1000000000000},"rateLimitMax":{"type":"number","description":"Maximum amount of requests allowed within a window. Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset. server-only. Eg: 100","maximum":1000000000000,"minimum":-1000000000000},"permissions":{"type":["object","null"],"propertyNames":{"type":"string"},"additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Update the permissions on the API Key. server-only."}},"required":["keyId"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/api-key/delete":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"API key deleted successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the API key was successfully deleted"}},"required":["success"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Delete an existing API key","tags":["API keys"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the API key to delete","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["keyId"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/api-key/list":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"API keys retrieved successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"apiKeys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"ID"},"name":{"type":["string","null"],"description":"The name of the key"},"start":{"type":["string","null"],"description":"Shows the first few characters of the API key, including the prefix. This allows you to show those few characters in the UI to make it easier for users to identify the API key."},"prefix":{"type":["string","null"],"description":"The API Key prefix. Stored as plain text."},"userId":{"type":"string","description":"The owner of the user id"},"refillInterval":{"type":["number","null"],"description":"The interval in milliseconds between refills of the `remaining` count. Example: 3600000 // refill every hour (3600000ms = 1h)"},"refillAmount":{"type":["number","null"],"description":"The amount to refill"},"lastRefillAt":{"type":["string","null"],"format":"date-time","description":"The last refill date"},"enabled":{"type":"boolean","description":"Sets if key is enabled or disabled","default":true},"rateLimitEnabled":{"type":"boolean","description":"Whether the key has rate limiting enabled"},"rateLimitTimeWindow":{"type":["number","null"],"description":"The duration in milliseconds"},"rateLimitMax":{"type":["number","null"],"description":"Maximum amount of requests allowed within a window"},"requestCount":{"type":"number","description":"The number of requests made within the rate limit time window"},"remaining":{"type":["number","null"],"description":"Remaining requests (every time api key is used this should updated and should be updated on refill as well)"},"lastRequest":{"type":["string","null"],"format":"date-time","description":"When last request occurred"},"expiresAt":{"type":["string","null"],"format":"date-time","description":"Expiry date of a key"},"createdAt":{"type":"string","format":"date-time","description":"created at"},"updatedAt":{"type":"string","format":"date-time","description":"updated at"},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Extra metadata about the apiKey"},"permissions":{"type":["string","null"],"description":"Permissions for the api key (stored as JSON string)"}},"required":["id","userId","enabled","rateLimitEnabled","requestCount","createdAt","updatedAt"]}},"total":{"type":"number","description":"Total number of API keys"},"limit":{"type":["number","null"],"description":"The limit used for pagination"},"offset":{"type":["number","null"],"description":"The offset used for pagination"}},"required":["apiKeys","total"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"List all API keys for the authenticated user or for a specific organization","tags":["API keys"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/generate-register-options":{"requests":{"generatePasskeyRegistrationOptions":{"method":"get","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"challenge":{"type":"string"},"rp":{"type":"object","properties":{"name":{"type":"string"},"id":{"type":"string"}}},"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"displayName":{"type":"string"}}},"pubKeyCredParams":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"alg":{"type":"number"}}}},"timeout":{"type":"number"},"excludeCredentials":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"transports":{"type":"array","items":{"type":"string"}}}}},"authenticatorSelection":{"type":"object","properties":{"authenticatorAttachment":{"type":"string"},"requireResidentKey":{"type":"boolean"},"userVerification":{"type":"string"}}},"attestation":{"type":"string"},"extensions":{"type":"object"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Generate registration options for a new passkey","tags":["Passkey"],"security":[{"bearerAuth":[]}],"parameterSchema":{"query":{"type":"object","properties":{"authenticatorAttachment":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"name":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"context":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"additionalProperties":false}},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/generate-authenticate-options":{"requests":{"passkeyGenerateAuthenticateOptions":{"method":"get","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"challenge":{"type":"string"},"rp":{"type":"object","properties":{"name":{"type":"string"},"id":{"type":"string"}}},"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"displayName":{"type":"string"}}},"timeout":{"type":"number"},"allowCredentials":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"transports":{"type":"array","items":{"type":"string"}}}}},"userVerification":{"type":"string"},"authenticatorSelection":{"type":"object","properties":{"authenticatorAttachment":{"type":"string"},"requireResidentKey":{"type":"boolean"},"userVerification":{"type":"string"}}},"extensions":{"type":"object"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Generate authentication options for a passkey","tags":["Passkey"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/verify-registration":{"requests":{"passkeyVerifyRegistration":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"$ref":"#/components/schemas/Passkey"}},"400":{"status":400,"description":"Bad request"},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Verify registration of a new passkey","tags":["Passkey"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","additionalProperties":false,"required":["response"],"properties":{"name":{"type":"string","maxLength":256,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"response":{"type":"object","additionalProperties":false,"required":["id","rawId","response","type"],"properties":{"id":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"rawId":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"type":{"type":"string","const":"public-key"},"authenticatorAttachment":{"type":"string","enum":["platform","cross-platform"]},"clientExtensionResults":{"type":"object","additionalProperties":false},"response":{"type":"object","additionalProperties":false,"required":["clientDataJSON","attestationObject"],"properties":{"clientDataJSON":{"type":"string","maxLength":8192,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"attestationObject":{"type":"string","maxLength":32768,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"transports":{"type":"array","maxItems":8,"items":{"type":"string","maxLength":32,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"authenticatorData":{"type":"string","maxLength":8192,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"publicKey":{"type":"string","maxLength":4096,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"publicKeyAlgorithm":{"type":"integer","minimum":-65535,"maximum":65535}}}}}}},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/verify-authentication":{"requests":{"passkeyVerifyAuthentication":{"method":"post","responses":{"200":{"status":200,"description":"Success","contentType":"application/json","contentSchema":{"type":"object","properties":{"session":{"$ref":"#/components/schemas/Session"},"user":{"$ref":"#/components/schemas/User"}}}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Verify authentication of a passkey","tags":["Passkey"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","additionalProperties":false,"required":["response"],"properties":{"response":{"type":"object","additionalProperties":false,"required":["id","rawId","response","type"],"properties":{"id":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"rawId":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"type":{"type":"string","const":"public-key"},"authenticatorAttachment":{"type":"string","enum":["platform","cross-platform"]},"clientExtensionResults":{"type":"object","additionalProperties":false},"response":{"type":"object","additionalProperties":false,"required":["clientDataJSON","authenticatorData","signature"],"properties":{"clientDataJSON":{"type":"string","maxLength":8192,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"authenticatorData":{"type":"string","maxLength":8192,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"signature":{"type":"string","maxLength":4096,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"userHandle":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}}}}}}},"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/list-user-passkeys":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"Passkeys retrieved successfully","contentType":"application/json","contentSchema":{"type":"array","items":{"$ref":"#/components/schemas/Passkey","required":["id","userId","publicKey","createdAt","updatedAt"]},"description":"Array of passkey objects associated with the user"}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"List all passkeys for the authenticated user","tags":["Passkey"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/delete-passkey":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Passkey deleted successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"status":{"type":"boolean","description":"Indicates whether the deletion was successful"}},"required":["status"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Delete a specific passkey","tags":["Passkey"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","description":"The ID of the passkey to delete. Eg: \"some-passkey-id\"","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["id"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/passkey/update-passkey":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Passkey updated successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"passkey":{"$ref":"#/components/schemas/Passkey"}},"required":["passkey"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Update a specific passkey's name","tags":["Passkey"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"id":{"type":"string","description":"The ID of the passkey which will be updated. Eg: \"passkey-id\"","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"name":{"type":"string","minLength":1,"description":"The new name which the passkey will be updated to. Eg: \"my-new-passkey-name\"","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["id","name"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/oauth2/consent":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"Consent processed successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"redirectURI":{"type":"string","format":"uri","description":"The URI to redirect to, either with an authorization code or an error"}},"required":["redirectURI"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Handle OAuth2 consent. Supports both URL parameter-based flows (consent_code in body) and cookie-based flows (signed cookie).","tags":["MCP"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"accept":{"type":"boolean","description":"Whether the user accepts or denies the consent request"},"consent_code":{"type":"string","description":"The consent code from the authorization request. Optional if using cookie-based flow.","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["accept"],"additionalProperties":false},"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/.well-known/oauth-authorization-server":{"requests":{"getOperation":{"method":"get","responses":{"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"tags":["MCP"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"summary":"Better Auth — .well-known oauth-authorization-server (MCP)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/.well-known/oauth-protected-resource":{"requests":{"getOperation":{"method":"get","responses":{"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"tags":["MCP"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"summary":"Better Auth — .well-known oauth-protected-resource (MCP)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/mcp/authorize":{"requests":{"getOperation":{"method":"get","responses":{"200":{"status":200,"description":"Authorization response generated successfully","contentType":"application/json","contentSchema":{"type":"object","additionalProperties":true,"description":"Authorization response, contents depend on the authorize function implementation"}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Authorize an OAuth2 request using MCP","tags":["MCP"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/mcp/token":{"requests":{"postOperation":{"method":"post","responses":{"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"tags":["MCP"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","propertyNames":{},"additionalProperties":{}},"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"summary":"Better Auth — mcp token (MCP)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/mcp/register":{"requests":{"postOperation":{"method":"post","responses":{"200":{"status":200,"description":"OAuth2 application registered successfully","contentType":"application/json","contentSchema":{"type":"object","properties":{"name":{"type":"string","description":"Name of the OAuth2 application"},"icon":{"type":["string","null"],"description":"Icon URL for the application"},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Additional metadata for the application"},"clientId":{"type":"string","description":"Unique identifier for the client"},"clientSecret":{"type":"string","description":"Secret key for the client. Not included for public clients."},"redirectUrls":{"type":"array","items":{"type":"string","format":"uri"},"description":"List of allowed redirect URLs"},"type":{"type":"string","description":"Type of the client","enum":["web","public"]},"authenticationScheme":{"type":"string","description":"Authentication scheme used by the client","enum":["client_secret","none"]},"disabled":{"type":"boolean","description":"Whether the client is disabled","enum":[false]},"userId":{"type":["string","null"],"description":"ID of the user who registered the client, null if registered anonymously"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["name","clientId","redirectUrls","type","authenticationScheme","disabled","createdAt","updatedAt"]}},"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"description":"Register an OAuth2 application","tags":["MCP"],"security":[{"bearerAuth":[]}],"contentType":"application/json","contentSchema":{"type":"object","properties":{"redirect_uris":{"type":"array","items":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"maxItems":1000},"token_endpoint_auth_method":{"type":"string","enum":["none","client_secret_basic","client_secret_post"]},"grant_types":{"type":"array","items":{"type":"string","enum":["authorization_code","implicit","password","client_credentials","refresh_token","urn:ietf:params:oauth:grant-type:jwt-bearer","urn:ietf:params:oauth:grant-type:saml2-bearer"]},"maxItems":1000},"response_types":{"type":"array","items":{"type":"string","enum":["code","token"]},"maxItems":1000},"client_name":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"client_uri":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"logo_uri":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"scope":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"contacts":{"type":"array","items":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"maxItems":1000},"tos_uri":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"policy_uri":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"jwks_uri":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"jwks":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"metadata":{"type":"object","propertyNames":{},"additionalProperties":{}},"software_id":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"software_version":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"},"software_statement":{"type":"string","maxLength":1024,"pattern":"^[^\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]*$"}},"required":["redirect_uris"],"additionalProperties":false},"x-suluk-access":{"requires":"anyone"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}},"api/auth/mcp/get-session":{"requests":{"getOperation":{"method":"get","responses":{"400":{"status":400,"description":"Bad Request. Usually due to missing parameters, or invalid parameters.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"401":{"status":401,"description":"Unauthorized. Due to missing or invalid authentication.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}},"403":{"status":403,"description":"Forbidden. You do not have permission to access this resource or to perform this action.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"404":{"status":404,"description":"Not Found. The requested resource was not found.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"429":{"status":429,"description":"Too Many Requests. You have exceeded the rate limit. Try again later.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}},"500":{"status":500,"description":"Internal Server Error. This is a problem with the server that you cannot fix.","contentType":"application/json","contentSchema":{"type":"object","properties":{"message":{"type":"string"}}}}},"tags":["MCP"],"security":[{"bearerAuth":[]}],"x-suluk-access":{"requires":"authenticated"},"x-suluk-cost":{"estimateMicroUsd":1,"lever":"rate-limit","components":[{"source":"compute","basis":"per-call","microUsd":1,"description":"Better Auth plumbing (session/account I/O) — FREE to you; metered by the IP-keyed flood allowance (AUTH_RATE_LIMIT), not credits"}]},"summary":"Better Auth — mcp get-session (MCP)","x-suluk-ratelimit":{"windowMs":60000,"maxRequests":15,"key":"ip"}}}}},"servers":[{"url":"https://app.toolfactory.saastemly.com"}],"components":{"securitySchemes":{"sessionCookie":{"type":"apiKey","in":"cookie","name":"better-auth.session_token"},"apiKeyCookie":{"type":"apiKey","in":"cookie","name":"apiKeyCookie","description":"API Key authentication via cookie"},"bearerAuth":{"type":"http","scheme":"bearer","description":"Bearer token authentication"}},"schemas":{"ProblemDetails":{"type":"object","title":"ProblemDetails","description":"RFC-9457 Problem Details (application/problem+json).","properties":{"type":{"type":"string","format":"uri-reference","default":"about:blank"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string","format":"uri-reference"},"errors":{"type":"object","additionalProperties":true},"error":{"type":"string","deprecated":true}},"required":["type","title","status"]},"User":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"name":{"type":"string"},"email":{"type":"string"},"emailVerified":{"type":"boolean","default":false,"readOnly":true},"image":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","email","emailVerified","createdAt","updatedAt"]},"Session":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"expiresAt":{"type":"string","format":"date-time"},"token":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"ipAddress":{"type":"string"},"userAgent":{"type":"string"},"userId":{"type":"string"}},"required":["id","expiresAt","token","createdAt","updatedAt","userId"]},"Account":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"accountId":{"type":"string"},"providerId":{"type":"string"},"userId":{"type":"string"},"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"idToken":{"type":"string"},"accessTokenExpiresAt":{"type":"string","format":"date-time"},"refreshTokenExpiresAt":{"type":"string","format":"date-time"},"scope":{"type":"string"},"password":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","accountId","providerId","userId","createdAt","updatedAt"]},"Verification":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"identifier":{"type":"string"},"value":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","identifier","value","expiresAt","createdAt","updatedAt"]},"Apikey":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"configId":{"type":"string","default":"default","readOnly":true},"name":{"type":"string","readOnly":true},"start":{"type":"string","readOnly":true},"referenceId":{"type":"string","readOnly":true},"prefix":{"type":"string","readOnly":true},"key":{"type":"string","readOnly":true},"refillInterval":{"type":"number","readOnly":true},"refillAmount":{"type":"number","readOnly":true},"lastRefillAt":{"type":"string","format":"date-time","readOnly":true},"enabled":{"type":"boolean","default":true,"readOnly":true},"rateLimitEnabled":{"type":"boolean","default":true,"readOnly":true},"rateLimitTimeWindow":{"type":"number","default":86400000,"readOnly":true},"rateLimitMax":{"type":"number","default":10,"readOnly":true},"requestCount":{"type":"number","default":0,"readOnly":true},"remaining":{"type":"number","readOnly":true},"lastRequest":{"type":"string","format":"date-time","readOnly":true},"expiresAt":{"type":"string","format":"date-time","readOnly":true},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true},"permissions":{"type":"string","readOnly":true},"metadata":{"type":"string"}},"required":["id","configId","referenceId","key","createdAt","updatedAt"]},"Passkey":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"name":{"type":"string"},"publicKey":{"type":"string"},"userId":{"type":"string"},"credentialID":{"type":"string"},"counter":{"type":"number"},"deviceType":{"type":"string"},"backedUp":{"type":"boolean"},"transports":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"aaguid":{"type":"string"}},"required":["id","publicKey","userId","credentialID","counter","deviceType","backedUp"]},"OauthApplication":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"name":{"type":"string"},"icon":{"type":"string"},"metadata":{"type":"string"},"clientId":{"type":"string"},"clientSecret":{"type":"string"},"redirectUrls":{"type":"string"},"type":{"type":"string"},"disabled":{"type":"boolean","default":false},"userId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id"]},"OauthAccessToken":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"accessTokenExpiresAt":{"type":"string","format":"date-time"},"refreshTokenExpiresAt":{"type":"string","format":"date-time"},"clientId":{"type":"string"},"userId":{"type":"string"},"scopes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id"]},"OauthConsent":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"clientId":{"type":"string"},"userId":{"type":"string"},"scopes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"consentGiven":{"type":"boolean"}},"required":["id"]}}},"x-suluk-notify":{"400":"warn","401":"silent","402":"error","403":"error","404":"error","429":"warn","2xx":"silent","4xx":"warn","5xx":"error","network":"error"}}