Skip to main content

Serverless Inference

General conventions​

  • Base URL: BASE_API_URL
  • Path: /bff/v1/serverless-inference/{orgIdentifier}/workspaces/{workspaceIdentifier}/{action}
  • Method: All endpoints use POST.
  • Service-specific headers: X-Region: hanoi-vn (fixed), X-Portal-Roles: <user role in workspace>
  • Common headers (apiClient): X-Org-Id, X-Workspace-Id, X-User-Id
  • Two call types (both POST):
    • Query action (list/get/view): empty body; parameters passed via query string.
    • Body action (create/edit/...): parameters passed via JSON body.
  • Response: { "data": <payload> }. Paginated lists: { items, page, page_size, total, total_pages }.
  • si.playground.chat (stream), si.tts.generate / si.playground.tts (binary) — see Notes.

Endpoints​

Model​

#ActionTypeParametersPurpose
1si.model.listquerypage, page_size, keyword, categories[], providers[], tags[], model_types[], model_region[], host, status, public, select, access_levelList models
2si.model.getquerycodeModel details
3si.model.listoptionquerypage, page_sizeFilter options (category, provider, type, host, data residency)
4si.model.codesamplebody{ code, sdk? }Code sample by model
5si.model.reqdedicatedbody{ name, model_name, email, phone_number, use_case, created_at }Submit dedicated model request

API key​

#ActionTypeParametersPurpose
6si.apikey.listquerypage, page_sizeList API keys
7si.apikey.createbody{ name, model_ids[], expires_at?, rate_limit_per_hour? }Create API key
8si.apikey.editbody{ id, name?, model_ids?, rate_limit_per_hour?, status? }Edit API key
9si.apikey.revokebody{ id, status? }Revoke API key

Usage​

#ActionTypeParametersPurpose
10si.usage.viewqueryfrom_date, to_date, model, filter_email, key_nameUsage overview
11si.usage.modelquerysame as above + page, page_sizeUsage by model
12si.usage.apikeyquerysame as above + page, page_sizeUsage by API key
13si.usage.optionsquery—Filter options (api_keys, models)

Playground​

#ActionTypeParametersPurpose
14si.playground.optionsquery—Model list for playground
15si.playground.chatbodyISiInferencePayloadChat completion (stream true/false)
16si.playground.embeddingbody{ model, input[], dimensions, encoding_format, input_text_truncate, input_type }Embedding
17si.playground.ttsbody{ model, input, voice, speed, response_format }Text-to-speech (binary)

Voice Studio​

#ActionTypeParametersPurpose
18si.tts.generatebody{ model, input, voice, speed, response_format }Generate speech (binary)
19si.voice.history.listquerypage, page_size, model_code, searchVoice history
20si.voice.history.deletebody{ id }Delete one history entry
21si.voice.history.deleteallbody—Delete all history
22si.voice.history.audiourlbody{ id }Get audio URL (presigned)
23si.voice.activebody{ status: boolean }Enable/disable voice

Quota (different BFF paths)​

#MethodPathParametersPurpose
24GET/bff/v1/iam/{org}/workspaces/{ws}/quota-memberspage, limit, search, sortBy, order, serviceCode, metricKey (FE defaults: serviceCode=serverless-inference, metricKey=credit)Member list with quota
25GET/bff/v1/iam/{org}/workspaces/{ws}/quota-members/overview—Workspace quota overview
26GET/bff/v1/iam/{org}/workspaces/{ws}/quota-members/usage—Current user's usage/quota
27POST/bff/v1/eq/{org}/workspaces/{ws}/quotasArray of ISiSetQuotaCapPayloadSet quota cap
28PUT/bff/v1/eq/{org}/workspaces/{ws}/quotasArray of ISiUpdateQuotaCapPayloadUpdate quota cap
29POST/bff/v1/eq/{org}/quotas:checkUpsertArray of ISiCheckUpsertQuotaPayloadValidate before setting quota

Request body​

15. si.playground.chat​

