Dokumentasi developer

Bangun di atas API NaraRouter

Satu endpoint stabil yang kompatibel dengan OpenAI untuk berbagai model terkemuka. Arahkan SDK OpenAI apa pun ke base URL kami, autentikasi dengan key Anda, lalu rilis.

Mulai cepat

Tiga langkah menuju respons pertama Anda: buat key, atur base URL, kirim permintaan. API memakai format OpenAI Chat Completions, jadi klien OpenAI yang sudah ada cukup mengubah dua baris.

1. Buat API key

Masuk dan buka halaman API key untuk membuat key. Secret hanya ditampilkan sekali saat dibuat — segera salin dan simpan dengan aman. Key diawali prefix sk-nry-.

2. Atur base URL

Kirim semua permintaan ke base URL gateway. Endpoint chat berada di /v1/chat/completions.

text
https://router.bynara.id/v1

3. Kirim permintaan pertama

Gunakan cURL atau SDK apa pun yang kompatibel dengan OpenAI. Berikan alias model (lihat Model), pesan Anda, dan key Anda sebagai Bearer token.

1curl https://router.bynara.id/v1/chat/completions \2  -H "Authorization: Bearer sk-nry-xxxxxxxx" \3  -H "Content-Type: application/json" \4  -d '{5    "model": "deepseek-v4-flash",6    "messages": [7      { "role": "user", "content": "Hello!" }8    ]9  }'

Karena API kompatibel dengan OpenAI, SDK resmi OpenAI bekerja tanpa perubahan selain base URL dan key — tidak perlu klien khusus penyedia.

Autentikasi & key

Setiap permintaan ke API harus menyertakan secret key Anda di header Authorization sebagai Bearer token.

Header Authorization

http
Authorization: Bearer sk-nry-xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Format key

Key diawali sk-nry- diikuti secret acak. Secret penuh hanya dikembalikan sekali, saat pembuatan atau rotasi; setelah itu hanya bentuk tersamarkan yang ditampilkan.

Rotasi & pencabutan

Kelola key dari dasbor. Anda bisa merotasi key (menerbitkan secret baru dan membatalkan yang lama), mencabut key (tetap terdaftar tetapi tidak lagi mengautentikasi), atau menghapusnya. Secret yang dirotasi dan dicabut langsung berhenti bekerja.

Jaga kerahasiaan key

Perlakukan key seperti kata sandi. Jangan pernah menanamkannya di kode sisi klien, aplikasi mobile, atau repositori publik. Gunakan variabel lingkungan sisi server dan rotasi key yang Anda curigai bocor.

Dukungan endpoint

Gateway menyediakan empat permukaan API di bawah base URL dan Bearer key yang sama. Arahkan SDK yang kompatibel ke path yang sesuai.

POST/v1/responses

OpenAI Responses API

Responses API yang stateful. Kirim input beserta tools opsional dan terima objek respons terstruktur. Kompatibel dengan SDK OpenAI Responses.

POST/v1/messages

Anthropic Messages API

Format Messages native Anthropic. Arahkan SDK Anthropic ke base URL dan panggil path ini dengan key Anda sebagai Bearer token.

POST/v1/chat/completions

OpenAI Chat Completions

Endpoint chat utama yang kompatibel dengan OpenAI. Kirim daftar pesan dan terima respons model; mendukung streaming dan reasoning_effort.

POSThttps://api-images.bynara.id/v1/images/generationshttps://api-images.bynara.id/v1/images/edits

Pembuatan & edit gambar

Buat gambar dari prompt (/v1/images/generations) atau edit gambar yang ada (/v1/images/edits). Mengembalikan URL atau payload base64.

Permintaan

json
{
  "model": "deepseek-v4-flash",
  "messages": [
    { "role": "system", "content": "You are helpful." },
    { "role": "user", "content": "Hello!" }
  ],
  "temperature": 0.7,
  "max_tokens": 256
}

Respons

json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "deepseek-v4-flash",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Hello! How can I help?" },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 18, "completion_tokens": 8, "total_tokens": 26 }
}

Gateway memvalidasi model dan payload sebelum meneruskan. Permintaan streaming pada model yang tidak mendukung streaming akan ditolak.

Streaming

Atur stream ke true untuk menerima respons secara bertahap sebagai Server-Sent Events (SSE). Setiap event membawa delta JSON dalam format streaming OpenAI.

Format wire

