API Reference
This page documents the API surface that exists in the current codebase.
Base URLs
Section titled “Base URLs”| Surface | Base URL | Audience |
|---|---|---|
| Developer API | https://api.shineshop.dev | API-key clients and SDKs |
| Website/account API | https://shineshop.dev/api | SHINE SHOP DEV web panel |
Use the developer API for model traffic. The website/account API is session-based and is intended for first-party UI flows such as sign-in, key management, usage, payment orders, and account security.
Common response behavior
Section titled “Common response behavior”Developer API errors use an OpenAI-compatible shape where possible:
{ "error": { "message": "Missing API key. Provide it as a Bearer token.", "type": "authentication_error", "code": "missing_api_key" }}Website/account API errors use:
{ "ok": false, "code": "unauthorized" }All first-party JSON endpoints set content-type: application/json; charset=utf-8. Personalized account and payment endpoints use cache-control: no-store; public content endpoints may use short-lived public caching.
Developer API
Section titled “Developer API”Authentication:
Authorization: Bearer sk-...or, for Anthropic-compatible clients:
x-api-key: sk-...anthropic-version: 2023-06-01Supported public endpoints:
| Method | Path | Notes |
|---|---|---|
GET | / | Health response: { "ok": true }. |
GET | /health | Same health response. |
GET | /v1/models | Model list. Requires a valid API key and consumes one request reservation. |
GET | /v1/model/info | Model metadata. Requires a valid API key and consumes one request reservation. |
POST | /v1/chat/completions | OpenAI-compatible chat completions. Requires model. Supports quota checks and OpenAI-style response fields. |
POST | /v1/responses | OpenAI-compatible Responses endpoint. Requires model. Supports quota checks. |
POST | /v1/messages | Anthropic-style messages endpoint after path normalization. Requires model. |
POST | /v1/messages/count_tokens | Token counting endpoint. Requires model; not treated as a generation endpoint. |
POST | /v1/embeddings | Embeddings endpoint. Requires model. |
POST | /v1/images/generations | Image generation endpoint. Requires model. |
POST | /v1/audio/speech | Speech endpoint. Requires model. |
POST | /v1/search | Search endpoint. Does not require model in the request. |
POST | /v1/web/fetch | Web fetch endpoint. Does not require model in the request. |
Anthropic path aliases are normalized before routing:
| Client path | Public route |
|---|---|
/anthropic | /v1/messages |
/anthropic/v1/messages | /v1/messages |
/anthropic/v1/messages/count_tokens | /v1/messages/count_tokens |
/anthropic/messages... | /v1/messages... |
Request checks
Section titled “Request checks”For accepted developer API traffic, SHINE SHOP DEV currently performs:
- API key validation from
Authorization: Bearer sk-...orx-api-key: sk-.... - Rejection of API keys or tokens sent in query parameters.
- Public route allowlist check.
- API key scope check.
- Account suspension check.
- Model allowlist check when the key is restricted to specific models.
- Per-key maximum input/output token checks when configured.
- Per-model context/output limit checks when model metadata is available.
- Quota reservation before request processing and settlement after response/stream completion.
Sensitive inbound credentials such as API keys, cookies, and authorization headers are not forwarded as model-provider credentials.
Developer API error codes
Section titled “Developer API error codes”| Code | HTTP status | Meaning |
|---|---|---|
not_found | 404 | Path is outside the enabled public developer API surface. |
endpoint_not_enabled | 404 | Path is under /v1/* but not currently allowlisted. |
sensitive_query_param | 400 | API keys or token-like values were sent in the query string. |
key_secret_not_configured | 503 | API key verification secret is missing. |
missing_api_key | 401 | No valid sk-... API key was provided. |
invalid_api_key | 401 | API key is invalid or revoked. |
account_suspended | 403 | Account is suspended from developer API usage. |
insufficient_scope | 403 | API key scopes do not allow the endpoint. |
model_not_allowed | 403 | API key is restricted and the requested model is not allowlisted. |
max_input_tokens_exceeded | 400 | Estimated input exceeds a key or model limit. |
max_output_tokens_exceeded | 400 | Requested output exceeds a key or model limit. |
context_window_exceeded | 400 | Estimated input plus output exceeds model context. |
routing_unavailable | 502 | The requested model route is temporarily unavailable. |
server_error | 500 | The service could not complete the request. |
Website authentication API
Section titled “Website authentication API”Base path: https://shineshop.dev/api/auth
These endpoints are session/cookie based. They are intended for the website panel, not for third-party model clients.
| Method | Path | Body / query | Success response |
|---|---|---|---|
GET | /session | none | Active session plus csrfToken, or null. |
GET | /config | none | `{ “ok”: true, “turnstileSiteKey”: string |
POST | /request-code | { "email": string, "acceptedTerms": true, "turnstileToken"?: string } | { "ok": true, "email": string, "expiresIn": number, "requiresCode": boolean } plus OTP cookie. |
POST | /resend-code | { "turnstileToken"?: string } | { "ok": true, "email": string, "expiresIn": number, "requiresCode": boolean } plus refreshed OTP cookie. |
POST | /verify-code | { "email": string, "code": string } | { "ok": true, "session": { "user": { "email": string }, "expires": string } } plus session cookie. |
GET | /verify-link?token=... | magic-link token | HTML interstitial form. |
POST | /verify-link | JSON, form body, or query token | Redirects to /panel/keys on success; returns JSON errors on failure. |
POST | /signout | none | { "ok": true } and clears session/OTP cookies. Requires same-origin + CSRF. |
Common auth errors include auth_not_configured, account_db_not_configured, terms_required, invalid_email, blocked_domain, private_beta_only, turnstile_required, turnstile_not_configured, turnstile_failed, rate_limited, too_many_attempts, email_not_configured, auth_challenge_failed, code_expired, invalid_code, invalid_link, link_expired, two_factor_code_required, invalid_origin, invalid_csrf, and account_persistence_failed.
Account API
Section titled “Account API”All account endpoints require an authenticated web session. Mutating endpoints also require same-origin requests and a CSRF token from /api/auth/session, /api/account/keys, or /api/account/security.
GET /api/account/profile
Section titled “GET /api/account/profile”Returns the current account user and quota state.
{ "ok": true, "user": { "id": "usr_...", "createdAt": "2026-05-09T00:00:00.000Z", "updatedAt": "2026-05-09T00:00:00.000Z", "lastLoginAt": "2026-05-09T00:00:00.000Z", "twoFactorEnabled": false, "quotaTier": "beginner", "quotaUnlimited": false }, "quota": { "effectiveTier": "beginner", "manualTier": "beginner", "usageTier": "beginner", "entitlementTier": null, "maxTier": null, "unlimited": false, "suspended": false, "weeklyTokens": 0, "computedAt": "2026-05-09T00:00:00.000Z", "thresholds": [] }}Errors: unauthorized, private_beta_only, account_db_not_configured, profile_query_failed.
GET /api/account/usage?period=7d
Section titled “GET /api/account/usage?period=7d”period may be 1h, 24h, 7d, or 30d. Invalid values fall back to 7d.
{ "ok": true, "period": "7d", "startsAt": "2026-05-02T00:00:00.000Z", "quota": {}, "quotaLots": [], "summary": { "requests": 12, "inputTokens": 1000, "outputTokens": 500, "totalTokens": 1500, "lastApiCall": "2026-05-09T00:00:00.000Z" }, "daily": [ { "day": "2026-05-09", "requests": 12, "inputTokens": 1000, "outputTokens": 500, "totalTokens": 1500 } ], "recentRequests": [ { "id": "evt_...", "model": "codex/gpt5.5", "reasoningEffort": null, "inputTokens": 1000, "outputTokens": 500, "totalTokens": 1500, "createdAt": "2026-05-09T00:00:00.000Z" } ], "byModel": [ { "model": "codex/gpt5.5", "requests": 12, "inputTokens": 1000, "outputTokens": 500, "totalTokens": 1500 } ]}Errors: unauthorized, private_beta_only, account_db_not_configured, account_persistence_failed, usage_query_failed.
GET /api/account/keys
Section titled “GET /api/account/keys”Returns API key metadata, quota, and a CSRF token. Raw secrets are not returned after creation.
{ "ok": true, "keys": [ { "id": "key_...", "name": "Global key", "status": "active", "keyPrefix": "sk-...", "keySuffix": "abcd", "scopes": ["*"], "limitMode": "account_pool", "customInputTokensPerMinute": null, "customOutputTokensPerMinute": null, "customRequestsPerMinute": null, "modelAllowlist": [], "maxInputTokensPerRequest": null, "maxOutputTokensPerRequest": null, "createdAt": "2026-05-09T00:00:00.000Z", "lastUsedAt": null, "revokedAt": null } ], "quota": {}, "csrfToken": "..."}POST /api/account/keys
Section titled “POST /api/account/keys”Currently used for global key rotation and key revocation from the panel.
Request body for rotating the global key:
{ "rotate": true }Success response:
{ "ok": true, "key": { "id": "key_...", "name": "Global key", "status": "active" }, "secret": "sk-..."}Request body for revoking a key:
{ "revokeId": "key_..." }Success response:
{ "ok": true, "key": { "id": "key_...", "status": "revoked" } }Advanced arbitrary key creation is intentionally disabled unless the body uses the supported rotation path; otherwise the endpoint returns advanced_keys_disabled.
DELETE /api/account/keys/:id
Section titled “DELETE /api/account/keys/:id”Revokes a key by ID.
{ "ok": true, "key": { "id": "key_...", "status": "revoked" } }Key endpoint errors include unauthorized, private_beta_only, account_db_not_configured, account_persistence_failed, account_query_failed, invalid_origin, invalid_csrf, advanced_keys_disabled, key_secret_not_configured, rate_limited, active_key_limit_reached, not_found, invalid_key_id, key_creation_failed, and key_revoke_failed.
GET /api/account/security
Section titled “GET /api/account/security”{ "ok": true, "security": { "twoFactorEnabled": false }, "csrfToken": "..."}POST /api/account/security
Section titled “POST /api/account/security”Request:
{ "twoFactorEnabled": true }Response:
{ "ok": true, "security": { "twoFactorEnabled": true } }Errors: unauthorized, private_beta_only, account_db_not_configured, invalid_origin, invalid_csrf, invalid_body, security_query_failed, security_update_failed.
Payment API
Section titled “Payment API”Payment endpoints are for the first-party billing panel.
GET /api/payment/orders
Section titled “GET /api/payment/orders”Unauthenticated response:
{ "ok": true, "authenticated": false, "packages": [], "orders": [], "quotaLots": [], "pricing": {}, "config": {}, "csrfToken": null}Authenticated response includes authenticated: true, active packages, order history, quota lots, pricing config, payment config, and a CSRF token.
Current fixed token packages:
| Package ID | Name | Tier | Tokens | Amount |
|---|---|---|---|---|
steady-100m | Steady 100M | steady | 100,000,000 | 85,000 VND |
persistent-1b | Persistent 1B | persistent | 1,000,000,000 | 240,000 VND |
tryharder-10b | Tryharder 10B | tryharder | 10,000,000,000 | 950,000 VND |
POST /api/payment/orders
Section titled “POST /api/payment/orders”Create a fixed package order:
{ "packageId": "steady-100m" }Create a custom quota order:
{ "quotaType": "token", "quantity": 1000000 }or:
{ "quotaType": "request", "quantity": 100 }Success response:
{ "ok": true, "order": { "id": "ord_...", "paymentStatus": "pending" } }Errors: unauthorized, private_beta_only, account_db_not_configured, invalid_origin, invalid_csrf, rate_limited, invalid_package, invalid_quota_type, invalid_quantity, price_not_configured, too_many_pending_payment_orders, payment_order_failed, and payment_query_failed.
POST /api/payment/web2m/callback
Section titled “POST /api/payment/web2m/callback”Webhook endpoint for Web2M payment notifications. This endpoint is not a public client API.
Request body:
{ "status": true, "data": [ { "transactionID": "bank_txn_123", "type": "IN", "amount": 85000, "description": "SHINEDEVABCDEFGH", "date": "2026-05-09 12:00:00", "bank": "MB" } ]}Success response:
{ "status": true, "msg": "Ok", "processed": [ { "transactionID": "bank_txn_123", "paymentCode": "SHINEDEVABCDEFGH", "orderId": "ord_...", "status": "matched" } ]}The webhook rejects bodies larger than 64 KiB and validates callback authentication using the configured shared secret mechanism.
Content API
Section titled “Content API”GET /api/content/tos
Section titled “GET /api/content/tos”Returns the Terms of Service markdown and rendered HTML.
{ "ok": true, "slug": "tos", "markdown": "# Terms of Service...", "html": "<h1>Terms of Service</h1>...", "updatedAt": null}Security boundaries
Section titled “Security boundaries”- Use only the documented public API base URLs.
- Do not send API keys in URLs.
- Do not forward website session cookies to the developer API.
- Do not use website/account endpoints as a third-party API contract unless explicitly documented as public.
- Treat
secretvalues returned from key rotation as one-time display values.