Base URL and API key
The base URL ishttps://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
Authorization header of every request, including GET requests:
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.
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:
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.
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.
Anthropic Messages format
Tools and SDKs built for Anthropic’s API, such as Claude Code, can callPOST /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
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_tokensis required and can’t be higher than the model’s Maximum output (tokens).- Tools must be your own: each tool needs a
nameand aninput_schema, and notypeother thancustom. Anthropic’s built-in tools, such as web search or code execution, return400with the message “Only caller-executed tools are supported.” So doesmcp_servers. - Documents such as PDFs aren’t accepted. They return
400with the message “This model does not support PDF input or other documents.” Images need a model that lists Image input or Vision. metadatamay hold only auser_idstring.- If the model has no cache write price for the duration you request, SinarCloud removes the
cache_controlmarks 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 themodel 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.modelis required and must be a string.stream, when sent, must betrueorfalse.- The output limit must be a positive whole number no higher than the model’s Maximum output (tokens). Chat completions use
max_completion_tokensormax_tokens, completions usemax_tokens, and responses usemax_output_tokens. nandbest_ofmust be1when sent. Each request returns one choice.metadata, when sent, must be a JSON object. Some keys insidemetadataare reserved and return400.- The body must stay within the request size limit. A larger body returns
413with the coderequest_too_large.
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_bodyandservice_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, andfile_idreferences. With the Responses API, send the full context in each request and leavestoreunset orfalse. - 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_optionsfield. Use tools that your application runs, such asfunctiontools.
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.
"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.
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 anX-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 thecode field to tell errors apart, because several errors can share one HTTP status.
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.
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:"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:
- Your token credits for the model cover as many tokens as they can.
- A promotion shown for the model on the Models page discounts what remains. See Models and pricing.
- The rest is deducted from your balance.