Skip to main content
The SinarCloud AI API uses the OpenAI API format. You can call it over plain HTTP, or point an OpenAI SDK at it by changing the base URL, the API key, and the model name. It also accepts the Anthropic Messages format, which tools such as Claude Code use. See Anthropic Messages format. This page covers the endpoints, the request rules SinarCloud enforces, the errors you can receive, and how each request is charged to your balance.

Base URL and API key

The base URL is https://ai.sinarcloud.com/v1.
1

Create an API key

In the console sidebar, under AI, click API keys. Create a key there, for example with Create API key in the quick start. See API keys.
2

Store your API key as an environment variable

Send the key as a bearer token in the Authorization header of every request, including GET requests:
SinarCloud reads the key from the Authorization header. The Anthropic Messages endpoints also accept it in the x-api-key header, where Anthropic clients send it. If a request sends both headers, they must hold the same key. Other headers, such as api-key, are not accepted.
Keep your API key on your server. Anyone who has the key can make requests that are charged to your account.

Endpoints

The base URL already ends in /v1, so add only the rest of the path. For example, use https://ai.sinarcloud.com/v1/chat/completions. Any other path under /v1 returns 404 with the code unsupported_endpoint. A path that doesn’t start with /v1 returns 404 with the code not_found. POST requests to the OpenAI endpoints must not include query parameters. The Anthropic Messages endpoints ignore them. The other POST endpoints take the same headers and the standard OpenAI body for that endpoint. For example, an embeddings request looks like this:
Replace MODEL_ALIAS with the alias of a model that lists Embeddings on the Models page.

Send a chat completion

The Python and TypeScript examples use the official OpenAI SDK (pip install openai or npm install openai). The cURL examples use macOS and Linux shell syntax. For a guided first call, see Make your first AI request.
To call a different model, replace deepseek/deepseek-v4-1-flash with the alias of a model from the Models page. The response uses the OpenAI chat completion format. Read the reply from choices[0].message.content and the token counts from usage. The model field in the response always contains the alias you sent. Some models also return the reasoning they do before they answer, in a reasoning_content or reasoning field of message, or of delta when you stream. Reasoning tokens count toward completion_tokens in usage and are charged at the output price. See How tokens are counted.
The console also has ready-made requests. On the API keys page, the Quick start (cURL) box holds a sample cURL request for a chat model. To call a different model, swap in another alias. On the Models page, each model’s details have a Use via API tab with samples for that model in cURL, Python, TypeScript, and Go. Replace YOUR_API_KEY in either sample with your key.

Anthropic Messages format

Tools and SDKs built for Anthropic’s API, such as Claude Code, can call POST /v1/messages with the standard Anthropic Messages body. They add /v1/messages to the base URL themselves, so give them https://ai.sinarcloud.com as the base URL, without /v1.
cURL
The response uses the Anthropic message format, with the reply in content. SinarCloud runs these requests on the model’s chat completions, so the model must list Chat completions. Requests are charged like any other request. These rules differ from the OpenAI endpoints:
  • max_tokens is required and can’t be higher than the model’s Maximum output (tokens).
  • Tools must be your own: each tool needs a name and an input_schema, and no type other than custom. Anthropic’s built-in tools, such as web search or code execution, return 400 with the message “Only caller-executed tools are supported.” So does mcp_servers.
  • Documents such as PDFs aren’t accepted. They return 400 with the message “This model does not support PDF input or other documents.” Images need a model that lists Image input or Vision.
  • metadata may hold only a user_id string.
  • If the model has no cache write price for the duration you request, SinarCloud removes the cache_control marks and runs the request without them, instead of returning an error.
POST /v1/messages/count_tokens counts the input tokens of a Messages request without running it. It doesn’t need max_tokens, and it’s never charged. The count is an estimate. See Count tokens before you send. Errors from these endpoints use Anthropic’s error format, with the error type in error.type, for example authentication_error for 401, billing_error for 402, and not_found_error for 404. The request ID is also in a request-id header.

Choose a model alias

Every request names its model by alias in the model field. To find an alias, open Models. Each model’s alias appears under its name. Click the copy icon (Copy model alias) next to it to copy it. Aliases use lowercase letters, digits, ., _, : and -, and can contain /. The model must be available and must list the capability for the endpoint you call. Otherwise the request fails with 404 and the code model_not_found. To see what a model supports, click Details in its row. The details list its capabilities under Model capabilities, and its output limit under Maximum output (tokens). See Models and pricing.

Zero data retention (ZDR) versions

Some models also have a zero data retention version, marked with a ZDR tag on the Models page. When you hover over the tag, it reads “Zero data retention: your prompts and responses aren’t kept after your request is complete.” Not every model has a ZDR version. A ZDR version is a separate model. It has its own alias, which ends in -zdr, and its own prices and limits. Its prices can be higher than the standard version’s, so check them in its details. The Models page lists ZDR versions together with all the other models. Copy a ZDR version’s alias and send it in model, like any other model. Everything else on this page applies to ZDR versions in the same way.

Request body rules

SinarCloud checks your JSON body, then forwards it to the model. If the model does not support a parameter, the parameter may be ignored instead of returning an error.
  • model is required and must be a string.
  • stream, when sent, must be true or false.
  • The output limit must be a positive whole number no higher than the model’s Maximum output (tokens). Chat completions use max_completion_tokens or max_tokens, completions use max_tokens, and responses use max_output_tokens.
  • n and best_of must be 1 when sent. Each request returns one choice.
  • metadata, when sent, must be a JSON object. Some keys inside metadata are reserved and return 400.
  • The body must stay within the request size limit. A larger body returns 413 with the code request_too_large.