Koneksi memakai content-type text/event-stream. Setiap potongan tiba sebagai baris data: berisi delta JSON. Stream berakhir dengan penanda data: [DONE].

text
data: {"choices":[{"delta":{"content":"Hel"}}]}

data: {"choices":[{"delta":{"content":"lo"}}]}

data: [DONE]

Mengonsumsi stream

Sebagian besar SDK OpenAI mendukung streaming secara native. Dengan SDK resmi, iterasi potongan stream dan baca content tiap delta.

python
stream = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Tell me a story."}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Jika error terjadi di tengah stream, gateway mengirim event error yang bersih diikuti [DONE]; error sebelum byte pertama dikembalikan sebagai respons error JSON biasa.

Model

Berikan alias model di field model. Daftar di bawah dimuat langsung dari endpoint paket publik, jadi selalu mencerminkan model yang ditawarkan saat ini dan tier paket mana yang memberikannya.

Langsung dari /api/plans. Endpoint terautentikasi /v1/models mengembalikan persis alias yang berhak diakses paket Anda sendiri.

Memuat model...

Sebagian model adalah model reasoning (misalnya kimi-k2.5 dan gemini-3.1-pro) yang memakai sebagian anggaran token untuk penalaran internal sebelum menghasilkan jawaban. Jika Anda menyetel max_tokens yang sangat kecil, isi (content) yang terlihat bisa kembali kosong karena anggaran habis untuk penalaran. Untuk model seperti ini, gunakan max_tokens yang lebih besar.

Reasoning

Model reasoning ("thinking") memakai sebagian budget token untuk berpikir secara internal sebelum menjawab. Atur seberapa dalam ia berpikir per permintaan dengan reasoning_effort.

reasoning_effort

Effort lebih tinggi berarti berpikir lebih dalam — lebih baik untuk tugas sulit, tapi lebih boros token dan lebih lambat. Gunakan none untuk mematikan reasoning, ultra sebagai alias max. Pada model non-reasoning field ini diabaikan. Level yang terlalu tinggi otomatis diturunkan ke level tertinggi yang didukung model (mis. max jadi xhigh/high) tanpa error.

EffortBerpikirBiaya & kecepatanCocok untuk
none

Mati

Paling murah, tanpa token berpikir

Matikan reasoning saat ingin jawaban langsung

minimal

Sekilas

Hampir tanpa biaya, berpikir tercepat

Tugas sepele yang butuh sedikit kehati-hatian

low

Singkat

Paling murah, paling cepat

Chat harian, tanya-jawab sederhana

medium

Sedang

Seimbang

Kebanyakan tugas - default yang masuk akal

high

Panjang, dalam

Lebih banyak token, lebih lambat

Matematika sulit, coding bertahap, perencanaan

xhigh

Sangat panjang, menyeluruh

Token berat, paling lambat

Coding frontier, agen jangka panjang

max

Tanpa batas

Token dan latensi maksimum

Analisis terdalam; ultra adalah alias max

json
{
  "model": "deepseek-v4-pro",
  "messages": [
    { "role": "user", "content": "Prove that sqrt(2) is irrational." }
  ],
  "reasoning_effort": "high"
}

// Same 7 levels on the other two chat endpoints:
// POST /v1/responses  ->  "reasoning": { "effort": "high" }
// POST /v1/messages   ->  "output_config": { "effort": "high" }
// Levels: none | minimal | low | medium | high | xhigh | max (ultra = max).
// Higher levels clamp to what each model supports instead of erroring.

Model mana yang mendukung

Panggil /v1/models dan cek flag reasoning di tiap model — true berarti model reasoning. Katalog Models juga menampilkan badge Reasoning.

Aman dikirim selalu

reasoning_effort tidak berefek pada model non-reasoning, jadi kamu bisa mengirimnya di setiap permintaan tanpa gating per model. Level yang tidak didukung tidak pernah error: otomatis diturunkan ke level tertinggi yang didukung model. Provider tanpa knob reasoning (Qoder, CommandCode, byNara event-stream) mengabaikan level dan memakai default masing-masing.

Budget output

Untuk model reasoning, gateway menjamin budget output yang cukup agar proses berpikir tidak menghabiskan jatah jawaban yang terlihat. max_tokens yang terlalu kecil tetap bisa mengembalikan konten kosong pada model ini — sisakan ruang atau kosongkan.

