Developer guidelines
Talo API documentation.
One key, one request format.
Authentication, model selection, usage and safe integration for PHP, JavaScript, Java and cURL.
Connect your application to Talo
Send API calls from your backend over HTTPS with Content-Type: application/json and the Bearer key. GET reads the model list; POST creates chat or images. Browser form checks improve usability; the server independently validates every request. Do not put API keys in URL parameters. Cross-origin browser calls with long-lived keys are not supported.
One key · one request format
Your application → your server → Talo authentication, model access and credit check → selected provider adapter → normalized response and usage settlement.
Fund your account, activate a monthly plan, then create a key with access to your chosen models. Monthly access and generation usage are charged separately. Store the key in your server's environment or secret manager; never in frontend JavaScript, mobile bundles or a public repository.
Base URL: https://taloventra.com/api/v1. Your existing API keys remain compatible. All providers use the same public model aliases and request fields; no provider key is needed in your application.
Setup and discover available models
Set TALO_API_KEY securely, then run:
curl --fail-with-body https://taloventra.com/api/v1/models \
-H "Authorization: Bearer $TALO_API_KEY"Set TALO_MODEL to an ID returned by this endpoint. It lists your permitted models, pricing, context and streaming support. Optional TALO_BASE_URL selects a test installation; production must use HTTPS. Examples below make one billable request, use 64 maximum output tokens and do not automatically retry.
Request, response and conversation history
Send model, a messages array of text-only system/user/assistant messages, and max_tokens. Optional temperature ranges from 0 to 1 for portability; some models support up to 2. The adapter selects the private model, authentication headers, token parameter and provider-specific message layout.
{"model":"your-public-alias","messages":[{"role":"system","content":"Be helpful."},{"role":"user","content":"Hello"}],"max_tokens":64}Read choices[0].message.content, usage.prompt_tokens, usage.completion_tokens and talo_request_id in the JSON response. See Usage for the settled USD charge and any outstanding holds.
There is no shared provider conversation session. Your server stores history per authenticated user and conversation, checks ownership, then sends the relevant history with each request. A shared application key does not perform your application's user authentication. Never mix histories between users. Previous messages count toward input usage on each call.
Copy a server-side example
#!/usr/bin/env bash
set -euo pipefail
: "${TALO_API_KEY:?Set your Talo API key}"
: "${TALO_MODEL:?Choose an ID from GET /models}"
[[ "$TALO_MODEL" =~ ^[a-z][a-z0-9-]{1,59}$ ]] || exit 1
base="${TALO_BASE_URL:-https://taloventra.com/api/v1}"
request_id="$(cat /proc/sys/kernel/random/uuid)"
curl --fail-with-body --silent --show-error --max-time 150 \
"$base/chat/completions" \
-H "Authorization: Bearer $TALO_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $request_id" \
--data "{\"model\":\"$TALO_MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"Say hello\"}],\"max_tokens\":64}"<?php
$key = getenv('TALO_API_KEY');
$model = getenv('TALO_MODEL');
if (!$key || !$model) throw new RuntimeException('Set TALO_API_KEY and TALO_MODEL');
$base = rtrim(getenv('TALO_BASE_URL') ?: 'https://taloventra.com/api/v1', '/');
$requestId = bin2hex(random_bytes(16));
$curl = curl_init($base . '/chat/completions');
curl_setopt_array($curl, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 150,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key,
'Content-Type: application/json', 'Idempotency-Key: ' . $requestId],
CURLOPT_POSTFIELDS => json_encode(['model' => $model,
'messages' => [['role' => 'user', 'content' => 'Say hello']],
'max_tokens' => 64], JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
$error = curl_error($curl);
curl_close($curl);
if ($raw === false) throw new RuntimeException('Network error; check Usage before retrying: ' . $error);
$result = json_decode($raw, true, 64, JSON_THROW_ON_ERROR);
if ($status !== 200) throw new RuntimeException('HTTP ' . $status . ': ' . ($result['error']['code'] ?? 'request_failed'));
echo json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
// Assistant text: $result['choices'][0]['message']['content']import { randomUUID } from 'node:crypto';
const { TALO_API_KEY: key, TALO_MODEL: model } = process.env;
if (!key || !model) throw new Error('Set TALO_API_KEY and TALO_MODEL');
const base = (process.env.TALO_BASE_URL || 'https://taloventra.com/api/v1').replace(/\/$/, '');
const response = await fetch(`${base}/chat/completions`, {
method: 'POST', signal: AbortSignal.timeout(150000),
headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json',
'Idempotency-Key': randomUUID() },
body: JSON.stringify({ model, messages: [{ role: 'user', content: 'Say hello' }], max_tokens: 64 })
});
const result = await response.json();
if (!response.ok) throw new Error(`HTTP ${response.status}: ${result.error?.code || 'request_failed'}`);
console.log(JSON.stringify(result, null, 2));
// Assistant text: result.choices[0].message.content
// On timeout/network failure, check Usage before intentionally making another request.import java.net.URI;
import java.net.http.*;
import java.time.Duration;
import java.util.UUID;
public class TaloExample {
public static void main(String[] args) throws Exception {
String key = System.getenv("TALO_API_KEY");
String model = System.getenv("TALO_MODEL");
if (key == null || model == null || !model.matches("[a-z][a-z0-9-]{1,59}"))
throw new IllegalArgumentException("Set TALO_API_KEY and a valid TALO_MODEL");
String base = System.getenv().getOrDefault("TALO_BASE_URL", "https://taloventra.com/api/v1");
String body = "{\"model\":\"" + model + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Say hello\"}],\"max_tokens\":64}";
HttpRequest request = HttpRequest.newBuilder(URI.create(base.replaceAll("/$", "") + "/chat/completions"))
.timeout(Duration.ofSeconds(150))
.header("Authorization", "Bearer " + key)
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.POST(HttpRequest.BodyPublishers.ofString(body)).build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200)
throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body());
System.out.println(response.body());
// Parse JSON with your application's JSON library; read choices[0].message.content.
// For dynamic messages use that library's JSON encoder, not string concatenation.
}
}Save JavaScript as talo.mjs and run node talo.mjs; PHP as talo.php and run php talo.php; Java as TaloExample.java and run java TaloExample.java. The Bash example requires Linux and cURL 7.76+.
Stream a response
For a model with streaming: true, add "stream":true,"stream_options":{"include_usage":true} to the same chat body. With cURL add --no-buffer. Parse complete SSE data: frames, read choices[].delta.content, and finish on [DONE]. Network chunks are not necessarily complete JSON frames. The final usage frame follows settlement. An SSE error can arrive after HTTP 200; handle it and check Usage before retrying.
Token pricing & credit holds
Input, cached input and output are billed separately from actual provider usage. Before generation, a conservative estimate reserves enough credit for your input and maximum output; the unused amount is released on completion. Holds can exceed the final charge. Cached tokens are not billed twice. Model rates are fixed for each accepted request.
Uncertain provider failures retain a hold until reviewed. A repeated idempotency key returns 409 and does not run or charge the request again. Use a new key only for an intentionally new request. UTC calendar-month limits apply to model usage; subscription fees are separate.
Limits and supported features
This version supports text-only system/user/assistant messages, temperature and bounded output. Maximum request body: 300 KB; up to 128 messages and 250 KB of message text including framing allowance; maximum output: 8,192 tokens. Provider context capacity is listed separately and does not remove these gateway request limits. Models marked streaming=true in the model list support stream=true for server-sent event output. Anthropic connections currently support non-streaming text responses. A terminal usage chunk is followed by [DONE] after billing settles. If generation is interrupted, check Usage before retrying. Tool calls, image/audio input and Responses API are not enabled in this version.
| HTTP | Meaning | Action |
|---|---|---|
| 400 / 413 / 415 | Invalid JSON, unsupported content type or oversized request | Check parameters and reduce input/output |
| 401 / 403 | Invalid key, access or subscription | Check key expiry, model access and plan |
| 402 | Credit or spend limit reached | Review balance, reservations and caps |
| 409 | Duplicate idempotency key | Inspect the request in Usage |
| 429 | Rate or concurrency limit | Respect Retry-After |
| 502 / 503 | Provider or service unavailable | Check request status before retrying |
Data handling
Your requests are routed to the configured AI service providers to generate responses. Public model IDs are Taloventra aliases. See the service privacy terms for processing and subprocessors. Talo records usage and billing metadata but does not retain message text in the usage ledger. Provider processing and retention follow your service agreement. Keep sensitive data out of test requests.
Generate an image
Choose an image model from GET /v1/models. One image per call, fixed model size, base64 output. The same key, balance and spending limits apply. Image prompts are limited to 8 KB. Image generation is non-streaming.
curl https://taloventra.com/api/v1/images/generations \
-H "Authorization: Bearer $TALO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(cat /proc/sys/kernel/random/uuid)" \
-d '{"model":"talo-image","prompt":"A green garden","n":1,"response_format":"b64_json"}'The image alias above is an example: use an enabled model from your model list. Never automatically retry an uncertain image request. HTTP 402 insufficient_credit includes a top-up link; a spend_limit response requires reviewing your chosen caps, not just adding credit.