16 KiB
API Endpoints
Complete reference for all Routstr API endpoints.
Overview
Routstr provides OpenAI-compatible endpoints with Bitcoin/eCash payment integration.
Base URL
All endpoints use the base URL:
https://api.routstr.com/v1
Authentication
All endpoints require authentication via:
- Bearer Token:
Authorization: Bearer sk-...orAuthorization: Bearer cashuAeyJ0... - X-Cashu Header:
X-Cashu: cashuAeyJ0...(for direct eCash payments)
See Authentication for details.
Chat
Create Chat Completion
Send messages to generate model responses.
POST /v1/chat/completions
Request Body:
{
"model": "gpt-4",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Hello!"
}
],
"temperature": 0.7,
"stream": false
}
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string | Yes | - | Model ID to use |
messages |
array | Yes | - | Array of message objects |
temperature |
number | No | 1.0 | Sampling temperature (0-2) |
max_tokens |
integer | No | Model default | Maximum tokens to generate |
stream |
boolean | No | false | Stream partial responses |
top_p |
number | No | 1.0 | Nucleus sampling |
n |
integer | No | 1 | Number of completions |
stop |
string/array | No | null | Stop sequences |
presence_penalty |
number | No | 0 | Presence penalty (-2 to 2) |
frequency_penalty |
number | No | 0 | Frequency penalty (-2 to 2) |
Response:
{
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1677652288,
"model": "gpt-4",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 13,
"completion_tokens": 9,
"total_tokens": 22
}
}
Streaming Response
When stream: true:
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
Completions (Coming Soon)
Create Completion
Note: This endpoint is coming soon and not yet available.
Generate text completion (legacy endpoint).
POST /v1/completions
Request Body:
{
"model": "gpt-3.5-turbo-instruct",
"prompt": "Once upon a time",
"max_tokens": 50,
"temperature": 0.7
}
Response:
{
"id": "cmpl-123",
"object": "text_completion",
"created": 1677652288,
"model": "gpt-3.5-turbo-instruct",
"choices": [{
"text": " in a faraway land, there lived a brave knight...",
"index": 0,
"logprobs": null,
"finish_reason": "length"
}],
"usage": {
"prompt_tokens": 4,
"completion_tokens": 50,
"total_tokens": 54
}
}
Embeddings
Create Embeddings (Coming Soon)
Note: This endpoint is coming soon and not yet available.
Generate vector representations of text.
POST /v1/embeddings
Request Body:
{
"model": "text-embedding-3-small",
"input": "The quick brown fox jumps over the lazy dog",
"encoding_format": "float"
}
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string | Yes | - | Embedding model ID |
input |
string/array | Yes | - | Text(s) to embed |
encoding_format |
string | No | "float" | Format: "float" or "base64" |
dimensions |
integer | No | Model default | Output dimensions |
Response:
{
"object": "list",
"data": [{
"object": "embedding",
"index": 0,
"embedding": [0.0023064255, -0.009327292, ...]
}],
"model": "text-embedding-3-small",
"usage": {
"prompt_tokens": 9,
"total_tokens": 9
}
}
Images (Coming Soon)
Create Image
Note: This endpoint is coming soon and not yet available.
Generate images from text prompts.
POST /v1/images/generations
Request Body:
{
"model": "dall-e-3",
"prompt": "A white siamese cat wearing a space helmet",
"n": 1,
"size": "1024x1024",
"quality": "standard"
}
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string | Yes | - | Model: dall-e-2, dall-e-3 |
prompt |
string | Yes | - | Text description |
n |
integer | No | 1 | Number of images |
size |
string | No | "1024x1024" | Image dimensions |
quality |
string | No | "standard" | Quality: standard, hd |
style |
string | No | "vivid" | Style: vivid, natural |
response_format |
string | No | "url" | Format: url, b64_json |
Response:
{
"created": 1677652288,
"data": [{
"url": "https://generated-image-url.com/image.png",
"revised_prompt": "A white Siamese cat wearing a detailed space helmet..."
}]
}
Audio (Coming Soon)
Create Transcription
Note: This endpoint is coming soon and not yet available.
Convert audio to text.
POST /v1/audio/transcriptions
Content-Type: multipart/form-data
Form Data:
| Field | Type | Required | Description |
|---|---|---|---|
file |
file | Yes | Audio file (mp3, mp4, mpeg, mpga, m4a, wav, webm) |
model |
string | Yes | Model ID (whisper-1) |
language |
string | No | Language code (ISO-639-1) |
prompt |
string | No | Context prompt |
response_format |
string | No | Format: json, text, srt, verbose_json, vtt |
temperature |
number | No | Sampling temperature |
Response:
{
"text": "Hello, this is the transcribed audio content."
}
Create Translation
Note: This endpoint is coming soon and not yet available.
Translate audio to English.
POST /v1/audio/translations
Content-Type: multipart/form-data
Same parameters as transcription, but always translates to English.
Models
List Models
Get available models and pricing.
GET /v1/models
Response:
{
"object": "list",
"data": [
{
"id": "gpt-3.5-turbo",
"object": "model",
"created": 1677610602,
"owned_by": "openai",
"permission": [...],
"root": "gpt-3.5-turbo",
"parent": null,
"pricing": {
"prompt": 0.001,
"completion": 0.002,
"unit": "1k tokens"
}
}
]
}
List Model Paths
Get the selectable upstream routes for each advertised model. This endpoint is discovery-only; request-side selection will be added separately.
GET /v1/models/paths
Response:
{
"data": [
{
"id": "anthropic/claude-sonnet-4",
"paths": [
{
"path": "url=https%3A%2F%2Fapi.anthropic.com%2Fv1&provider-id=12&model-id=anthropic%2Fclaude-sonnet-4",
"provider": {"id": 12, "slug": "anthropic-primary", "type": "anthropic"},
"endpoint": null
},
{
"path": "url=https%3A%2F%2Fopenrouter.ai%2Fapi%2Fv1&provider-id=42&model-id=anthropic%2Fclaude-sonnet-4&endpoint=google-vertex%2Fus",
"provider": {"id": 42, "slug": "openrouter-main", "type": "openrouter"},
"endpoint": {"tag": "google-vertex/us", "name": "Google"}
}
]
}
],
"updated_at": 1753500000
}
path is an opaque, percent-encoded selector. Clients must store and return it
unchanged rather than parsing or reconstructing it. It identifies the exact
configured route with url, provider-id, and model-id. To avoid exposing
private network details, a configured private IP address or any URL with an
explicit port is advertised as http://localhost. OpenRouter routes additionally
preserve the exact machine-readable endpoint tag. Provider slugs/types and
endpoint names remain display data. When request-side selection is implemented,
an endpoint tag must not silently fall back to another backend.
List Paths for One Model
Use the exact model ID advertised by /v1/models. The query parameter safely
supports IDs containing /.
GET /v1/models/paths/model?model_id=anthropic/claude-sonnet-4
The response uses the same path objects and updated_at field as the collection
endpoint. An unknown model returns 404 Model not found. A known model whose
paths have not been discovered yet returns 200 with an empty data array.
Wallet Management
Create Wallet (Coming Soon)
Note: This endpoint is coming soon. Currently, you can use Cashu tokens directly as API keys.
Create a new wallet with eCash deposit.
POST /v1/wallet/create
Request Body:
{
"cashu_token": "cashuAeyJ0...",
"admin_key": "optional-admin-key"
}
Response:
{
"api_key": "sk-1234567890abcdef",
"admin_key": "radmin_fedcba0987654321",
"balance": 10000,
"mint": "https://mint.example.com",
"unit": "sat"
}
Get Key Information
Get current balance and consumption data for an API key.
GET /v1/balance/info
Authorization: Bearer sk-...
Response:
{
"api_key": "sk-abc...",
"balance": 8500000,
"reserved": 0,
"total_requests": 42,
"total_spent": 1500000,
"validity_date": null
}
balance is the spendable balance used by request admission.
Check Balance
Get current wallet balance.
GET /v1/wallet/balance
Authorization: Bearer sk-...
Response:
{
"balance": 8500,
"currency": "sat",
"reserved": 0
}
Top Up Wallet
Add funds to existing wallet.
POST /v1/wallet/topup
Authorization: Bearer sk-...
Request Body:
{
"cashu_token": "cashuAeyJ0..."
}
Response:
{
"balance": 18500,
"amount_added": 10000,
"currency": "sat"
}
Refund Balance
Pay out the current balance. The key remains valid at zero balance and can be topped up again. The payout goes to a Lightning address when one is given (in the request or stored on the key), otherwise a Cashu token is returned.
POST /v1/balance/refund
Authorization: Bearer sk-...
Content-Type: application/json
/v1/wallet/refund is a deprecated alias.
Request Body (optional):
{
"lightning_address": "user@getalby.com"
}
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lightning_address |
string | No | Key's stored refund address | Lightning address or LNURL to pay. Overrides the stored address for this request. The effective address (request or stored) is resolved only for a request that can open a new claim, before any balance is debited. |
Response (Lightning):
{
"refund_id": "3f9c1e2d8b7a4c6e9f0a1b2c3d4e5f60",
"status": "paid",
"recipient": "user@getalby.com",
"sats": "4500"
}
Response (Cashu):
{
"refund_id": "3f9c1e2d8b7a4c6e9f0a1b2c3d4e5f60",
"status": "paid",
"token": "cashuAeyJ0...",
"sats": "4500"
}
The amount field is sats or msats depending on the key's refund currency. It reports the gross balance debited by the claim. For Lightning refunds, mint and input fees can reduce the amount actually delivered to the recipient.
Behaviour:
- The balance is debited and a refund claim is recorded before the payout is attempted. A key has at most one open claim at a time.
- If the payout fails cleanly, the claim is closed and the balance is restored. Retry the request.
- Once a melt quote has been recorded or a Cashu token has been issued, the payout may already have happened, so any later failure returns
502and withholds the balance rather than restoring it. The exception is the mint answering the melt itself withunpaid: that is proof nothing was sent, so the balance is restored at once and the request returns503. - If the Lightning payment is dispatched but the mint cannot confirm the outcome, the request returns
502, the balance stays withheld, and a background reconciler asks the mint until it answers. The balance is restored if the mint reports the payment unpaid. - An unresolved claim is reported before any replay: a request on a key with an open claim returns
409with that claim'srefund_idandstatus. - Calling again on a zero-balance key with no open claim returns the last paid Lightning refund, or the Cashu token issued by the last paid claim while it remains uncollected.
Errors:
| Status | Meaning |
|---|---|
400 |
Invalid Lightning destination, no balance, or balance too small for the refund unit |
400 |
Ongoing requests are still reserving balance on this key |
401 |
Unknown key |
409 |
Balance changed concurrently. Retry. |
409 |
refund_in_progress: another refund claim for this key is still open. The body carries its refund_id and status |
409 |
refund_unresolved: a claim for this key is stuck and needs operator reconciliation |
410 |
Previously issued Cashu refund token has been swept |
500 |
Payout failed before anything was dispatched. Balance restored. Retry. |
502 |
Payment dispatched, outcome unconfirmed. Balance withheld pending reconciliation. Do not retry. |
503 |
Mint unavailable, or the mint reported the Lightning payment unpaid. Balance restored. Retry later. |
X-Cashu refunds:
Requests paid per-call with an X-Cashu header get their change from this endpoint by sending the same header instead of Authorization:
POST /v1/balance/refund
X-Cashu: cashuAeyJ0...
Returns the change token in the body and in an X-Cashu response header. 404 if no matching request exists, 425 while the change is still being minted, 410 if it was swept.
Provider Discovery
Admin Settings
These endpoints are protected by the Admin cookie (admin_password set to your configured admin password).
Get Settings
GET /admin/api/settings
Returns the current application settings (sensitive values may be redacted).
Update Settings
PATCH /admin/api/settings
Content-Type: application/json
Body is a partial JSON of settings fields to update. Validated and persisted to the database.
List Providers
Get available upstream providers.
GET /v1/providers
Response:
{
"providers": [
{
"name": "openai",
"models": ["gpt-4", "gpt-3.5-turbo"],
"endpoints": ["chat/completions", "completions"],
"status": "active"
}
]
}
Provider Info
Get specific provider details.
GET /v1/providers/{provider_name}
Response:
{
"name": "openai",
"display_name": "OpenAI",
"description": "Official OpenAI API",
"models": [
{
"id": "gpt-4",
"name": "GPT-4",
"context_window": 8192,
"pricing": {
"prompt": 0.03,
"completion": 0.06,
"unit": "1k tokens"
}
}
],
"endpoints": ["chat/completions", "completions", "embeddings"],
"features": ["streaming", "function_calling"],
"status": "active"
}
Rate Limiting
All endpoints are subject to rate limiting:
- Per minute: 60 requests
- Per hour: 1000 requests
- Per day: 10000 requests
Rate limit information is included in response headers.
Next Steps
- Errors - Error handling reference
- Authentication - Auth details
- Integration Guide - Code examples