Jika reasoning_effort dikosongkan, default bawaan provider yang dipakai (medium di kebanyakan model, high di model yang reasoning-nya tidak bisa dimatikan). 7 level yang sama berlaku di /v1/chat/completions (reasoning_effort), /v1/responses (reasoning.effort), dan /v1/messages (output_config.effort).

Embedding

Ubah teks menjadi vektor untuk pencarian semantik, clustering, dan RAG. Kompatibel dengan OpenAI Embeddings API: kirim input dan terima vektor float.

POSThttps://router.bynara.id/v1/embeddings

POST /v1/embeddings dipetakan ke model embedding penyedia. Gunakan untuk mengindeks dokumen; saat query, embed pertanyaan, cari berdasarkan cosine similarity, lalu opsional rerank.

Permintaan

bash
curl https://router.bynara.id/v1/embeddings \
  -H "Authorization: Bearer sk-nry-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-small",
    "input": "The quick brown fox jumps over the lazy dog"
  }'
python
from openai import OpenAI

client = OpenAI(base_url="https://router.bynara.id/v1", api_key="sk-nry-xxxxxxxx")
res = client.embeddings.create(model="text-embedding-3-small", input="The quick brown fox jumps over the lazy dog")
print(res.data[0].embedding[:5])  # [0.012, -0.034, ...]

Respons

json
{
  "object": "list",
  "data": [{ "object": "embedding", "index": 0, "embedding": [0.012, -0.034, 0.041, ...] }],
  "model": "text-embedding-3-small",
  "usage": { "prompt_tokens": 9, "total_tokens": 9 }
}

Parameter

input bisa string atau array string. encoding_format, dimensions, dan user diteruskan apa adanya.

Embedding tidak mendukung streaming. Flag stream akan ditolak. Usage hanya melaporkan input token.

Rerank

Urutkan ulang kandidat hasil retrieval agar dokumen paling relevan berada di atas. Rerank memakai cross-encoder yang membaca query + dokumen bersamaan, lebih akurat daripada cosine similarity untuk memilih konteks teratas bagi LLM.

POSThttps://router.bynara.id/v1/rerank

POST /v1/rerank dipetakan ke model rerank penyedia. Kirim query dan daftar dokumen kandidat (mis. 20 teratas dari pencarian vektor) dan terima hasil berperingkat dengan relevance_score.

Pipeline RAG umum: embed 20 kandidat via /v1/embeddings -> rerank ke top 5 -> kirim ke chat completions. Rerank menambah 100-300ms tapi meningkatkan presisi 20-30%.

Permintaan

bash
curl https://router.bynara.id/v1/rerank \
  -H "Authorization: Bearer sk-nry-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "rerank-v3",
    "query": "cara reset password nararouter",
    "documents": [
      "panduan billing reset saldo",
      "cara reset password nararouter via dashboard",
      "reset password email token"
    ],
    "top_n": 3
  }'
python
# RAG: embed 20 docs via /v1/embeddings, then rerank top candidates
import requests
res = requests.post(f"https://router.bynara.id/v1/rerank", headers={"Authorization": "Bearer sk-nry-xxxxxxxx"}, json={
    "model": "rerank-v3",
    "query": "cara reset password nararouter",
    "documents": docs,  # 10-20 candidates from vector search
    "top_n": 5
})
for r in res.json()["results"]:
    print(r["index"], r["relevance_score"], docs[r["index"]][:60])

Respons

json
{
  "object": "list",
  "results": [
    { "index": 1, "relevance_score": 0.98 },
    { "index": 2, "relevance_score": 0.85 },
    { "index": 0, "relevance_score": 0.21 }
  ],
  "model": "rerank-v3",
  "usage": { "prompt_tokens": 142, "total_tokens": 142 }
}

Parameter

query

Query pencarian (string).

documents

Array string dokumen kandidat (cuplikan yang akan dinilai).

top_n

Opsional. Batasi jumlah hasil (mis. 5). Jika kosong, penyedia mengembalikan semua dokumen yang sudah diranking.

model

Alias model rerank.

System One

System One (Jev) menjawab pertanyaan bertipe tentang suatu state, bukan menghasilkan prosa. Ajukan beberapa pertanyaan dalam satu request dan dapatkan jawaban terstruktur yang mudah dipakai untuk classifier atau control plane.

POSThttps://router.bynara.id/v1/systemone

