DigiHoosh API reference
Preview: not released
These endpoints are implemented and acceptance-tested locally, but no production API hostname has been announced. Replace every base URL and key placeholder with values from your own approved environment.
The DigiHoosh public API v1 exposes a strict, versioned subset of Chat Completions plus model discovery and organization usage:
POST /v1/chat/completions
GET /v1/models
GET /v1/usageUnknown or unsupported fields are rejected with a stable error. They are never silently sent to a model provider.
Authentication and scopes
Send a DigiHoosh organization API key in the standard Bearer header:
Authorization: Bearer <YOUR_DIGIHOOSH_API_KEY>| Endpoint | Required scope |
|---|---|
POST /v1/chat/completions | chat:write |
GET /v1/models | models:read |
GET /v1/usage | usage:read |
A browser session cookie cannot authenticate these endpoints. Accept-Language: en or Accept-Language: fa selects error prose only; status codes, error codes, IDs, and other machine fields stay unchanged.
Set placeholders once before running the examples:
export DIGIHOOSH_API_BASE_URL="http://localhost:8080"
export DIGIHOOSH_API_KEY="<YOUR_DIGIHOOSH_API_KEY>"$env:DIGIHOOSH_API_BASE_URL = "http://localhost:8080"
$env:DIGIHOOSH_API_KEY = "<YOUR_DIGIHOOSH_API_KEY>"POST /v1/chat/completions
Creates a stateless model execution. It does not create a Dashboard conversation. The accepted request fields are:
| Field | Rules |
|---|---|
model | Required public model ID. Use GET /v1/models to discover it. |
messages | Required ordered system, user, or assistant text messages. |
stream | Optional; defaults to false. |
stream_options.include_usage | Allowed only when stream is true. |
max_completion_tokens | Optional integer from 1 through 131072. |
temperature | Optional number from 0 through 2. |
reasoning_effort | Optional medium or high. |
n | Optional; only 1 is supported. |
Tools, tool calls, images, audio, arbitrary metadata, provider selection, the developer role, n greater than one, and the deprecated max_tokens field are unsupported.
Non-streaming request
Save this contract-validated payload as chat-request.json:
{
"model": "gpt-5.6-luna",
"messages": [
{
"role": "system",
"content": "Answer concisely."
},
{
"role": "user",
"content": "What is two plus two?"
}
],
"stream": false,
"max_completion_tokens": 64,
"temperature": 0.2,
"reasoning_effort": "high",
"n": 1
}Run it with curl:
curl --request POST "$DIGIHOOSH_API_BASE_URL/v1/chat/completions" --header "Authorization: Bearer $DIGIHOOSH_API_KEY" --header "Content-Type: application/json" --header "Accept-Language: en" --data @chat-request.jsonOr with PowerShell:
$headers = @{
Authorization = "Bearer $env:DIGIHOOSH_API_KEY"
"Accept-Language" = "en"
}
Invoke-RestMethod -Method Post -Uri "$env:DIGIHOOSH_API_BASE_URL/v1/chat/completions" -Headers $headers -ContentType "application/json" -InFile "chat-request.json"A successful response has object: "chat.completion", one assistant choice, the selected public model, and final prompt/completion token usage.
Streaming request
Save this contract-validated payload as chat-stream-request.json:
{
"model": "gpt-5.6-luna",
"messages": [
{
"role": "system",
"content": "Answer concisely."
},
{
"role": "user",
"content": "What is two plus two?"
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"max_completion_tokens": 64,
"temperature": 0.2,
"reasoning_effort": "high",
"n": 1
}curl --no-buffer --request POST "$DIGIHOOSH_API_BASE_URL/v1/chat/completions" --header "Authorization: Bearer $DIGIHOOSH_API_KEY" --header "Content-Type: application/json" --header "Accept: text/event-stream" --data @chat-stream-request.jsonA successful stream uses text/event-stream. Each message is data: <JSON>. The first choice delta declares the assistant role, text deltas remain ordered, exactly one choice has a non-null finish_reason, and—when requested—one final chunk with empty choices contains complete usage. data: [DONE] is always last.
If an admitted request fails mid-stream, the standard error envelope is emitted as a data item followed by [DONE]. The HTTP status cannot change after admission. Client cancellation propagates to execution, and DigiHoosh does not silently retry a partial stream.
GET /v1/models
Returns enabled public models that have exactly one effective customer rate, in deterministic order. In addition to id, object, created, and owned_by, each model has pricing.currency, pricing.unit_tokens, pricing.input_rate, and pricing.output_rate. Rates are decimal USD amounts per the stated token unit; cached input is part of input and reasoning is part of output, so those subsets are not charged again.
The response excludes provider identity, routing configuration, provider cost, markup, discount, and margin. Published rates are pre-tax operational rates, not an invoice or final payment amount. Credit purchase, payments, taxes, and invoices are not available in this preview.
curl "$DIGIHOOSH_API_BASE_URL/v1/models" --header "Authorization: Bearer $DIGIHOOSH_API_KEY" --header "Accept-Language: en"GET /v1/usage
Returns durable token usage for the authenticated organization.
| Query parameter | Rules |
|---|---|
from | Required RFC3339 instant; inclusive. |
to | Required RFC3339 instant; exclusive and later than from. |
model | Optional exact public-model filter. |
limit | Optional 1–100; defaults to 50. |
cursor | Optional opaque cursor returned by the previous page. |
The interval cannot exceed 90 days. Results are newest first by creation time and request ID. totals and by_model cover the complete filtered interval; data and next_cursor describe one page. A cursor is bound to its original filters.
curl "$DIGIHOOSH_API_BASE_URL/v1/usage?from=2099-08-01T00%3A00%3A00Z&to=2099-09-01T00%3A00%3A00Z&limit=50" --header "Authorization: Bearer $DIGIHOOSH_API_KEY" --header "Accept-Language: en"Only request IDs, public model IDs, timestamps, and recorded token counts are returned. Prompts, responses, provider data, credentials, price, cost, and conversation data are excluded.
Request IDs and idempotency
Every response includes DigiHoosh-Request-Id. You may send that header on a chat request with a value matching req_[A-Za-z0-9_-]{8,120}.
Within one organization, reusing the ID with an identical completed request replays its completed representation. Reusing it with a changed payload returns 409 idempotency_conflict; reusing it while the identical request is still active returns a conflict instead of starting another execution. Generate a new request ID for each new logical request.
Rate limits
The current preview admits 60 newly admitted requests per organization in each fixed UTC minute. Completed idempotent replays do not consume another admission. A rejected request returns 429 rate_limit_exceeded with retryable: true and a Retry-After header from 1 through 60 seconds.
Wait for Retry-After before attempting a new logical request. Never automatically retry after receiving any SSE event.
Credits and billing availability
Developer API requests now require enough prepaid USD credit for a conservative model-limit reservation. One credit means USD 1.00. Active reservations reduce available credit. A completed request with valid usage posts its exact customer-priced debit once; failed, cancelled, or timed-out requests release customer value. If final evidence cannot safely close a request, its reservation may remain held for reconciliation instead of being guessed or silently released. Insufficient credit returns HTTP 402 with code insufficient_credit before model execution.
The effective rate is copied when the request is admitted. An identical replay uses that historical snapshot and is never repriced by a later rate change. Input and output amounts are calculated separately, rounded midpoint-to-even to 12 decimal places, and then added. Cached input remains part of input and reasoning remains part of output, so neither subset is charged twice. Display rounding must not replace these exact stored values.
The API-key surface still exposes no balance, transaction, purchase, refund, payment, tax, invoice, or Shamsi billing-period API. An authenticated Owner or Admin browser session may read only its active organization's exact API-credit summary from GET /app/v1/billing/credit-summary and bounded API-credit history from GET /app/v1/billing/transactions; API keys and Members cannot use those routes. The unreleased Developer Dashboard preview presents those reads to an authorized Owner or Admin; Chat does not expose API credit. Transaction history defaults to 25 rows, permits at most 100, is newest first, and uses an opaque cursor bound to the active organization. It distinguishes pending reservations, final debits, refunded debits, promotional credit, and append-only refund reversals while retaining exact twelve-decimal USD values. An internal usage reversal restores credit through an append-only entry; it is not a cash refund and no public refund workflow exists. Published prices and calculated amounts are pre-tax operational values, not invoices, settlement amounts, tax records, revenue-recognition records, or statutory accounts. GET /v1/usage remains token-only and is not a customer charge statement.
Errors
HTTP failures use a stable envelope with type, code, message_key, message_args, param, retryable, and request_id. Only message is localized.
| Status | Common code | Retryable |
|---|---|---|
| 400 | invalid_request or unsupported_parameter | no |
| 401 | invalid_api_key | no |
| 402 | insufficient_credit | no |
| 403 | forbidden | no |
| 409 | idempotency_conflict | no |
| 429 | rate_limit_exceeded | yes |
| 503 | model_unavailable | yes |
Do not parse localized message text. Branch on HTTP status and code, retain request_id for support, and follow retryable plus Retry-After where present. Public errors do not contain provider names, raw provider errors, credentials, prompt content, or internal topology.
Safe key handling
- Copy a newly created key once and store it in an approved secret manager.
- Put the key in an environment variable or mounted secret file; never hard-code it.
- Never place it in a URL, browser storage, frontend bundle, source file, screenshot, log, or support message.
- Use only the scopes needed by the application.
- Revoke a key immediately if exposure is suspected and replace it with a newly created key.