Skip to main content

InferNode API

Base path: https://api.<tu-dominio>/infernode/v1. Authentication with Authorization: Bearer sk-saptiva-.... Compatible with the OpenAI SDK (see Use the API from code).

Inference​

Method and pathDescription
POST /v1/chat/completionsChat. Fields: model, messages, stream, temperature, top_p, max_tokens, n, stop, presence_penalty, frequency_penalty, seed, tools, tool_choice, response_format, logprobs, top_logprobs. The reasoning parameters thinking_token_budget, chat_template_kwargs (enable_thinking, reasoning_budget) and reasoning (effort) are forwarded to the model without being interpreted (X-Saptiva-Passthrough header). With stream: true it responds over SSE with the OpenAI chunk format.
POST /v1/embeddingsVectors. model, input (string or list), dimensions (up to the model's maximum, 4096 for the platform's model), encoding_format (float or base64).
POST /v1/images/generationsGenerates images. Body: preset (name of the image model in the Catalog), prompt (up to 4096 characters), n (1 to 4), size (default 1024x1024). Returns the result, or a job with job_id if the generation is asynchronous. Counts against the images-per-minute limit.
GET /v1/images/generations/{job_id}Status and result of the job.
POST /v1/guardEvaluates a text against the risk categories.
GET /v1/guard/eventsRecorded evaluations of your Client.

Request and response example​

The examples call by alias, which is the recommended way: the exact Catalog name is accepted too, but it changes when the model is updated. The response returns in model the model that answered, not the alias you called with.

curl https://api.<tu-dominio>/infernode/v1/chat/completions -i \
-H "Authorization: Bearer sk-saptiva-..." -H "Content-Type: application/json" \
-d '{"model": "Saptiva Turbo", "messages": [{"role": "user", "content": "Hola"}], "max_tokens": 64}'
HTTP/1.1 200 OK
X-Request-Id: req_01J9X4M2K7
X-RateLimit-Remaining-Requests: 58
X-RateLimit-Remaining-Tokens: 199872
X-Request-Cost: 0.0004
X-Credits-Remaining: 1249.31
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "Qwen3.6 35B A3B (FP8)",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "Hola, ¿en qué puedo ayudarte?" }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 9, "completion_tokens": 11, "total_tokens": 20 }
}

An error uses the OpenAI envelope with request_id:

{ "error": { "type": "rate_limit_error", "code": "rate_limit_exceeded", "message": "Token limit exceeded, resets in 42s", "request_id": "req_01J9X4M2K7" } }

Batches​

Asynchronous requests in a file, compatible with the OpenAI Batch API. Guide in Process requests in batches. If the installation does not have them enabled, these routes respond 404.

Method and pathDescription
POST /v1/filesUploads the input file. Multipart with purpose=batch (the only accepted value) and file. Returns an object with id, bytes, filename, purpose, status and created_at. The same content uploaded twice returns the existing file, with the X-Saptiva-Deduplicated-From header
GET /v1/filesFiles of the organization
GET /v1/files/{file_id}Metadata of a file
GET /v1/files/{file_id}/contentDownloads the bytes. Responds with X-Saptiva-Content-SHA256. It is the only way to download: there are no temporary links
DELETE /v1/files/{file_id}Deletes a file. An input file used by a live batch responds 400 file_in_use
POST /v1/batchesCreates the batch. Body: input_file_id, endpoint (/v1/chat/completions or /v1/embeddings), completion_window (only "24h", with no delivery promise) and optional metadata
GET /v1/batchesBatches of the organization. limit from 1 to 100 (20 by default) and after with a batch id as the cursor
GET /v1/batches/{batch_id}Status and result of the batch
POST /v1/batches/{batch_id}/cancelCancels. From finalizing or a terminal state it responds 400 batch_not_cancellable

The batch object includes status, input_file_id, output_file_id, error_file_id, endpoint, model, completion_window, metadata, request_counts (total, completed, and failed, which adds up the failed, cancelled and expired lines), errors.data, usage when it finishes, and the timestamps of each transition (created_at, in_progress_at, expires_at, finalizing_at, completed_at, failed_at, expired_at, cancelling_at, cancelled_at).

errors.data carries the causes when the whole file fails and, when someone other than its owner cancelled the batch, a cancelled_by_org_admin or cancelled_by_platform_admin entry.

Statuses: validating, in_progress, finalizing, cancelling, and the terminal ones completed, failed, cancelled and expired.

The output file contains only the lines that finished successfully; the rest go to the error file. Input and output files expire after 30 days by default, with the date in expires_at.

Each line is billed as the equivalent call, with no discount. The transaction carries the endpoint marked, visible in last_event.endpoint of GET /v1/billing/balance (/v1/chat/completions:batch). The lines do not consume the per-minute limits; the calls in this section do.

Models​

Method and pathDescription
GET /v1/modelsModels available for the key.
GET /v1/models/{name}Detail: type, provider, capabilities, context_window, max_output_tokens, pricing (input, output, unit, currency) and deprecation (deprecated_at, retires_at). With an alias, X-Alias-Of header.
GET /v1/models/aliasesPublic aliases and the model they point to.

Account and keys​

Method and pathDescription
GET /v1/meorg, user, membership, plan (with is_billing_exempt and has_rate_limits) and the api_key you called with.
GET /v1/me/orgsOrganizations you belong to.
GET /v1/me/api-keysThe user's keys (without the secret).
POST /v1/me/api-keysCreate a key. The secret is shown only once.
POST /v1/me/api-keys/{id}/rotateRotate: new key, the previous one stops working.
DELETE /v1/me/api-keys/{id}Revoke.

Usage​

Method and pathDescription
GET /v1/billing/balancecredits_remaining, initial_credits, spending_caps, usage_this_month, last_event; is_billing_exempt indicates whether the plan deducts credits.
GET /v1/billing/usage?period=AAAA-MMtotal_requests, total_tokens_in, total_tokens_out, total_cost, by_model, by_api_key, daily_breakdown (and by_user for administrators).
GET /v1/billing/transactionsCredit transactions.

Response headers​

X-Request-Id, X-RateLimit-Limit-Requests, X-RateLimit-Remaining-Requests, X-RateLimit-Reset-Requests, X-RateLimit-Limit-Tokens, X-RateLimit-Remaining-Tokens, X-RateLimit-Reset-Tokens, X-Request-Cost, X-Credits-Remaining, X-Credits-Warning, X-Model-Deprecated, X-Model-Retires-At, X-Alias-Of, X-Saptiva-Passthrough, X-Saptiva-Model-Defaults; on a 429, also Retry-After. In streaming responses the token headers are not sent (the count happens after the header is emitted). Meaning in InferNode.

Errors​

Extended OpenAI envelope: {"error": {"type", "code", "message", "param", "request_id", "details"}}. code carries the module as a prefix when applicable (identity.invalid_token, identity.org_suspended) or is flat (model_not_found, rate_limit_exceeded, insufficient_credits, parameter_not_supported). Types: invalid_request_error, authentication_error, permission_error, not_found_error, billing_error, rate_limit_error, provider_error, maintenance_error, internal_error. A 429 includes details.dimension (rpm, rpd, tpm, tpd, ipm). Details in Error codes.

The platform administration operations (adding models, per-Client limits, credits, auditing) are under /v1/admin/* and /v1/billing/admin/*, reserved for the operator.