POST /v1/systemone menerima state, alias model, dan map questions. Respons mempertahankan nama setiap pertanyaan dan mengembalikan jawaban bertipe, serta probabilitas dan confidence jika tersedia.

choice — pilih satu opsi

Gunakan choice saat tepat satu label harus dipilih. Definisikan maksimal 255 opsi di criteria; respons berisi choice terpilih, probabilitas tiap opsi, dan confidence.

score — nilai pada level berurutan

Gunakan score saat hasil berada pada skala berurutan. Berikan 2–10 level criteria; respons berisi score berbobot, legend, probabilitas, dan confidence.

noul — evaluasi sebuah pernyataan

Gunakan noul untuk pernyataan bergaya ya/tidak seperti “Apakah pesan ini menunjukkan urgensi?”. Respons mengembalikan nilai noul dari 0 sampai 1; confidence bisa tidak ada.

System One tidak mendukung streaming.

Permintaan

bash
curl https://router.bynara.id/v1/systemone   -H "Authorization: Bearer sk-nry-xxxxxxxx"   -H "Content-Type: application/json"   -d '{
    "model": "jev",
    "state": "The customer has waited three days for a refund.",
    "questions": {
      "intent": {
        "type": "choice",
        "instructions": "Classify the customer's intent.",
        "criteria": {
          "billing": "Billing or payment issue",
          "technical": "Technical issue",
          "abuse": "Abuse or safety issue"
        }
      },
      "severity": {
        "type": "score",
        "instructions": "Rate the severity of the issue.",
        "criteria": ["trivial", "minor", "major", "critical"]
      },
      "urgent": {
        "type": "noul",
        "instructions": "Does this message express urgency?"
      }
    }
  }'
python
import requests

res = requests.post(
    "https://router.bynara.id/v1/systemone",
    headers={"Authorization": "Bearer sk-nry-xxxxxxxx"},
    json={
        "model": "jev",
        "state": "The customer has waited three days for a refund.",
        "questions": {
            "intent": {
                "type": "choice",
                "instructions": "Classify the customer's intent.",
                "criteria": {"billing": "Billing", "technical": "Technical"},
            },
            "severity": {
                "type": "score",
                "instructions": "Rate the severity.",
                "criteria": ["trivial", "minor", "major", "critical"],
            },
            "urgent": {
                "type": "noul",
                "instructions": "Does this message express urgency?",
            },
        },
    },
)
print(res.json()["answers"])

Respons

json
{
  "model": "jev",
  "answers": {
    "intent": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.98,
      "probabilities": { "billing": 0.98, "technical": 0.01, "abuse": 0.01 }
    },
    "severity": {
      "type": "score",
      "score": 2.31,
      "confidence": 0.66,
      "legend": { "0": "trivial", "1": "minor", "2": "major", "3": "critical" },
      "probabilities": { "0": 0.01, "1": 0.02, "2": 0.66, "3": 0.31 }
    },
    "urgent": { "type": "noul", "noul": 0.72 }
  },
  "usage": { "input_tokens": 293, "output_tokens": 21 }
}

Bentuk wire kompatibel dengan SDK TypeSafe System One. Arahkan SDK ke https://router.bynara.id/v1 dan ubah hanya base URL (tetap gunakan Bearer key NaraRouter); tidak perlu adapter khusus provider.

Generasi video

Buat klip MP4 pendek dari teks atau gambar dengan satu endpoint. Gateway menangani task async di upstream (buat + polling) di server, jadi satu request mengembalikan video jadi.

POSThttps://api-images.bynara.id/v1/videos

Text-to-video memakai body JSON. Image-to-video dan reference-to-video mengirim gambar sumber sebagai multipart form data (image, image2, image3), atau sebagai URL publik lewat image_urls[] di JSON.

Mode generasi

ModeCara gambar dipakaiGambar
t2v · Text-to-video

Tanpa gambar. Video dibuat murni dari prompt teks.

0

i2v · Image-to-video

Gambar yang diupload menjadi frame PERTAMA video; model menggerakkan isi gambar dari komposisi itu.

Tepat 1

r2v · Reference-to-video

Gambar menjadi referensi subjek/gaya (karakter, objek, pakaian); model menggabungkannya ke scene BARU dari prompt, tidak terikat frame sumber mana pun.

1-3

Contoh r2v: gambar 1 penyihir, gambar 2 naga api, gambar 3 kastil, prompt 'Penyihir bertarung melawan naga api di halaman kastil' — model menyusun scene baru dengan elemen dari ketiga gambar.