SinarCloud rejects these with 400 and the code invalid_request:
  • Fields that pass credentials, choose where the request is sent, or change routing, retries, or timeouts. Examples are api_key, base_url, fallbacks, num_retries, timeout, extra_body and service_tier.
  • Anything that stores data for later requests or points to stored data: "store": true, "background": true, previous_response_id, conversation, prompt (stored prompt references) on the Responses API, file inputs, and file_id references. With the Responses API, send the full context in each request and leave store unset or false.
  • Built-in tools that would run outside your application, such as web search, file search, code interpreter, image generation, and MCP tools, and the web_search_options field. Use tools that your application runs, such as function tools.
These rules apply to fields in the JSON body. OpenAI SDK client options such as timeout and max_retries are not sent in the body, so you can use them. The SDK’s extra_body option is also fine, as long as it does not add any of the fields above.

Features that need a model capability

If the model does not list the capability, the request fails with 400 and the code unsupported_model_capability. The message names the feature, for example “The requested model does not support streaming.”

Prompt caching

Each model’s details on the Models page list three cache prices: Cache read per 1M tokens, Cache write (standard) per 1M tokens, and Cache write (1 hour) per 1M tokens. A price the model doesn’t have shows Not available. The model list also has Cache read and Cache write columns, where a dash means the model has no such price. The Cache write column shows the standard price. Cached input tokens that the model reports are charged at the cache read price. To mark content for caching, add "cache_control": {"type": "ephemeral"} to a message, content block, or tool. The default duration is 5m. Add "ttl": "1h" inside cache_control to cache for one hour. Any other ttl value is rejected. The prompt_cache_retention field isn’t accepted and returns 400 with the code invalid_request, so set the duration with ttl instead. Use one cache duration per request. The default 5m duration needs a Cache write (standard) price, and 1h needs a Cache write (1 hour) price. If that price shows Not available, the request fails with 400, the code invalid_request, and the message “The requested cache write duration is unavailable for this model.” So send cache_control only to models that show a cache write price.

Stream responses

Set "stream": true on a model that lists Streaming. The response is a stream of server-sent events (text/event-stream). Each event has a data: line that holds one JSON chunk. Responses API streams also include an event: line that names each event. A chat completion stream ends with data: [DONE]. Lines that start with : are keep-alive comments, so ignore them.
To get token counts for a chat completion stream, add "stream_options": {"include_usage": true} to the body. A chunk with usage then arrives at the end of the stream. If the model fails after the stream starts, the stream can end before [DONE]. It can also contain a chunk with an error object that uses one of the codes under Errors, such as upstream_error or context_length_exceeded.

List models

GET /v1/models returns the models that are currently available. The list includes models of every type, such as chat and embedding models. Check a model’s capabilities on the Models page before you call it. GET /v1/models/MODEL_ALIAS returns one model. You can put an alias that contains / directly in the path. If the model is not available, the response is 404 with the code model_not_found.
Use id as the model value in your requests. The list does not include prices or capabilities. Check those on the Models page. Listing models is never charged.

Track a request

Every response includes an X-Request-Id header. To use your own ID, send an X-Request-Id header of up to 100 characters. It must start with a letter or digit and can contain letters, digits, and ., _, :, / and -. Otherwise SinarCloud generates an ID for you. The same value appears as Request ID when you click Show details on a request under Recent requests, on the Log tab of the Usage page. Only your most recent requests are listed, so record the X-Request-Id from the response if you need it later.

Errors

Errors use the OpenAI error format, except on the Anthropic Messages endpoints. Check the code field to tell errors apart, because several errors can share one HTTP status.
Retry 429, 502, 503 and 504 errors after a short wait, and increase the wait between attempts. The exception is a 503 with key_provisioning_pending: create a new key instead. Change the request or your account before you retry a 400, 401, 402, 403, 404, 413 or 422 error. A 404 with model_not_found can also mean the model is temporarily unavailable. Check the model on the Models page, then retry later.

How requests are charged

Before a request starts

SinarCloud starts a request only when one of these is true:
  • Your balance is above zero.
  • You have token credits left for that model.
  • The request costs nothing, for example on a free model or with a promotion that makes the model free.
Otherwise the request fails with 402 and the code insufficient_balance.

After a request finishes

Model prices are in rupiah per 1M tokens and appear on the Models page. The price and any promotion in effect when your request starts apply to that request. The full price of a request is:
The cache write price is Cache write (standard) per 1M tokens for the default 5-minute cache, or Cache write (1 hour) per 1M tokens when you set "ttl": "1h". Input tokens in this formula exclude the tokens charged as cache reads or cache writes. If the model has no price for a kind of cache token, those tokens are charged at the input price. Output tokens include any reasoning tokens the model uses, even when the reasoning text is not returned to you. For worked examples, see How tokens are counted. Every request that costs something has a full price of at least Rp 0.6. If a request’s tokens cost less than that, its full price is Rp 0.6. Requests on a free model, and requests that use no tokens, stay free. SinarCloud then pays the full price in this order:
  1. Your token credits for the model cover as many tokens as they can.
  2. A promotion shown for the model on the Models page discounts what remains. See Models and pricing.
  3. The rest is deducted from your balance.
A promotion that makes the model free applies first, so your token credits are not used while the promotion lasts. You are charged after the request finishes, so a large request can take your balance below zero. Your next top-up covers the negative amount first. A request that the model rejects or fails isn’t charged. If the model produced output that didn’t fully reach you, for example after a timeout, a dropped connection, or a stream you stopped early, the request can still be charged for the tokens it used. Your latest charged requests appear under Recent requests on the Usage page, with their tokens and cost. Older requests are included in the totals and reports. When token credits or a promotion reduced the charge, Show details includes a Charge breakdown. See Usage and spending. On the Billing page, the Transactions tab adds up each day’s AI charges into one AI usage transaction. See Balance and billing.