Protect your keys
- Keep keys in environment variables or a secret manager. Never commit them or put them in browser or mobile code.
- Use a separate key per application and environment, with a monthly cap and, where you can, an allowed-models list and an IP allowlist. See API keys.
- Revoke a leaked key at once. Revocation takes effect within about 10 seconds.
Retry the right errors
Retry 429, 500, 502, 503 and 504. Do not retry 400, 401, 402, 403, 404 or 413 without changing something. See Errors.
- Honor
Retry-Afterwhen present. - Otherwise use exponential backoff with jitter, for example 1 s, 2 s, 4 s, each randomized by up to 50%, with a cap on the number of attempts.
- For non-streaming requests, send an
Idempotency-Keyand reuse it on every retry so you cannot be billed twice. See Idempotency.
ts
async function chatWithRetry(body: unknown, attempts = 4): Promise<Response> {
const idempotencyKey = crypto.randomUUID();
for (let i = 0; ; i += 1) {
const res = await fetch("https://api.ticonai.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AIP_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify(body),
});
const retryable = [429, 500, 502, 503, 504].includes(res.status);
if (!retryable || i + 1 >= attempts) return res;
const wait = Number(res.headers.get("retry-after")) || 2 ** i;
await new Promise((r) => setTimeout(r, wait * 1000 * (1 + Math.random() * 0.5)));
}
}Control cost
- Set
max_tokensto what you need (it is required on/v1/messages). It bounds the cost of the answer and the size of the wallet hold. See Billing and wallet. - Keep prompts short. Send only the context the model needs.
- Pick the smallest model that does the job; compare prices on the pricing page.
- Watch your balance and turn on the low-balance notification in the app, so a top-up lands before requests start failing with
402.
Make long answers feel fast
Use streaming for long outputs so users see text immediately. Handle the in-stream error event, and cancel the request when the user leaves, since output you no longer need still costs money once it has started.
Make requests easy to debug
- Log the
x-request-idresponse header with every call (not the prompt). Support can find a request by it. - Treat error
codeas the contract andmessageas text for humans. - Check
usagein responses against your own estimates to catch prompt bloat.
Timeouts
Set a client timeout a little above the 120 seconds the gateway allows for non-streaming requests, and prefer streaming for work that may take longer.