Permintaan

bash
curl --request POST \
  --url https://api-images.bynara.id/v1/videos \
  --header 'Authorization: Bearer sk-nry-xxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "happyhorse-1.1-t2v",
    "prompt": "A miniature city built from cardboard comes to life at night",
    "mode": "t2v",
    "resolution": "720p",
    "ratio": "16:9",
    "duration": 5
  }'

// Optional: "enable_audio": true adds a soundtrack (CodeBuddy/Seedance models
// only, JSON or --form). It is OFF by default because audio renders can be
// rejected upstream by the copyright check.
bash
curl --request POST \
  --url https://api-images.bynara.id/v1/videos \
  --header 'Authorization: Bearer sk-nry-xxxxxxxx' \
  --form [email protected] \
  --form model=happyhorse-1.1-i2v \
  --form mode=i2v \
  --form prompt='The wizard raises his staff, wind blows his cloak, camera slowly zooms in' \
  --form resolution=720p \
  --form duration=5
bash
curl --request POST \
  --url https://api-images.bynara.id/v1/videos \
  --header 'Authorization: Bearer sk-nry-xxxxxxxx' \
  --form [email protected] \
  --form [email protected] \
  --form [email protected] \
  --form model=agnes-video-v2.0 \
  --form mode=r2v \
  --form prompt='The wizard battles the fire dragon in the castle courtyard' \
  --form duration=5

Respons

json
# POST /v1/videos  ->  202 Accepted
{ "id": "01934...", "status": "pending", "created": 1780457477 }

# GET /v1/videos/{id}  (poll every ~5s)
{ "id": "01934...", "status": "succeeded",
  "url": "/v1/videos/01934.../download",
  "duration": 5, "created": 1780457477, "expires_at": "..." }

Parameter

model

Alias video, mis. happyhorse-1.1-t2v atau agnes-video-v2.0.

mode

t2v, i2v, atau r2v. i2v wajib tepat 1 gambar; r2v wajib 1-3.

prompt

Prompt positif (dan negative_prompt opsional). Maksimal 3.500 karakter masing-masing.

resolution

720p atau 1080p (default provider jika dikosongkan).

ratio

16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9. Hanya text-to-video; i2v mengikuti rasio frame pertama.

duration

Panjang klip dalam detik, 3-15 (atau sesuai batas maks model). Ditagih per detik (harga_per_detik × durasi).

seed

Seed acak [0, 2147483647] untuk reproduksibilitas.

watermark

Toggle watermark provider.

images

Multipart image, image2, image3 (i2v/r2v), atau image_urls[] di JSON untuk URL publik.

Videos API bersifat asynchronous: POST /v1/videos langsung mengembalikan ID dengan status pending (HTTP 202), lalu polling GET /v1/videos/[id] tiap ~5 detik sampai status succeeded — response lalu menyertakan URL unduhan. MP4 disimpan sementara dan kedaluwarsa setelah 3 jam. Generasi biasanya memakan 1-5 menit.

Rate limit & kuota

Batas tergantung paket Anda. Paket langganan diatur oleh rate limit permintaan per menit dan kuota token harian; tier gratis dan batas pemakaian wajar per model berlaku selain itu.

Rate limit (per menit)

Tiap paket menetapkan jumlah maksimum permintaan per menit. Melebihinya mengembalikan 429 dengan error rate_limited. Jendela direset tiap menit.

Kuota token harian

Paket langganan menghitung token input + output terhadap bucket harian — tetapi bucket-nya per kelas model, bukan satu plafon untuk seluruh akun. Tiap kelas (Dasar, Lite, Mocin, Pro) punya plafon harian terpisah. Saat bucket sebuah kelas tercapai, hanya kelas itu yang mengembalikan 429 hingga hari berikutnya; bucket kelas lain tetap jalan. Plafon null berarti pemakaian wajar (tanpa plafon harian keras).

Bucket token harian per kelas

Setiap model termasuk dalam satu kelas kuota — Dasar, Lite, Mocin, atau Pro — dan tiap kelas punya bucket token harian sendiri: Dasar 60.000.000, Lite 50.000.000, Mocin 70.000.000, Pro 20.000.000 token/hari. Langganan mendapat bucket harian terpisah untuk setiap kelas yang bisa diakses, dan bucket-nya independen: memakai model hanya dihitung pada bucket kelasnya sendiri dan tidak pernah mengurangi bucket lain. Ketika satu bucket habis, model di kelas lain yang Anda miliki tetap bisa dipakai hingga bucket direset di awal hari berikutnya.