{
"model": "model-code",
"messages": [{ "role": "user", "content": "Hello", "reasoning_content": null, "name": "", "tool_call_id": "", "tool_calls": [] }],
"stream": true,
"stream_options": { "include_usage": true },
"temperature": 0.7, "top_p": 1, "max_tokens": 1024, "max_completion_tokens": 1024,
"frequency_penalty": 0, "presence_penalty": 0, "n": 1, "seed": 0, "stop": [],
"logit_bias": {}, "logprobs": false, "top_logprobs": 0,
"response_format": { "type": "text" },
"tools": [{ "type": "function", "function": { "name": "", "description": "", "parameters": {} } }],
"tool_choice": null, "metadata": {}, "user": ""
}

content is a string or array of objects (multimodal, e.g. image). Only model and messages are required.

27 / 28 / 29. Quota​

// 27 setQuotaCap
[{ "metric_key": "credit", "dimensions": { "service_code": "serverless-inference", "user_id": "..." }, "limit_value": 100, "period": "MONTH" }]

// 28 updateQuotaCap (limit_value null = remove cap)
[{ "metric_key": "credit", "dimensions": { "service_code": "...", "user_id": "..." }, "limit_value": 200, "workspace_id": "..." }]

// 29 checkUpsert
[{ "metric_key": "credit", "dimensions": { "service_code": "...", "user_id": "..." }, "limit_value": 200, "workspace_id": "..." }]

Responses​

ActionResponse (data)
si.model.list{ items: Model[], page, page_size, total, total_pages }; Model: id, code, name, version, model_type, status, access_level, host{id, code, name, host_type(resell|self_hosted), region_name, region_code}, tags[], introduction{short, long, usecase}, capabilities{context_length, max_output_tokens, supports_stream, supports_function_call, supports_vision, supports_json_schema}, docs{overview_md, details_md, benchmarks_md, usage_notes_md, image_url}, pricing{currency, input_price_per_1m, output_price_per_1m, cached_price_per_1m, billing_unit}, max_requests_per_minute, max_requests_per_minute_per_api_key, max_tokens_per_minute, max_tokens_per_minute_per_api_key, has_access_to_non_public_model, category, provider, parameters, performance, created_at, updated_at
si.model.getModel (same as above)
si.model.listoption{ categories[], providers[], model_types[{id, name, code}], hosts[{id, name, count}], data_residency[{id, name}] }
si.model.codesample[{ id, model_type, type, sdk, title, description, code_block, response_block, sort_order }]
si.apikey.list{ items: ApiKey[], page, page_size, total, total_pages }; ApiKey: id, name, masked_key, status, organization_id, user_id, models[{id, name, version, model_type, status}], rate_limit_per_hour, expires_at, last_used_at, created_at, updated_at
si.apikey.create{ api_key, key_info: ApiKey } (api_key is secret, shown only once)
si.apikey.edit / revokeApiKey
si.usage.view{ currency, estimated_cost, estimated_cost_change_pct, tokens_in, tokens_in_change_pct, tokens_out, tokens_out_change_pct, total_requests, total_requests_change_pct }
si.usage.model{ items: [{ model_code, model_name, provider_name, requests, tokens_in, tokens_out, cached_read_tokens, cost, currency }], page, page_size, total, total_pages }
si.usage.apikey{ items: [{ api_key_name, masked_key, scope, status, user_email, requests, tokens_in, tokens_out, cached_read_tokens, cost, currency }], ... }
si.usage.options{ api_keys: [{ id, masked_key, name, status, user_email }], models: [{ id, code, name }] }
si.playground.options{ models: [{ id, code, name, category, voices[], response_format[], price }] }
si.playground.chat (non-streaming){ id, object, created, model, provider, system_fingerprint, choices[{ index, finish_reason, logprobs, message }], usage{prompt_tokens, completion_tokens, total_tokens} }
si.playground.embedding[{ object, index, embedding: number[] | base64 string }]
si.voice.history.list{ items: [{ id, model_id, voice, input_text, speed, audio_format, audio_size_bytes, duration_seconds, status, has_audio, audio_url, audio_url_expires_at, expired_at, created_at }], total, page, page_size, total_pages }
si.voice.history.audiourl{ audio_url, expires_at, ttl_seconds }
quota-members[{ id, username, email, firstName, lastName, role, joinedAt, isActive, lastLogin, totalWorkspaces, status, canRemove, monthlyCap, hasCap, mtdUsage, percentageUsed, nearLimit }]
quota-members/overview{ workspaceQuota{ quotaId, limitValue, period, region, metricKey } | null, summary{ totalMembers, withCap, noCap, nearLimit } }
quota-members/usage{ monthlyCap, hasOwnCap, mtdUsage, percentageUsed, nearLimit }

