TitikAPI mengekspos API model di path /v1. Ganti base URL dan API key pada klien OpenAI yang sudah ada, lalu pilih model id dari katalog.
Katalog publik saat ini mencantumkan 17 model.
Base URL
https://api.titikapi.com/v1
Autentikasi
Setiap request memakai header Authorization dengan API key akunmu (awalan tk_live_). Key lengkap hanya ditampilkan sekali saat dibuat.
Authorization: Bearer $TITIKAPI_API_KEY
Request pertama
Contoh Chat Completions. Ganti model id jika katalog sudah berubah.
curl https://api.titikapi.com/v1/chat/completions \
-H "Authorization: Bearer $TITIKAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-8-27b",
"messages": [{"role": "user", "content": "Halo"}]
}'Langkah berikutnya
- Daftar dan buat API key
- Referensi API lengkap (setelah masuk)
- Bandingkan
- OpenAI SDK
- Katalog model
- Tentang
Autentikasi
Setiap request membawa key di header Authorization: Bearer tk_live_…. Key berlaku untuk semua endpoint, termasuk format Anthropic Messages.
Panggil API dari server atau dari tool di komputer Anda, jangan dari browser atau aplikasi mobile: key di sisi klien bisa dibaca siapa saja. Jangan taruh key di query string. Kalau key bocor, cabut di API Keys dan buat yang baru.
POST /v1/chat/completions HTTP/1.1
Authorization: Bearer $TITIKAPI_API_KEY
Content-Type: application/jsonTool calling
Berikan daftar tools, dan model bisa membalas dengan tool_calls alih-alih teks. Jalankan tool-nya di sisi Anda, lalu kirim hasilnya sebagai pesan role: "tool" dengan tool_call_id yang sama. Format ini sama persis dengan OpenAI, termasuk saat streaming.
Tool calling tersedia di Chat Completions untuk model yang mendukungnya — lihat capabilities.tools di GET /v1/models. Definisi tools ikut dihitung sebagai token input.
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Cuaca terkini untuk satu kota",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
reply = client.chat.completions.create(
model="qwen3-8-27b",
messages=[{"role": "user", "content": "Cuaca di Jakarta?"}],
tools=tools,
)
call = reply.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)Endpoint
Satu key dan satu saldo untuk semua format. Model id sama di setiap format, dan tidak berubah walau jalur di belakangnya berubah.
| Endpoint | Kegunaan |
|---|---|
| GET/v1/models | Daftar model aktif untuk key ini, dengan kemampuan dan harga IDR. |
| POST/v1/chat/completions | Format OpenAI Chat Completions, termasuk tool calling. |
| POST/v1/responses | Format OpenAI Responses, untuk model yang mendukungnya. |
| POST/v1/messages | Format Anthropic Messages, untuk model yang mendukungnya. |
curl https://api.titikapi.com/v1/models \
-H "Authorization: Bearer $TITIKAPI_API_KEY"Streaming
Tambahkan stream: true untuk menerima jawaban bertahap lewat Server-Sent Events. Stream diakhiri data: [DONE]. Isi stream_options.include_usage supaya chunk terakhir membawa jumlah token.
Request yang sudah mulai streaming tidak diulang otomatis. Kalau koneksi putus di tengah, pemakaian yang sudah terjadi tetap dihitung.
stream = client.chat.completions.create(
model="qwen3-8-27b",
messages=[{"role": "user", "content": "Ceritakan tentang Danau Toba."}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")Biaya dan saldo
Harga dalam Rupiah per 1 juta token, terpisah untuk input dan output — lihat Models. Harga dikunci saat request diterima, jadi perubahan harga tidak memengaruhi request yang sedang berjalan.
Saat request diterima, perkiraan biaya ditahan dari saldo tersedia. Setelah selesai, saldo dipotong sesuai token yang benar-benar dipakai dan sisanya dilepas. Rincian per request ada di Usage.
Error
Semua error memakai format yang sama. Periksa code, bukan message: kode stabil, pesan bisa berubah. Sertakan request_id saat menghubungi support.
| HTTP | Kode | Artinya |
|---|---|---|
| 401 | invalid_api_key | Key salah, dicabut, atau tidak dikirim. |
| 402 | insufficient_balance | Saldo tersedia tidak cukup. Top up lalu coba lagi. |
| 402 | wallet_expired | Masa aktif saldo berakhir. Top up untuk mengaktifkan lagi. |
| 400 | unsupported_feature | Fitur yang diminta tidak didukung model ini, misalnya tools. |
| 404 | model_not_found | Model id tidak dikenal atau tidak aktif. Cek GET /v1/models. |
| 429 | rate_limit_exceeded | Terlalu banyak request. Tunggu, lalu ulangi dengan jeda. |
| 503 | model_unavailable | Model sedang tidak tersedia. Tidak ada biaya. |
| 502 | upstream_error | Gagal setelah request dikirim. Biaya mengikuti pemakaian nyata. |
| 504 | upstream_timeout | Waktu habis setelah request dikirim. Biaya mengikuti pemakaian nyata. |
{
"error": {
"message": "Saldo tidak cukup untuk reservasi request ini.",
"type": "billing_error",
"code": "insufficient_balance",
"param": null,
"request_id": "req_01J9ZQ4M7X2B8K5T3N6W",
"retryable": false
}
}