Konkurensi

Paket juga membatasi berapa banyak permintaan yang boleh berjalan sekaligus. Permintaan bersamaan yang berlebih ditolak dengan 429; coba lagi setelah permintaan yang sedang berjalan selesai.

Perilaku 429

Pada setiap pelanggaran batas, status respons 429 dengan tipe error rate_limited. Pelanggaran token harian bersifat per tier model — pesannya menyatakan kuota tier model ini habis, sementara tier model lain yang bisa Anda akses tetap jalan. Mundur dan coba lagi setelah jendela terkait direset. Batas per paket ditampilkan di halaman harga dan dimuat langsung di bawah.

Error

Error memakai satu envelope JSON yang stabil. Cabang berdasarkan field type alih-alih mengurai message. Field request_id membantu mengaitkan kegagalan dengan log server.

Bentuk error

json
{
  "error": {
    "type": "rate_limited",
    "message": "Rate limit exceeded. Please retry later.",
    "request_id": "req_..."
  }
}

Kode status

StatusTipeArti
400validation_error

Permintaan salah bentuk atau gagal validasi (misalnya field model atau messages hilang).

401unauthorized

API key hilang atau tidak valid. Periksa header Authorization.

403forbidden

Terautentikasi, tetapi paket Anda tidak mencakup model yang diminta, atau akun ditangguhkan.

404not_found

Alias model atau endpoint yang diminta tidak ada.

413bad_request

Body permintaan atau input terlalu besar.

415unsupported_media_type

Content-Type harus application/json.

429rate_limited

Rate limit atau bucket token harian per tier model terlampaui. Pelanggaran kuota hanya memengaruhi tier model itu — tier lain yang bisa Anda akses tetap jalan. Coba lagi setelah jendela direset.

503service_unavailable

Layanan model sementara tidak tersedia. Coba lagi dengan backoff.

500internal_error

Error internal tak terduga. Coba lagi; jika berlanjut, hubungi dukungan dengan request_id.

Keamanan & kebijakan konten

Permintaan disaring terhadap sejumlah kecil kategori penyalahgunaan sebelum mencapai penyedia upstream. Permintaan yang ditandai ditolak secara lokal dengan pesan yang jelas — penyedia upstream tidak pernah melihatnya. Ini melindungi akun upstream bersama di balik gateway dan menjaga layanan tetap tersedia untuk semua orang.

Apa yang disaring

KategoriPemicu penolakan

Pembuatan alat ofensif

Permintaan membangun alat serangan atau malware — misalnya bingkai otorisasi ("pentest resmi") yang membungkus pengembangan exploit, framework C2, pencurian kredensial, penghindaran deteksi, atau rantai serangan end-to-end.

Keamanan anak (CSAM)

Permintaan apa pun yang melibatkan konten seksual tentang anak di bawah umur. Kategori ini ditolak langsung dan berakibat tindakan akun seketika di upstream, sehingga ditegakkan secara ketat.

Eksfiltrasi kredensial

Permintaan untuk meng-echo atau mereproduksi nilai berbentuk rahasia secara verbatim (API key, private key, atau access token). Kode konfigurasi biasa yang hanya menyebut nama key tidak terpengaruh.

Senjata & infrastruktur kritis

Permintaan membangun senjata atau material CBRN, atau menyerang infrastruktur kritis (jaringan listrik, pasokan air, SCADA). Diskusi tentang topik yang sama tidak terpengaruh — hanya permintaan build/serang.

Penyaringan ini konservatif: coding biasa, kerja pertahanan keamanan (detection rule, threat intel, patching), dan edukasi tidak terpengaruh. Hanya transkrip yang jelas terbaca sebagai permintaan membangun serangan, atau konten seksual yang melibatkan anak di bawah umur, yang ditolak.

Respons saat permintaan diblokir

Permintaan yang diblokir mengembalikan envelope error standar dengan HTTP 400 dan type validation_error. Pesannya menjelaskan alasannya dan menegaskan tidak ada yang dikirim ke upstream. Beralih pada field type, bukan teks pesan.

json
{
  "error": {
    "type": "validation_error",
    "message": "This request was rejected locally: ...",
    "request_id": "req_..."
  }
}

