Swift API
Chat Completions for the Swift models, compatible with the OpenAI SDKs. Point an SDK at this base URL and use a key from the dashboard.
1. Create a key
Sign in to the dashboard and create a key. It's shown once, so save it somewhere safe.
2. Add credit
Add at least $5 on the Billing page. Usage is taken from your balance per token, and paid credit doesn't expire.
3. Make a request
Models and pricing
Prices are in US dollars per million tokens. Reasoning tokens count as output. GET /v1/models returns the same list.
Chat completions
POST /v1/chat/completions takes the OpenAI request format. These fields are used:
modelandmessages, with the rolessystem,developer,user,assistantandtoolmax_tokensormax_completion_tokens: 8,192 by default, up to the model's max outputtemperature,top_p,top_k,min_p,presence_penalty,frequency_penalty,repetition_penalty,seed,stoptools,tool_choice,parallel_tool_calls,response_formatlogprobsandtop_logprobs(up to 5)streamandstream_optionschat_template_kwargs.enable_thinking, see Reasoning
Other fields are ignored, and n must be 1. If your balance can't cover max_tokens, it's lowered to what the balance covers and the response carries an x-max-tokens-applied header.
GET /v1/credits returns your balance, tier and limits for the key you send.
Streaming
With "stream": true the response is a stream of server-sent events that ends with data: [DONE]. Set stream_options.include_usage to get a last chunk with the token counts. If you stop reading early, you pay for the tokens generated up to that point.
Tool calls
Tools use the OpenAI function format. The model replies with tool_calls; run the tool and send its result back as a tool message with the matching tool_call_id.
Images
Send images as image_url content parts with a base64 data URL in PNG, JPEG, WebP or GIF. Links to images on the web are refused. Images are billed as input tokens.
Reasoning
Swift thinks before it answers. The thinking arrives in reasoning_content, next to content, and is billed as output tokens. To answer without thinking, set enable_thinking to false:
Prompt caching
When a request starts with the same tokens as a recent one, that shared start is billed at the cached input price. It happens on its own; usage.prompt_tokens_details.cached_tokens shows how many tokens were cached. Keep the parts that don't change, such as the system prompt, tools and documents, at the start.
Rate limits
Limits apply to your account across all its keys. Tiers rise with the credit you've paid in and the age of your first payment. Tokens per minute count uncached input plus output; requests at once are counted per model.
Every response carries x-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests and the same three for tokens. A 429 response carries Retry-After.
Errors
Errors use the OpenAI shape, {"error": {"message", "type", "code"}}, and every response has an x-request-id.
| Status | Code | What to do |
|---|---|---|
| 400 | invalid_request | Fix the request; the message says what's wrong. |
| 401 | invalid_api_key | Check the key. Revoked keys stop working at once. |
| 402 | insufficient_quota | Add credit. Retrying won't help. |
| 403 | account_suspended | Write to hello@ukisai.com. |
| 404 | model_not_found | Use a model from GET /v1/models. |
| 429 | rate_limit_exceeded | Retry after Retry-After seconds. |
| 429 | concurrency_limit_exceeded | Wait for a request to finish, or move up a tier. |
| 429 | model_at_capacity | The model is busy. Retry after Retry-After seconds. |
| 429 | spend_limit_exceeded | Your tier's monthly limit is reached. |
| 503 | model_unavailable | The model is down. Retry later. |
Data and privacy
We don't store or log prompts or outputs, and we don't train on them. For billing we keep the token counts, cost and timing of each request.
The API runs on a best-effort basis with no uptime guarantee. Models marked Preview can change or go away. See the Terms.