BazaarLink menyediakan format permintaan dan respons terpadu yang kompatibel dengan OpenAI untuk berbagai model dan penyedia. Integrasikan sekali, lalu ganti model tanpa menulis ulang aplikasi.
Spesifikasi OpenAPI
API BazaarLink lengkap didokumentasikan dengan spesifikasi OpenAPI dalam format YAML dan JSON:
Gunakan spesifikasi ini dengan Swagger UI, Postman, atau generator kode yang kompatibel dengan OpenAPI untuk menjelajahi API atau membuat pustaka klien.
Permintaan
Format Permintaan Chat Completions
Isi permintaan chat completions dikirim ke endpoint berikut:
POST/api/v1/chat/completions
Untuk daftar lengkap bidang yang didukung, lihat Parameter。
Paksa model mengembalikan JSON valid yang cocok dengan skema. Ini penting untuk membangun aplikasi andal yang mem-parse output model secara programatik.
json_object — mode JSON dasar; model mengembalikan JSON yang valid.
json_schema — mode skema ketat; keluaran harus cocok dengan JSON Schema yang diberikan.
Plugin
BazaarLink meneruskan array plugins ke rute upstream yang dipilih. Ketersediaan bergantung pada model dan penyedia; varian model :online juga mengaktifkan plugin web.
Tambahkan pesan assistant yang belum selesai sebagai item terakhir untuk meminta kelanjutan pada rute model yang kompatibel.
Cara kerjanya
BazaarLink mempertahankan dan meneruskan pesan assistant terakhir. Perilaku kelanjutan diterapkan oleh model dan penyedia upstream yang dipilih, sehingga tidak dijamin pada setiap rute.
TypeScript
1
2
3
4
5
6
7
8
const response = await client.chat.completions.create({
model: "anthropic/claude-sonnet-4.6",
messages: [
{ role: "user", content: "What is the meaning of life?" },
// Intentional partial response; compatible routes continue from here.
{ role: "assistant", content: "My best answer is" }
]
});
Respons
BazaarLink menormalkan respons completion dari berbagai model dan penyedia ke satu format yang kompatibel dengan OpenAI.
Format Respons Completion
choices selalu berupa array. Respons streaming memakai delta, sedangkan non-streaming memakai message. Detail penggunaan dan biaya dikembalikan jika tersedia.
finish_reason memakai nilai ternormalisasi seperti stop, length, tool_calls, content_filter, dan error; native_finish_reason mempertahankan nilai asli penyedia.
Seed integer untuk sampling deterministik. Tidak dijamin untuk semua model
n
integer
Jumlah completion yang dihasilkan. Default: 1
user
string
Pengidentifikasi pengguna akhir untuk pemantauan dan deteksi penyalahgunaan. Tidak berpengaruh pada tagihan. Hanya model keluarga OpenAI — lihat catatan di bawah.
stop
string | string[]
Urutan berhenti — generasi berhenti saat ditemukan
logit_bias
object
Peta ID token ke nilai bias [-100, 100] yang ditambahkan sebelum sampling. Hanya model keluarga OpenAI — lihat catatan di bawah.
logprobs
boolean
Kembalikan probabilitas log dari setiap token output. Hanya model keluarga OpenAI — lihat catatan di bawah.
top_logprobs
integer
Jumlah token paling mungkin per posisi (memerlukan logprobs: true). Rentang: 0–20. Hanya model keluarga OpenAI — lihat catatan di bawah.
tools
Tool[]
Daftar tools (fungsi) yang dapat dipanggil model
tool_choice
string | object
Mengontrol penggunaan tool: "auto", "none", atau tool tertentu
parallel_tool_calls
boolean
Aktifkan pemanggilan fungsi paralel saat tools disediakan. Default: true. Hanya model keluarga OpenAI — lihat catatan di bawah.
response_format
object
Paksa output JSON terstruktur. Lihat bagian Output Terstruktur
structured_outputs
boolean
Meminta output yang sesuai skema JSON secara ketat pada penyedia yang mendukungnya. Diteruskan apa adanya
reasoning
object
Konfigurasi reasoning/thinking spesifik penyedia. Diteruskan apa adanya
reasoning_effort
string
Tingkat upaya reasoning gaya OpenAI seri-o: "low", "medium", atau "high". Diteruskan apa adanya
transforms
string[]
Transformasi pesan yang diterapkan, mis. ["middle-out"]. Abaikan untuk menerapkan otomatis pada model konteks <=8k
models
string[]
Daftar model fallback — BazaarLink mencoba masing-masing secara berurutan jika utama gagal
route
string
Field kompatibilitas routing lanjutan — sebagian besar pengguna tidak memerlukannya. Gunakan "models" untuk fallback.
provider
object
Preferensi routing lanjutan — sebagian besar pengguna tidak memerlukannya.
user, logprobs, top_logprobs, logit_bias, dan parallel_tool_calls hanya sampai ke model keluarga OpenAI
Kelima parameter ini dihapus dari permintaan upstream setiap kali model yang di-resolve bukan dikenali sebagai milik OpenAI sendiri — mengirimkannya ke anthropic/claude-*, google/gemini-*, atau target non-OpenAI lainnya mengembalikan 200 dengan parameter diabaikan secara diam-diam, bukan error. Jika Anda mengatur salah satu parameter ini dan efeknya tidak muncul, periksa apakah model target adalah milik OpenAI.
BazaarLink menormalkan tepat dua field — model dan penghapusan field provider — lalu meneruskan sisa respons upstream apa adanya. Field seperti native_finish_reason, system_fingerprint, dan reasoning hanya ada jika penyedia upstream tertentu mengisinya; jangan mengandalkan kehadirannya di semua model. usage.cost adalah pengecualian — selalu berupa jumlah yang diselesaikan/ditagih oleh BazaarLink sendiri, bukan nilai yang diteruskan dari upstream.
Hasilkan gambar dari prompt teks menggunakan model seperti DALL·E dan GPT-4o. Gunakan parameter `modalities` untuk meminta output gambar dari endpoint chat completions. Pengeditan gambar (memodifikasi gambar yang sudah ada) menggunakan POST /v1/images/edits —— kompatibel dengan OpenAI images.edit, multipart/form-data dengan gambar sumber Anda. Model yang mendukung pengeditan memiliki modality text+image->image (mis. qwen/qwen-image-edit); model murni-generasi adalah text->image —— periksa modality tiap model di GET /v1/models.
Response format
/api/v1/images/generations secara default mengembalikan JSON sinkron kompatibel OpenAI (sejak 2026-07-25) — client.images.generate() berfungsi tanpa wrapper. Kirim stream: true untuk beralih ke aliran event SSE, yang memberikan progres untuk model dengan waktu pembuatan lama.
A. /v1/chat/completions (native, direkomendasikan)
POST/api/v1/chat/completions
The canonical streaming path. Recommended for any new integration.
1
2
3
4
5
6
7
8
9
curl -N https://bazaarlink.ai/api/v1/chat/completions \
-H "Authorization: Bearer $BL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.4-image-2",
"messages": [{"role":"user","content":"a red cat on a sofa"}],
"modalities": ["image","text"],
"stream": true
}'
Image-to-image: sertakan bagian image_url dalam array content. Mendukung data URI atau URL gambar https (http:// ditolak), hingga 8 gambar, ~10MB per data URI. Pesan yang membawa gambar juga harus menyertakan bagian teks (instruksi penyuntingan). Beberapa model juga mendukung image_config (mis. {"strength": 0.7}, 0–1 — nilai lebih rendah lebih mendekati gambar sumber), diteruskan ke upstream apa adanya.
1
2
3
4
5
6
7
8
9
10
11
12
curl -N https://bazaarlink.ai/api/v1/chat/completions \
-H "Authorization: Bearer $BL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.4-image-2",
"messages": [{"role":"user","content":[
{"type":"image_url","image_url":{"url":"data:image/png;base64,..."}},
{"type":"text","text":"change the background to a night city"}
]}],
"modalities": ["image"],
"stream": true
}'
Penyuntingan Gambar (kompatibel OpenAI)
POST/api/v1/images/edits
client.images.edit() dari OpenAI SDK berfungsi langsung (unggahan multipart, respons JSON sinkron yang mengembalikan data: [{ url }]). Batas sama dengan image-to-image: hingga 8 gambar, 10MB per gambar; mask dan response_format=b64_json belum didukung.
1
2
3
4
5
curl https://bazaarlink.ai/api/v1/images/edits \
-H "Authorization: Bearer $BL_API_KEY" \
-F model="openai/gpt-5.4-image-2" \
-F image=@cat.png \
-F prompt="change the background to a night city"
B. /v1/images/generations (kompatibel DALL·E)
POST/api/v1/images/generations
OpenAI DALL-E request shape. Sync JSON ({ created, data: [{ url }] }) is the default and works with client.images.generate() out of the box; pass stream: true to get the SSE event stream documented below instead.
1
2
3
4
5
6
7
8
curl https://bazaarlink.ai/api/v1/images/generations \
-H "Authorization: Bearer $BL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-image-2",
"prompt": "a red cat on a sofa",
"size": "1024x1024"
}'
modelwajib
string
ID model, misalnya google/gemini-2.5-flash-image
promptwajib
string
Prompt teks
size
string
Ukuran keluaran (dipetakan otomatis)
n
integer
Jumlah gambar (default 1)
1
2
3
4
5
6
# Streaming variant — progressive delivery for long generations
curl -N https://bazaarlink.ai/api/v1/images/generations \
-H "Authorization: Bearer $BL_API_KEY" \
-H "Accept: text/event-stream" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-5.4-image-2","prompt":"a red cat on a sofa","stream":true}'
Alur asinkron tiga langkah (submit → poll → content). Pembuatan video memakan waktu 30 detik–5 menit, sehingga tidak cocok dengan semantik permintaan/respons sinkron chat-completions — karena itu BazaarLink memisahkan video ke jalur /api/v1/videos dengan pola job-id: submit mengembalikan ID vjob_* → poll status → ambil bytes setelah selesai. Memanggil model video lewat /chat/completions atau /images/generations akan mengembalikan 400 (code: wrong_endpoint_for_video). Biaya diselesaikan berdasarkan usage.cost aktual saat completed.
Jenis tugas video
Satu endpoint mencakup beberapa tugas. Tugas mana yang berjalan ditentukan oleh field yang Anda kirim —— satu model bisa melakukan image-to-video, keyframe, dan lanjutan. Tidak semua model mendukung setiap tugas; permintaan yang tidak didukung mengembalikan 400.
Teks-ke-video
prompt
Menghasilkan hanya dari prompt teks — tanpa media masukan.
Gambar-ke-video
frame_images: [ first frame ]
Gambar Anda ADALAH gambarnya: menjadi frame pertama dan dianimasikan, tetap setia pada aslinya. Mis. foto seekor kucing → kucing yang sama menoleh di adegan yang sama.
Keyframe (pertama + terakhir)
frame_images: [ first, last ]
Berikan gambar awal dan gambar akhir; model menginterpolasi gerakan di antaranya.
Lanjutan
input_video
Memperpanjang klip yang sudah ada. Durasi yang diminta harus lebih besar dari panjang video sumber.
Referensi-ke-video
input_references: [ images ]
Gambar Anda adalah REFERENSI, bukan frame: model mempertahankan subjek/gaya dan menghasilkan adegan yang benar-benar baru. Mis. foto kucing + "menari di hutan" → video baru di mana tampilan kucing dipertahankan tetapi adegan dan gerakannya baru (1–9 referensi). Bedanya dengan gambar-ke-video: i2v tetap setia pada gambar persisnya; r2v menampilkan ulang subjek ke dalam rekaman baru.
Pengeditan video
input_video + prompt
Mengedit video yang sudah ada — mengubah adegan, gaya, atau gerakan. Ditagih berdasarkan detik video masukan + detik keluaran.
Gambar referensi untuk reference-to-video —— panduan subjek/gaya, bukan frame persis.
input_video
string|object
URL video sumber untuk lanjutan dan pengeditan video. Harus dapat diambil secara publik oleh upstream.
aspect_ratio
string
Rasio aspek, mis. 16:9 atau 9:16. Diabaikan bila gambar input menentukan rasionya.
watermark
boolean
Menambahkan watermark. Default false.
callback_url
string
URL webhook yang dipanggil saat job mencapai status akhir — hanya HTTPS, diperiksa SSRF. Tidak ada tanda tangan di v1; perlakukan sebagai petunjuk dan konfirmasi via GET /videos/{id}.
Resolusi yang diizinkan berbeda per model —— nilai yang tidak didukung mengembalikan 400 beserta daftar yang didukung.
Gambar/video input harus dapat dijangkau dari URL publik. Host yang dilindungi hotlink (mis. beberapa wiki) akan gagal.
Media input melewati moderasi konten upstream dan sesekali dapat ditolak.
Untuk lanjutan, durasi yang diminta harus melebihi panjang video sumber.
Rasio aspek output mengikuti gambar input —— gambar persegi menghasilkan video persegi.
Pengeditan video ditagih berdasarkan detik video input ditambah detik output yang dihasilkan.
input_video (pengeditan / lanjutan) harus berupa URL PUBLIK. Video yang Anda hasilkan di sini disajikan di balik API key Anda, sehingga upstream tidak bisa mengambilnya —— host video sumber Anda di URL yang dapat diakses publik.
Payload webhook tidak ditandatangani — konfirmasi status/jumlah via GET /videos/{id} sebelum bertindak, dan perhatikan unsigned_urls di sana bersifat absolut (berbeda dari path relatif pada respons poll).
Model video yang didukung
Model ID
Modality
Tasks
bytedance/seedance-2.0
text+image+audio+video->video
t2v, i2v
bytedance/seedance-2.0-fast
text+image+audio+video->video
t2v, i2v
google/veo-3.1
text+image->video
t2v, i2v
openai/sora-2-pro
text+image->video
t2v, i2v
bytedance/seedance-1-5-pro
text+image->video
t2v, i2v
alibaba/happyhorse-1.0
text->video
t2v
alibaba/wan2.6-r2v-flash
text+image+video->video
r2v
alibaba/wan2.5-i2v-preview
text+image->video
i2v
alibaba/happyhorse-1.1
text->video
t2v
alibaba/wan2.7-t2v
text->video
t2v
alibaba/wan2.7-i2v
text+image+video->video
i2v, kf2v, continuation
alibaba/wan2.6-t2v
text->video
t2v
alibaba/wan2.5-t2v-preview
text->video
t2v
alibaba/wan2.2-t2v-plus
text->video
t2v
alibaba/wan2.7-r2v
text+image+video->video
r2v
alibaba/wan2.1-t2v-plus
text->video
t2v
alibaba/wan2.1-t2v-turbo
text->video
t2v
alibaba/wan2.6-i2v-flash
text+image->video
i2v
alibaba/wan2.2-i2v-flash
text+image->video
i2v
alibaba/wan2.7-videoedit
text+image+video->video
videoedit
alibaba/wan2.6-i2v
text+image->video
i2v
alibaba/wan2.2-i2v-plus
text+image->video
i2v
alibaba/wan2.6-r2v
text+image+video->video
r2v
Input Video
Kirim file video ke model yang mendukung input video untuk dianalisis, diberi keterangan, atau dijawab pertanyaannya seputar adegan dan peristiwa. Bisa pakai URL langsung atau base64 data URI — URL lebih efisien untuk video yang dapat diakses publik; base64 untuk file lokal atau video privat.
Format yang Didukung
MP4 (H.264)MPEGMOVWebM
1
2
3
4
5
6
7
8
9
10
11
12
13
response = client.chat.completions.create(
model="google/gemini-2.5-flash",
messages=[{
"role": "user",
"content": [
{
"type": "video_url",
"video_url": {"url": "https://example.com/video.mp4"},
},
{"type": "text", "text": "What is happening in this video?"},
],
}],
)
Kirim dokumen PDF langsung dalam pesan ke model yang mendukung input PDF secara native (mis. Claude, Gemini). BazaarLink meneruskan file langsung ke model — ditagih sebagai input token biasa, tanpa biaya tambahan atau langkah pemrosesan ekstra.
Format yang Didukung
Dokumen PDF (teks, gambar, tabel, pindai)
URL data base64 (`data:application/pdf;base64,...`)
Endpoint yang kompatibel dengan OpenAI Responses API untuk percakapan multi-turn stateless, tool calling, dan input multimodal. Ideal untuk agen dan framework yang menggunakan OpenAI Python SDK >= 1.x dengan client.responses.create().
POST/api/v1/responses
Note
Menerima autentikasi dan routing model yang sama dengan Chat Completions.
Body Permintaan
modelwajib
string
ID Model, mis. "openai/gpt-4o" atau "anthropic/claude-3.5-sonnet"
inputwajib
string | Item[]
Input pengguna — string biasa (pesan tunggal) atau array item input untuk percakapan multi-turn / multimodal.
instructions
string
Instruksi level sistem, setara dengan pesan sistem. Harus dikirim ulang pada setiap permintaan.
stream
boolean
Jika true, mengembalikan event stream SSE Responses API. Tipe event: response.created, response.output_text.delta, response.completed.
max_output_tokens
integer
Jumlah maksimum token output yang dihasilkan (termasuk token penalaran untuk model o-series).
temperature
number
Temperatur sampling 0–2. Lebih tinggi = lebih acak. Default: 1
top_p
number
Massa probabilitas sampling nukleus. Default: 1
tools
Tool[]
Definisi tool (fungsi) — format JSON Schema yang sama dengan Chat Completions (menerima bentuk datar Responses maupun bentuk bersarang). Tool bawaan milik OpenAI sendiri (web_search_preview, file_search, computer_use_preview) tidak didukung; pencarian web tersedia melalui plugins: [{id:"web"}] — hanya didukung pada beberapa rute model.
tool_choice
string | object
Mengontrol penggunaan tool: "auto", "none", atau tool tertentu
parallel_tool_calls
boolean
Aktifkan pemanggilan fungsi paralel saat tools disediakan. Default: true. Hanya model keluarga OpenAI — lihat catatan di bawah.
response_format
object
Paksa output JSON terstruktur. Lihat bagian Output Terstruktur
models
string[]
Daftar model fallback — BazaarLink mencoba masing-masing secara berurutan jika utama gagal
transforms
string[]
Transformasi pesan yang diterapkan, mis. ["middle-out"]. Abaikan untuk menerapkan otomatis pada model konteks <=8k
previous_response_id
string
Endpoint ini stateless — mengirim nilai yang bukan null langsung mengembalikan 400 (invalid_prompt), tidak pernah diterima lalu diabaikan. Gunakan mode stateless: kirim riwayat percakapan lengkap dalam array input.
provider
object
Preferensi routing lanjutan — sebagian besar pengguna tidak memerlukannya.
curl https://bazaarlink.ai/api/v1/responses \
-H "Authorization: Bearer $BAZAARLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"instructions": "You are a helpful assistant.",
"input": "What is the capital of Taiwan?"
}'
Ganti messages dengan input (string atau array), gunakan instructions sebagai pengganti pesan system-role, dan baca output[0].content[0].text alih-alih choices[0].message.content.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Chat Completions (before)
response = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{"role": "system", "content": "You are helpful."},
{"role": "user", "content": "Hello"},
]
)
text = response.choices[0].message.content
# Responses API (after)
response = client.responses.create(
model="openai/gpt-4o-mini",
instructions="You are helpful.",
input="Hello"
)
text = response.output[0].content[0].text
Keterbatasan
previous_response_id atau store: true ditolak dengan 400 (kode error invalid_prompt) — bukan diterima lalu diabaikan. Selalu gunakan mode stateless: kirim riwayat percakapan lengkap dalam array input.
Tool bawaan milik OpenAI sendiri (web_search_preview, file_search, computer_use_preview) tidak didukung. Pencarian web tersedia melalui plugins: [{id:"web"}] — hanya didukung pada beberapa rute model.
background: true diterima tetapi diabaikan — setiap permintaan selalu berjalan secara sinkron hingga selesai.
Messages (Anthropic)
Anthropic API untuk Claude SDK. Gunakan persis seperti yang Anda lakukan dengan API Anthropic — cukup ubah basis URL dan header autentikasi.
POST/api/v1/messages
Note
AMenerima token pembawa atau header x-api-key (kompatibilitas Anthropic SDK). Ukuran badan maksimal: 10 MB.
Body Permintaan
modelwajib
string
ID Model, mis. "openai/gpt-4o" atau "anthropic/claude-3.5-sonnet"
max_tokenswajib
integer
Jumlah maksimum token yang akan dihasilkan (bilangan bulat positif).
messageswajib
Message[]
Array pesan percakapan (tidak kosong).
system
string
Permintaan sistem opsional.
stream
boolean
Jika true, mengembalikan stream Server-Sent Events. Default: false
temperature
number
Temperatur sampling 0–2. Lebih tinggi = lebih acak. Default: 1
top_p
number
Massa probabilitas sampling nukleus. Default: 1
top_k
integer
Batasi pilihan token ke top-K. 0 = dinonaktifkan (pertimbangkan semua). Default: 0
stop_sequences
string[]
String urutan penghentian khusus.
tools
Tool[]
Daftar tools (fungsi) yang dapat dipanggil model
tool_choice
string | object
Mengontrol penggunaan tool: "auto", "none", atau tool tertentu
{"id":"msg_...","type":"message","role":"assistant","model":"anthropic/claude-opus-4","content":[{"type":"text","text":"Hello! How can I help you today?"}],"stop_reason":"end_turn","usage":{"input_tokens":10,"output_tokens":12,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"bz_cost":0.00042}}
Kesalahan: 400 (validasi), 402 (kredit tidak mencukupi), 429 (batas kecepatan), 502 (kesalahan hulu/kunci hilang), 503 (server dimulai ulang).
Model
Daftar semua model yang tersedia dengan informasi harga dan kemampuan. Tidak diperlukan autentikasi untuk endpoint ini.
// /v1/models — Response SchematypeModelsResponse = {
data: Model[];
};
typeModel = {
id: string; // Model ID (e.g. "openai/gpt-4.1")name: string; // Human-readable namecontext_length: number | null; // Max context window in tokensmodality: string | null; // e.g. "text->text", "text+image->text"architecture?: {
input_modalities?: string[];
output_modalities?: Array<
"text" | "image" | "embeddings" | "audio" |
"video" | "rerank" | "speech" | "transcription"
>;
};
pricing: {
prompt: string; // Input price per 1M tokens (USD)completion: string; // Output price per 1M tokens (USD)
};
description?: string | null; // Model descriptiontop_provider?: {
max_completion_tokens?: number;
};
supported_parameters?: string[]; // e.g. ["tools", "response_format", "reasoning"]pricing_tiers?: { // Present only for models with input-length tiersabove_prompt_tokens: number; // Ascending; strict "greater than" thresholdprompt: string; // USD per token, override tiercompletion: string; // USD per token, override tier
}[];
};
Harga Bertingkat Berdasarkan Panjang Input
Beberapa model beralih ke tabel harga yang berbeda setelah prompt melebihi ambang token — seluruh tabel berubah, bukan hanya token di atas ambang. Ambang bersifat ketat: prompt dengan tepat N token masih ditagih pada tingkat di bawah N; tingkat yang lebih tinggi berlaku hanya ketika token input lebih besar dari N.
pricing_tiers adalah field sejajar dengan pricing, hanya ada ketika model memiliki tingkat override di atas harga dasar. Entri diurutkan berdasarkan above_prompt_tokens menaik; prompt/completion adalah USD per token (satuan sama dengan pricing.prompt/pricing.completion). pricing.prompt dan pricing.completion selalu tetap menjadi tingkat dasar (terendah).
Sebagian besar model tidak memiliki tingkat — untuk model tersebut, key pricing_tiers tidak ada sama sekali dalam respons.
Saat streaming, data penggunaan dikembalikan dalam potongan terakhir sebelum pesan [DONE], bersama array choices dengan delta kosong dan finish_reason: "stop".
Keep-alive & chunk terakhir
Stream dapat berisi baris komentar SSE (diawali tanda titik dua) atau event heartbeat sebagai keep-alive — lewati baris non-data: alih-alih mem-JSON.parse stream mentah. Chunk data terakhir membawa usage (jumlah token dan biaya) sebelum data: [DONE]. Respons yang berhasil menyertakan header X-Request-Id — sertakan saat melaporkan masalah.
1
2
3
4
5
6
7
: keepalive <- SSE comment line — ignore, do NOT JSON.parse
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"Hi"},"index":0}]}
data: {"id":"chatcmpl-abc","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":{...}}
data: [DONE]
Pembatalan Stream
Permintaan streaming dapat dibatalkan dengan menutup koneksi klien — misalnya memanggil AbortController.abort() atau menutup objek stream. BazaarLink berhenti meneruskan chunk berikutnya dan membatalkan permintaan ke provider segera setelah pembatalan diterima.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
importOpenAIfrom"openai";
const client = newOpenAI({
baseURL: "https://bazaarlink.ai/api/v1",
apiKey: "sk-bl-YOUR_API_KEY",
});
const controller = newAbortController();
const stream = await client.chat.completions.create(
{
model: "anthropic/claude-sonnet-4.6",
messages: [{ role: "user", content: "Write a long story." }],
stream: true,
},
{ signal: controller.signal }
);
forawait (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) process.stdout.write(content);
}
// e.g. on a "Stop" button click:
controller.abort();
Tidak ada biaya untuk stream yang terputus
Jika stream berakhir sebelum chunk usage terakhir tiba — termasuk pembatalan dari sisi klien — tidak ada data jumlah token yang valid untuk permintaan tersebut, sehingga BazaarLink mengembalikan penuh reservasi. Anda tidak dikenakan biaya untuk konten yang sudah terkirim ke klien sebelum pembatalan.
Tidak dijamin langsung berhenti di sisi provider
Menutup koneksi langsung menghentikan BazaarLink dari meneruskan dan menagih token berikutnya, tetapi apakah provider upstream benar-benar menghentikan generasi di server mereka sendiri saat koneksi terputus tergantung pada provider tersebut — beberapa mungkin masih memproses sebentar setelah terputus.
Error di Tengah Stream
Tidak ada field choices pada frame error
Jika terjadi kegagalan setelah streaming sudah dimulai (mis. koneksi upstream terputus), Anda akan menerima SSE data frame berbentuk {error:{message,type,code}} alih-alih {choices:[...]} yang biasa — tanpa perubahan status HTTP, karena header sudah terkirim. Periksa field error sebelum membaca choices[0].delta, dan hanya token yang sudah di-stream yang ditagih (berlaku billing parsial).
1
2
3
4
5
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"The capital of "},"index":0}]}
data: {"error":{"message":"Upstream connection lost.","type":"upstream_error","code":502}}
data: [DONE]
Embeddings
Embeddings adalah representasi numerik teks yang menangkap makna semantik — mengubah teks menjadi vektor (deretan angka) yang dapat digunakan untuk berbagai tugas machine learning. BazaarLink menyediakan endpoint terpadu yang kompatibel dengan OpenAI Embeddings API, sehingga Anda dapat memanggil model embedding dari berbagai penyedia melalui satu antarmuka.
Apa itu Embeddings?
Embeddings mengubah teks menjadi vektor berdimensi tinggi, di mana teks yang secara semantik mirip akan berdekatan dalam ruang vektor — misalnya, "kucing" dan "anak kucing" akan memiliki embedding yang mirip, sedangkan "kucing" dan "pesawat" akan sangat berjauhan. Representasi vektor ini memungkinkan mesin memahami hubungan antar teks, menjadikannya fondasi banyak aplikasi AI.
Kasus Penggunaan Umum
Kasus Penggunaan
Deskripsi
RAG (Generasi Augmented Pengambilan)Membangun sistem yang mengambil konteks relevan dari basis pengetahuan sebelum menghasilkan jawaban — embeddings menemukan dokumen paling relevan untuk disertakan dalam konteks LLM.
Pencarian SemantikMengubah dokumen dan kueri menjadi embeddings, lalu menemukan dokumen paling relevan berdasarkan kemiripan vektor — memahami makna, bukan sekadar mencocokkan kata kunci, sehingga hasilnya lebih baik daripada pencarian kata kunci.
Sistem RekomendasiMenghasilkan embeddings untuk item (produk, artikel, video) dan preferensi pengguna untuk merekomendasikan item serupa — perbandingan vektor menemukan item yang terkait secara semantik meskipun tidak ada kata kunci yang sama.
Clustering & KlasifikasiMengelompokkan dokumen serupa atau mengklasifikasikan teks dengan menganalisis pola embedding — dokumen dengan embedding serupa biasanya termasuk topik atau kategori yang sama.
Deteksi DuplikatMenemukan konten duplikat atau hampir duplikat dengan membandingkan kemiripan embedding — tetap berfungsi meskipun konten telah diparafrasekan.
Deteksi AnomaliMengenali konten yang tidak biasa atau outlier dengan mengidentifikasi embedding yang menyimpang jauh dari pola umum dataset.
POST/api/v1/embeddings
Note
Tidak semua penyedia upstream mendukung embeddings. Jika penyedia yang dikonfigurasi tidak mendukung model yang diminta, BazaarLink akan otomatis failover ke penyedia berikutnya yang tersedia.
Parameter
modelwajib
string
Model embedding yang digunakan, mis. "openai/text-embedding-3-small".
inputwajib
string | string[] | ContentItem[]
Teks yang akan di-embed — satu string, array string untuk satu panggilan batch, atau (untuk model yang mendukung) array item {content:[...]} yang menggabungkan bagian text dan image_url.
dimensions
integer
Ukuran vektor output yang diminta. Hanya dihormati oleh model yang mendukung dimensi variabel (mis. keluarga OpenAI text-embedding-3); diteruskan apa adanya ke penyedia upstream dan diabaikan oleh model yang tidak mendukungnya.
encoding_format
string
Format encoding embedding yang diminta, mis. "float" atau "base64". Diteruskan apa adanya ke penyedia upstream — dukungan tergantung pada model.
provider
object
Preferensi routing penyedia — order, allow_fallbacks, data_collection, dan field lain yang dijelaskan di Provider Selection.
Permintaan Dasar
1
2
3
4
5
6
7
8
9
10
11
12
13
from openai import OpenAI
client = OpenAI(
base_url="https://bazaarlink.ai/api/v1",
api_key="sk-bl-YOUR_API_KEY",
)
response = client.embeddings.create(
model="openai/text-embedding-3-small",
input="The quick brown fox jumps over the lazy dog",
)
print(response.data[0].embedding) # 1536-dimensional vector
Pemrosesan Batch
Kirim array string untuk meng-embed beberapa teks dalam satu permintaan — lebih murah dan cepat daripada satu panggilan per teks.
1
2
3
4
5
6
7
8
9
10
11
response = client.embeddings.create(
model="openai/text-embedding-3-small",
input=[
"Machine learning is a subset of artificial intelligence",
"Deep learning uses neural networks with multiple layers",
"Natural language processing enables computers to understand text",
],
)
for i, item inenumerate(response.data):
print(f"Embedding {i}: {len(item.embedding)} dimensions")
Input Multimodal (Gambar + Teks)
Model dengan dukungan input gambar (output_modalities mencakup "embeddings" dan inputModalities mencakup "image") menerima item input berbentuk {content:[{type:"text",...}, {type:"image_url",...}]}, memungkinkan Anda meng-embed gambar sendiri atau bersama teks.
Tergantung model
Hanya sebagian model embedding yang menerima input gambar — periksa modalitas yang didukung model di halaman Models sebelum mengirim konten image_url. Model teks-saja akan menolak bentuk ini.
Kendalikan upstream mana yang melayani permintaan embedding, sama seperti chat completions — lihat Provider Selection untuk referensi field lengkap.
1
2
3
4
5
6
7
8
9
{"model":"openai/text-embedding-3-small","input":"Your text here","provider":{"order":["openai"],"allow_fallbacks":true,"data_collection":"deny"}}
Menemukan Model Embedding
Tidak ada endpoint khusus untuk mendaftar model embedding — panggil GET /api/v1/models lalu filter di sisi klien untuk entri yang output_modalities-nya mencakup "embeddings", atau jelajahi halaman Models.
Keterbatasan
Tidak ada streaming — embedding selalu dikembalikan sebagai respons lengkap, berbeda dengan chat completions.
Setiap model punya panjang input maksimum; teks yang melebihi batas akan dipotong atau ditolak di upstream.
Embedding untuk input yang identik bersifat deterministik — tidak ada temperature atau keacakan.
Praktik Terbaik
Pilih model sesuai trade-off kecepatan/kualitas/biaya — model lebih kecil (mis. qwen/qwen3-embedding-4b) lebih murah dan cepat; model lebih besar (mis. openai/text-embedding-3-large) umumnya meng-embed dengan fidelitas lebih tinggi.
Gabungkan beberapa teks dalam satu permintaan alih-alih satu panggilan per teks — lebih sedikit round trip, overhead lebih rendah.
Simpan hasil (cache) — embedding untuk input yang sama tidak pernah berubah, jadi simpan alih-alih membuatnya ulang.
Bandingkan dengan cosine similarity, bukan Euclidean distance — bersifat scale-invariant dan lebih baik untuk vektor berdimensi tinggi.
Perhatikan context length setiap model — dokumen panjang mungkin perlu dipecah (chunking) sebelum di-embed.
Parameter
Parameter sampling membentuk proses generasi token. BazaarLink meneruskan parameter yang didukung ke penyedia upstream; parameter yang tidak didukung diabaikan secara diam-diam.
Parameter Sampling
Murni passthrough — tidak ada default lokal
Parameter ini diteruskan ke penyedia upstream persis seperti yang dikirim — BazaarLink tidak pernah menyisipkan atau memaksakan nilai default. "Default" di bawah menjelaskan perilaku penyedia sendiri saat field diabaikan, bukan jaminan dari BazaarLink.
temperature
number
Temperatur sampling 0–2. Lebih tinggi = lebih acak. Default: 1
top_p
number
Massa probabilitas sampling nukleus. Default: 1
top_k
integer
Batasi pilihan token ke top-K. 0 = dinonaktifkan (pertimbangkan semua). Default: 0
is_free_tier = benar bila saldo kredit < $10. Windows dalam format UTC: harian = hari ini, mingguan = Senin–Minggu, bulanan = 1–EOM. Ketika kunci memiliki batas pembelanjaan per kunci yang ditetapkan (melalui parameter batas pada kunci creation/update), limit / limit_remaining / limit_reset mencerminkan batas tersebut dan penggunaan periode yang cocok; jika tidak, limit adalah nol dan limit_remaining akan dikembalikan ke saldo kredit akun Anda. expired_at adalah waktu kedaluwarsa kunci (null jika tidak ada). is_management_key dan is_provisioning_key adalah alias untuk konsep yang sama — keduanya berlaku untuk kunci manajemen.
BYOK
BazaarLink tidak menawarkan program bawa kunci Anda sendiri (BYOK), jadi titik akhir ini tidak mengembalikan bidang byok_usage apa pun.
Pendaftaran layanan mandiri untuk agen AI (bot, sistem otonom). Mengembalikan kunci API dengan kredit percobaan dan token klaim untuk peningkatan akun.
POST/api/v1/agents/register
Rate Limit
Tidak diperlukan otentikasi, tetapi IP dibatasi untuk 1 pendaftaran per 24 jam.
curl -X POST https://bazaarlink.ai/api/v1/agents/register \
-H "content-type: application/json" \
-d '{
"name": "My Agent",
"description": "Autonomous research bot"
}'
Respons
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{"api_key":"sk-bl-xxxxx...","credits":0.10,"credits_usd":"$0.1000","claim_token":"abc...xyz","claim_expires":"2026-04-27T10:00:00.000Z","upgrade_url":"https://bazaarlink.ai/claim?token=...","referral_code":"aBcDeFgH","free_model":"auto:free","message":"Welcome to BazaarLink!...","referral_message":"Share referral link:...","base_url":"https://bazaarlink.ai/api/v1","docs":"https://bazaarlink.ai/llms.txt"}
Errors: 400 (isi tidak valid / nama hilang), 429 (batas kecepatan — 1/IP/24h), 500 (internal).
Kode Error
Format respons kesalahan
Endpoint inferensi model mengembalikan amplop kesalahan yang kompatibel dengan OpenAI. Kolom type dapat berbeda atau tidak disertakan; gunakan status HTTP dan error.code untuk logika program, bukan mengurai pesan.
1
2
3
4
5
6
7
{"error":{"message":"Insufficient credits. Please top up to continue.","type":"invalid_request_error","code":"insufficient_credits"}}
HTTP status dan kode kesalahan
Before streaming, the HTTP status identifies the broad failure class. error.code is either that number or a stable string for a specific remedy. Prefer the string code when present, otherwise use the HTTP status.
Kode
Nama
Deskripsi
400Permintaan BurukPermintaan salah format, array messages kosong, atau field wajib hilang
401Tidak SahKunci API hilang, tidak valid, atau dinonaktifkan
402Pembayaran DiperlukanKredit akun tidak cukup, batas pengeluaran per kunci tercapai, atau batas anggaran bulanan/mingguan terlampaui
403DilarangAkun ditangguhkan atau tidak memiliki izin
404Tidak DitemukanRequested model, generation, key, or other resource does not exist
409KonflikResource is not in the required state, such as an incomplete video job
410HilangRequested model has been retired and must be replaced
413Muatan Terlalu BesarBody permintaan melebihi 10 MB; kurangi ukuran konten atau pecah permintaan
416Rentang Tidak MemuaskanRequested byte range is invalid for generated video content
429Terlalu Banyak PermintaanBatas rate terlampaui; periksa header Retry-After sebelum mencoba ulang
500Kesalahan ServerError internal BazaarLink
502Gerbang BurukSemua penyedia upstream gagal; failover telah dicoba
503Layanan Tidak TersediaTidak ada penyedia upstream yang dikonfigurasi untuk model ini; hubungi admin
504Gateway Batas WaktuUpstream connection or stream stalled and timed out
Kode penagihan yang dapat dibaca mesin
A 402 can represent different controls. Use these stable codes to choose the correct action.
Kode
Deskripsi
budget_cap_reachedA weekly or monthly budget cap was reached; raise or reset the cap.
credit_limit_exceededA monthly-billing organization's credit line was exhausted; contact billing.
insufficient_creditsThe prepaid balance is insufficient; add credits.
spend_limit_exceededThe API key reached its daily, weekly, or monthly spend limit.
Stable error.code catalog
These string codes are emitted by public inference and media paths. Branch on the string code when present; the HTTP status remains the broad failure class.
Model dan titik akhir
Kesalahan pencarian model, siklus hidup, harga, modalitas, dan kompatibilitas titik akhir.
Kode
HTTP
unknown_model400
invalid_model_id400
model_not_found404
model_retired410
model_endpoint_mismatch400
embedding_on_chat_endpoint400
model_not_priced400
invalid_modality_for_model400
Permintaan dan keamanan
Parameter, konteks, alat, skema, dan penolakan keamanan konten tidak valid.
Kode
HTTP
missing_required_field400
unsupported_param400
max_tokens_invalid400
context_too_long400
tool_use_unsupported400
malformed_tool_messages400
invalid_response_format_schema400
invalid_tools_definition400
content_moderation403
content_filter403
unknown_4xx400
Pembuatan dan pengeditan gambar
Masukan gambar, pengeditan multibagian, keluaran, dan kesalahan saluran gambar.
Kode
HTTP
invalid_image_url400
input_images_not_supported400
invalid_content_type400
mask_not_supported400
unsupported_response_format400
missing_prompt400
missing_image400
too_many_images400
invalid_image_type400
image_too_large400
invalid_n400
pipeline_error502
no_images502
Perutean hulu
Konektivitas penyedia yang disanitasi, autentikasi, pembatasan, dan kesalahan ketersediaan.
Kode
HTTP
upstream_unreachable502
upstream_auth_failed502
upstream_rate_limited429
upstream_unavailable502/503
Batas tarif, anggaran, dan rem darurat
These controls can reject an otherwise valid request and require different recovery actions.
Kontrol
HTTP
Cara mengidentifikasinya
Batas kecepatan permintaan429Kode numerik 429; gunakan header Retry-After dan X-RateLimit-*.
Global menghabiskan rem darurat503Kode numerik 503, pesan batas pembelanjaan global, dan Coba Lagi Setelah 30 atau 300 detik.
Scoped spend brake429Numeric code 429 and a spend circuit-breaker message naming the scope.
Penagihan dan kontrol anggaran402Gunakan kode string penagihan stabil yang tercantum di atas.
Compatibility note: rate-limit and emergency-brake paths currently emit numeric error.code values. Use HTTP status, Retry-After, and the documented response message.
Status sumber daya video dan media
Video validation commonly returns numeric code 400. Missing jobs return 404, retired models 410, unfinished video content 409, and invalid video byte ranges 416.
Kebijakan coba lagi
Retry only failures that may recover without changing the request. Honor Retry-After or use exponential backoff with jitter. Do not stack SDK and manual retries.
Coba lagi dengan backoff
429, 502, 503, and 504. Check the original generation job before creating another after an ambiguous network failure.
Perbaiki sebelum mencoba lagi
400, 401, 402, 403, 404, 409, 410, 413, and 416. Fix the request, credentials, balance, permissions, resource state, or Range header first.
Menangani Error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import random
import time
from openai import OpenAI, APIStatusError
client = OpenAI(
base_url="https://bazaarlink.ai/api/v1",
api_key="sk-bl-YOUR_API_KEY",
max_retries=0, # Avoid double retries; this example handles them.
)
RETRYABLE = {429, 502, 503, 504}
for attempt inrange(5):
try:
response = client.chat.completions.create(
model="openai/gpt-4.1",
messages=[{"role": "user", "content": "Hello!"}],
)
breakexcept APIStatusError as error:
if error.status_code notin RETRYABLE or attempt == 4:
raise
retry_after = error.response.headers.get("Retry-After")
delay = (
float(retry_after)
if retry_after
elsemin(8, 0.5 * (2 ** attempt)) + random.uniform(0, 0.25)
)
time.sleep(delay)
Format Error Streaming
Error yang terjadi sebelum token apa pun di-stream mengembalikan respons error HTTP standar dengan body JSON.
After a stream starts, the HTTP response is already 200. Parse each SSE data frame and treat a top-level error or choices[0].finish_reason === "error" as a failed, incomplete response.
Jika stream gagal di tengah jalan, BazaarLink mengirim event SSE terakhir dengan objek error tingkat atas, diikuti data: [DONE]. Chunk yang diteruskan apa adanya dari beberapa upstream mungkin justru membawa error pada choice (choices[0].finish_reason === "error") — tangani keduanya.
1
2
3
4
5
6
7
8
9
10
// If the stream fails mid-flight, BazaarLink emits a final SSE event
// with a top-level "error" object, followed by data: [DONE]
data: {"error":{"message":"Upstream stream interrupted. The response is incomplete.","type":"upstream_error","code":502}}
data: [DONE]
// Chunks relayed verbatim from some upstreams may instead carry the error
// inline on the choice: choices[0].finish_reason === "error" with an
// "error" object ({ code, message }) on the choice — handle both shapes.
// Branch on error.code; error.type can vary by failure path.
BazaarLink menyediakan satu jalur API stabil, /api/v1 — tidak ada versi berbasis tanggal atau header versi yang perlu dikelola. API berkembang secara berkelanjutan, bukan melalui rilis bernomor.
Perubahan Non-Breaking
Perubahan ini dirilis tanpa pemberitahuan sebelumnya:
Endpoint baru
Model baru ditambahkan ke katalog
Parameter permintaan opsional baru
Field respons baru
Skema baru dengan properti opsional
Kode status/error respons tambahan
Tulis klien secara defensif
Abaikan field respons yang tidak Anda kenali, dan jangan gagal pada nilai yang tidak dikenal di field bertipe enum — nilai baru ditambahkan seiring bertambahnya katalog dan fitur.
Perubahan Breaking
Perubahan ini jarang terjadi, dan mencakup:
Menghapus atau mengganti nama endpoint, parameter, atau field respons
Mengubah tipe suatu field
Menjadikan parameter opsional sebagai wajib
Jika terjadi, perubahan breaking berlaku pada endpoint tertentu, bukan seluruh permukaan /api/v1 — tidak ada satu lompatan versi yang bisa merusak semua integrasi sekaligus. Kami belum mempublikasikan changelog resmi dengan tag Breaking (lihat "Tetap Update" di bawah) — untuk hal yang kritis bagi integrasi Anda, hubungi Support sebelum mengandalkan perilaku yang tidak terdokumentasi.
Kebijakan Deprecation
Satu peristiwa "breaking" rutin yang perlu Anda antisipasi: model tertentu dipensiunkan seiring penyedia upstream men-deprecate-nya. Periksa status model saat ini melalui GET /api/v1/models.
1
2
3
4
5
6
7
GET https://bazaarlink.ai/api/v1/models
Authorization: Bearer sk-bl-YOUR_API_KEY
# A model within 30 days of its deprecation date shows in the catalog# with an "EOL" badge on the Models page. After the effective date it's# dropped from the catalog and calls return:# 410 { "error": { "type": "model_not_available", "code": "model_retired" } }
Tetap Update
Kami belum mempublikasikan changelog API khusus atau RSS feed. Untuk saat ini, periksa langsung halaman ini, pantau status model melalui GET /api/v1/models, atau hubungi Support jika Anda memerlukan pemberitahuan lebih awal untuk integrasi yang kritis.
Support
Support
Hi! How can we help you? Send a message and we'll get back to you soon.