Karena permintaan tidak pernah mencapai penyedia, ia tidak diulang dan tidak dialihkan ke akun lain. Ubah kalimat permintaan atau arahkan sesi ke model lain.

Ditolak lokal, tidak pernah diteruskan

Penyaringan berjalan di dalam gateway sebelum koneksi upstream apa pun — termasuk tahap autentikasi. Permintaan yang diblokir tidak memakai kuota upstream dan tidak dapat membuat akun ditandai.

Keamanan defensif diizinkan

Detection engineering, threat intelligence, incident response, analisis malware, studi CTF/lab, dan hardening keamanan diakui sebagai sah dan lolos. Menyebut sebuah teknik dalam konteks defensif tidak membuat Anda diblokir.

Bukan error transien

Penolakan keamanan bersifat terminal: mengulang prompt yang sama, atau beralih ke akun lain, tidak akan mengubah hasilnya. Sesuaikan isi permintaan.

Combo model

Combo model adalah virtual model id milik user berbentuk combo/'<nama>' yang menggabungkan beberapa model nyata dalam satu strategi fallback. Jika model pertama di panel gagal, combo otomatis beralih ke model berikutnya — sempurna untuk menjaga model gratis tetap tangguh.

Apa itu combo?

Combo menggabungkan 1-5 alias model dalam satu id combo/'<nama>'. Permintaan ke id tersebut dirutekan ke model panel secara berurutan: jika model pertama gagal, combo langsung mencoba model berikutnya dalam permintaan yang sama. Circuit breaker berbasis Redis melacak kegagalan antar permintaan sehingga model yang diketahui turun dilewati tanpa memanggil engine.

Cara kerja fallback

Saat Anda memanggil combo/'<nama>', gateway mencoba setiap model panel satu per satu dalam PERMINTAAN YANG SAMA: target 1 → jika gagal (402, 403, 500, timeout) → lepaskan billing → target 2 → jika gagal → target 3, dan seterusnya. Target pertama yang berhasil mengembalikan responsnya. Jika semua target gagal, combo mengembalikan error terakhir.

Circuit breaker

Circuit breaker mencegah combo memanggil model yang sedang turun berulang-ulang. Setelah kegagalan, circuit model tersebut terbuka selama cooldown 10 menit — selama itu model dilewati langsung (tanpa panggilan engine yang sia-sia). Setelah cooldown berakhir, model dicoba lagi. Permintaan yang berhasil menutup circuit dan mereset counter. Kegagalan deterministik (402 saldo tidak cukup, 403 tidak berhak) langsung membuka circuit; kegagalan transien (500, timeout) butuh 3 kegagalan berturut-turut sebelum circuit terbuka.

Strategi fallback

Model panel dicoba dari atas ke bawah sesuai urutan yang Anda konfigurasi. Taruh model paling andal di atas dan gunakan sisanya sebagai cadangan. Target yang circuit-open dilewati sebelum engine dipanggil, jadi model yang turun tidak menambah latensi.

Contoh permintaan

bash
curl https://router.bynara.web.id/v1/chat/completions \
  -H "Authorization: Bearer sk-nry-yourapikey" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "combo/free-pack",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Aturan penamaan

Bagian '<nama>' harus 1-19 karakter huruf kecil, angka, titik, dan tanda hubung — tanpa tanda baca ganda, tanpa underscore, tanpa spasi. Id lengkap combo/'<nama>' harus 25 karakter atau kurang. Nama yang salah bentuk dinormalisasi otomatis (mis. combo/-aneh---.. menjadi combo/aneh).

Privasi pemilik

Combo bersifat pribadi untuk pemilik API key yang membuatnya. User lain yang memanggil combo/'<nama>' Anda mendapat 404 (model tidak ditemukan), bukan 403 — sehingga keberadaan combo tidak pernah bocor. Ini mencegah konflik nama antar user.

Mengelola combo

Buat dan kelola combo di dashboard bagian Developer > Combo model. Tiap combo menampilkan jumlah permintaan dan token per model. Log permintaan menampilkan via combo/'<nama>' di tiap baris yang dirutekan, dengan model yang benar-benar melayani permintaan.

Paket & harga

Harga dalam Rupiah, ditagih per hari atau per minggu. Tiap tier memberikan set model, rate limit permintaan, dan kuota token harian. Tier dimuat langsung di bawah.