Enums​

  • API key status: active, suspended, revoked, blocked, expired
  • host_type: resell, self_hosted
  • response_format (voice): mp3, wav, opus, flac, caf
  • encoding_format (embedding): float, base64; input_text_truncate: none, start, end; input_type: passage, query
  • Playground category: large_language_model, vision_language_model, embedding_model, speech_to_text, text_to_speech, rerank, vision_language_action

Notes​

  • Stream chat: si.playground.chat with stream: true sends Accept: text/event-stream and returns SSE (chunks chat.completion.chunk: choices[].delta{role, content, reasoning_content}; the final chunk may include usage). Errors during streaming return JSON body { code, message }.
  • Binary: si.tts.generate, si.playground.tts return audio files; the audio URL (if any) is in response header x-audio-url.
  • Voice Studio max input length is 5000 characters (FE).
  • Dedicated inference API docs: docs/dedicated-inference/api-endpoints.md.

Error codes​

Error format​

On error, HTTP status ≠ 2xx and the body has the following shape:

{ "code": "SI-KEYS-00004", "message": "...", "params": { "field": "name" }, "role_based": false, "statusCode": 400 }
  • role_based: true — the error message depends on the caller's role (MANAGEMENT / WS_ADMIN / MEMBER) and params.quotaLevel.
  • HTTP 401 — the client logs out.

Common error codes (billing / quota / gateway)​

CodeMeaning
INSUFFICIENT_BALANCEInsufficient credits (role-based). Role MANAGEMENT auto-opens the top-up modal.
INSUFFICIENT_PERMISSIONSThe caller does not have permission to perform this action.
EQ-RESOURCE-00001Quota reached (role-based, per params.quotaLevel: Organization / Workspace / Service).
EQ-RESOURCE-SYSTEM-LIMITResource quota reached (params.name).
BFF-CREATING-CONCURRENCYAnother resource is being created in this workspace/service.
route_not_foundEndpoint does not exist.
method_not_allowedWrong method. Only POST is accepted.
request_too_largeBody exceeds 64 KB.
invalid_tokenToken is invalid or expired.
gateway_internal_errorInternal gateway error.
upstream_unavailableBackend service is temporarily unavailable.
gateway_timeoutBackend service timed out.

Serverless Inference error codes (SI-*)​

