Getting started
Quickstart
Connect your application to Laras Router in a few minutes. The API is compatible with the official OpenAI SDKs and any client that lets you set a base URL.
Create an account and add balance
Sign up at the developer console. Open Billing & Wallet, choose an amount between $3.00 and $100.00, and scan the dynamic QRIS code with any Indonesian banking or e-wallet app. The invoice shows the exchange rate, the 0.70% QRIS fee, and the IDR total before you pay. There is no free credit, so your first request needs a top-up.
Generate an API key
Navigate to API Keys and click Create Key. Copy your secret key (
lr_live_...). For security, the full key is only displayed once.Send your first request
Point your OpenAI client at
https://api.larasrouter.com/v1and use your Laras Router key:curl https://api.larasrouter.com/v1/chat/completions \ -H "Authorization: Bearer $LARAS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-flash", "messages": [ {"role": "user", "content": "Explain recursion in one short paragraph."} ] }'
Security
Authentication
All API requests authenticate with an HTTP Bearer token in the Authorization header. Keys start with lr_live_.
Authorization: Bearer lr_live_••••••••••••••••Environment variables
The official OpenAI SDKs read these environment variables:
export OPENAI_BASE_URL="https://api.larasrouter.com/v1"export OPENAI_API_KEY="lr_live_your_key_here"Endpoint
Chat Completions
POST /v1/chat/completions creates a completion for a list of chat messages, in the OpenAI request and response format.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | Yes | Model ID. The only accepted value is deepseek-flash. |
| messages | array | Yes | Message objects with a role and content, as in the OpenAI API. |
| max_tokens | integer | No | Maximum output tokens, 1 to 384,000. If omitted, the gateway sends a cap of 8,192 to the provider. A value above 384,000 is rejected with 400 max_tokens_exceeded, never silently reduced. max_completion_tokens is also accepted; if you send both, the smaller value applies. |
| stream | boolean | No | If true, partial message deltas are sent as Server-Sent Events (SSE). Set stream_options.include_usage to true to receive token usage on the final chunk. |
| other parameters | — | No | Other OpenAI-compatible parameters, such as temperature, tools, response_format, and stop, are forwarded to DeepSeek unchanged. See DeepSeek's API documentation for how each behaves. |
max_tokens — the default cap of 8,192 tokens applies when you omit it.Request ID
Responses to requests that reached billing carry an X-Laras-Request-ID header. It identifies the charge and hold for that request — include it when you contact support about a charge. Requests rejected before a hold is placed (for example a 401 or 404) may not carry it.
Endpoint
Models Endpoint
GET /v1/models lists the models your key can use.
curl https://api.larasrouter.com/v1/models \ -H "Authorization: Bearer $LARAS_API_KEY"Supported model IDs
deepseek-flash— DeepSeek-V4.1-Flash. Fast general-purpose model with a 1M token context window, up to 384K output tokens, streaming, tool calls, and JSON output.
Legacy IDs such as deepseek-v4-flash and deepseek-v4-flash-vision-exp are not accepted and return 404 model_not_found. Image input is not available.
The endpoint returns a standard OpenAI-style list payload: each entry carries id, object, and owned_by.
Limits
Rate Limits
Each API key has two limits by default:
- Requests per minute
- 60
- Concurrent requests
- 4
A request over either limit returns 429 with error code rate_limit_exceeded or concurrency_limit_exceeded and a Retry-After header in seconds. If DeepSeek itself rate-limits a request, its 429 and Retry-After are forwarded to you. Retry after the indicated delay, with backoff.
Every in-flight request also holds part of your balance (see below), so a small balance can limit concurrency before these limits do.
Economics
Billing & Holds
Your balance is a prepaid USD wallet. We record operational metadata for each request — model ID, token counts, HTTP status, charge, and timestamps. Your prompt and completion text passes through our gateway in memory and is not stored by us; it is sent to DeepSeek to generate the response.
Cost calculation
Each request is charged from the usage DeepSeek reports (prompt_cache_hit_tokens, prompt_cache_miss_tokens, and completion_tokens). Prices are fixed and do not change by time of day:
cost = cache_hit_input_tokens × $0.010 / 1M + cache_miss_input_tokens × $0.400 / 1M + output_tokens × $1.600 / 1MExample: 8,000 cache-hit input, 4,400 cache-miss input, and 1,800 output tokens cost $0.000080 + $0.001760 + $0.002880 = $0.004720. Charges are computed to a billionth of a dollar, rounded up, and shown to six decimal places ($0.000001) in your console. Try other splits in the cost calculator.
Holds and 402 errors
Before a request is sent to the provider, a hold is reserved on your balance. The hold covers the largest prompt the model accepts plus your output cap (max_tokens, or 8,192 tokens if omitted). At current prices that is about $0.41 for a request using the default cap. When the request finishes, the hold is settled to the actual charge and the rest is released.
Requests run while your available balance — your balance minus holds for requests already in flight — is above $0.00, even if it is smaller than the new hold. A request that finishes can take your balance below zero by at most $1.00; that amount is owed and is deducted from your next top-up. While your available balance is $0.00 or below, requests fail with 402 insufficient_credit until you top up.
Failed requests
- A request DeepSeek rejects with a 4xx error is not charged; its hold is released.
- A request that fails with a 5xx error, times out, or is interrupted keeps its hold while we reconcile it. You may be charged for any usage DeepSeek reports for it; otherwise the hold is released without a charge.
Key budgets
Each API key can have an optional monthly budget in USD, set in the console. A key’s month-to-date spend is its settled charges plus the holds of its requests still running, counted per calendar month in Jakarta time (WIB). A request whose hold would take the key past its budget fails with 402 key_budget_exceeded before it reaches the provider. A budget limits one key; it never lets a key spend more than your balance.
When your available balance drops below $1.00, the owners and admins of your organization receive one email with a link to top up. The next alert is sent only after your balance is topped up above $1.00 and drops again.
Troubleshooting
Error Reference
Errors use the OpenAI error shape, so SDKs parse them normally. Branch on code (and type), never on the message text.
The message text is in English by default. Send Accept-Language: id (for example id-ID,id;q=0.9) to receive it in Bahasa Indonesia. code and type are the same in every language.
{ "error": { "message": "Insufficient wallet balance", "type": "insufficient_quota", "code": "insufficient_credit", "param": null }}| Status | Code | Type | Cause & solution |
|---|---|---|---|
| 400 | invalid_request | invalid_request_error | The body is not valid JSON or does not name a model. Fix the request body. |
| 400 | max_tokens_exceeded | invalid_request_error | max_tokens (or max_completion_tokens) is above the model ceiling of 384,000. Lower it. |
| 401 | invalid_api_key | invalid_request_error | The Authorization header is missing, or the key is invalid or revoked. |
| 402 | insufficient_credit | insufficient_quota | Your available balance, after holds for requests still running, is $0.00 or below (see Billing & Holds). A balance below zero, at most $1.00, is deducted from your next top-up. Top up to continue. |
| 402 | key_budget_exceeded | insufficient_quota | This request’s hold would take the API key past its monthly budget. Month-to-date spend counts settled charges plus holds of requests still running, in the current calendar month in Jakarta time (WIB). Raise or clear the budget in the console, or wait for the next month. |
| 403 | insufficient_scope | insufficient_permissions | The API key does not have the chat:write scope. |
| 404 | model_not_found | invalid_request_error | The model ID is not served. Use deepseek-flash. |
| 429 | rate_limit_exceeded / concurrency_limit_exceeded | rate_limit_exceeded | A per-key limit was hit (see Rate Limits). Wait for the Retry-After seconds, then retry. A 429 from DeepSeek is forwarded with its own body and Retry-After. |
| 502 | provider_unavailable | api_error | The model provider could not be reached or failed. Retry with backoff. |
| 503 | billing_unavailable | api_error | Billing is temporarily unavailable, so the request was not run. Retry later. |
Other error statuses returned by DeepSeek — for example a 400 for a parameter combination it does not support — are forwarded with DeepSeek's own error body.
Still stuck? Email [email protected] with the X-Laras-Request-ID of the request.