CodeMessage
SI-AUTH-00001Authorization is required.
SI-AUTH-00002The access token is invalid or has expired.
SI-AUTH-00003User not authenticated.
SI-AUTH-00004Cannot access other user's data.
SI-AUTH-00005Organization scope missing from access token.
SI-AUTH-00006Authentication is temporarily unavailable.
SI-AUTH-00007Invalid or expired token.
SI-AUTH-00008Unauthorized - User not authenticated.
SI-KEYS-00001You are not a member of this organization.
SI-KEYS-00002One or more model IDs not found.
SI-KEYS-00003Cannot create API key: organization balance is insufficient. Please top up and try again.
SI-KEYS-00004An API key with this name already exists in this workspace.
SI-KEYS-00005Failed to create API key.
SI-KEYS-00006Failed to list API keys.
SI-KEYS-00007API key not found.
SI-KEYS-00008You are not authorized to access this API key.
SI-KEYS-00009API key has been revoked.
SI-KEYS-00010API key is inactive.
SI-KEYS-00011Failed to get API key.
SI-KEYS-00012You are not authorized to update this API key.
SI-KEYS-00014Invalid status transition. Revoked and blocked keys cannot be reactivated.
SI-KEYS-00016Failed to update API key.
SI-KEYS-00017You are not authorized to delete this API key.
SI-KEYS-00018Failed to delete API key.
SI-KEYS-00019You are not authorized to revoke this API key.
SI-KEYS-00020Failed to revoke API key.
SI-LEADS-00001A request for this model was already submitted with this email recently.
SI-LEADS-00002Validation failed.
SI-LEADS-00003Failed to submit contact-us lead.
SI-MODEL_HOST-00001Failed to create model host.
SI-MODEL_HOST-00002Failed to get model host.
SI-MODEL_HOST-00003Failed to list model hosts.
SI-MODEL_HOST-00004Failed to update model host.
SI-MODEL_HOST-00005Failed to delete model host.
SI-MODEL_HOST-00006Model host cannot be deleted while models still reference it.
SI-MODEL_SAMPLES-00001Failed to list samples.
SI-MODEL_SAMPLES-00002Failed to get sample.
SI-PERMISSION-00001Forbidden - Insufficient permissions.
SI-PLAYGROUND-00001Failed to list playground model options.
SI-PORTAL-MODELS-00001Failed to create model.
SI-PORTAL-MODELS-00002Failed to get model.
SI-PORTAL-MODELS-00003Failed to list models.
SI-PORTAL-MODELS-00006Failed to get related models.
SI-PORTAL-MODELS-00007Failed to update model.
SI-PORTAL-MODELS-00008Failed to delete model.
SI-PORTAL-MODELS-00009Failed to get capabilities.
SI-PORTAL-MODELS-00010Failed to update capabilities.
SI-PORTAL-MODELS-00011Failed to get pricing.
SI-PORTAL-MODELS-00012Failed to update pricing.
SI-PORTAL-MODELS-00013Failed to get limits.
SI-PORTAL-MODELS-00014Failed to update limits.
SI-PORTAL-MODELS-00015Failed to get rate limits.
SI-PORTAL-MODELS-00016Failed to update rate limits.
SI-PORTAL-MODELS-00017Failed to get docs.
SI-PORTAL-MODELS-00018Failed to update docs.
SI-PORTAL-MODELS-00019Failed to list benchmarks.
SI-PORTAL-MODELS-00020Failed to create benchmark.
SI-PORTAL-MODELS-00021Failed to delete benchmark.
SI-PORTAL-MODELS-00022Failed to list reviews.
SI-PORTAL-MODELS-00023Failed to get average rating.
SI-PORTAL-MODELS-00024Failed to create review.
SI-PORTAL-MODELS-00025Failed to delete review.
SI-PORTAL-MODELS-00026Failed to list active categories.
SI-PORTAL-MODELS-00027Failed to list active providers.
SI-PORTAL-MODELS-00028Failed to retrieve pricing information.
SI-PORTAL-MODELS-00030Failed to query Grafana.
SI-PORTAL-MODELS-00031Failed to list trending models.
SI-RESOURCE-00001{{resource}} not found.
SI-SYSTEM-00001Internal server error.
SI-USAGE-MODEL-00001Failed to retrieve model usage.
SI-USAGE-MODEL-00002Failed to retrieve usage statistics.
SI-USAGE-MODEL-00003Failed to retrieve usage options.
SI-USAGE-MODEL-00004Failed to retrieve API key usage.
SI-USER-00001User not found.
SI-VALIDATION-00001{{field}} should not exist.
SI-VALIDATION-00002{{field}} is required.
SI-VALIDATION-00003{{field}} must be an integer.
SI-VALIDATION-00004{{field}} must be a number.
SI-VALIDATION-00005{{field}} must be a boolean.
SI-VALIDATION-00006{{field}} must follow {{format}}.
SI-VALIDATION-00007{{field}} must be a valid email address containing an @ followed by a domain, for example name@example.com.
SI-VALIDATION-00008{{field}} must be a UUID.
SI-VALIDATION-00009{{field}} must be at least {{limit}}.
SI-VALIDATION-00010{{field}} must not exceed {{limit}}.
SI-VALIDATION-00011{{field}} must be one of: {{allowed_values}}.
SI-VALIDATION-00012{{field}} must be provided only once.
SI-VALIDATION-00013Request body must be valid JSON.
SI-VALIDATION-00014{{field}} is invalid.
SI-VALIDATION-00015{{field}} must be a string.
SI-VOICE-00001History is not found in caller scope.
SI-VOICE-00002History operation conflicts with current state.
SI-VOICE-00003History query/delete/persistence failure.
SI-VOICE-00004Object storage or presigning unavailable.