seamless.ai.id

Mulai dengan JavaScript / TypeScript (SDK OpenAI)

seamless.ai.id kompatibel dengan API OpenAI. Yang berbeda hanya base URL dan API key:

https://api.seamless.ai.id/v1

1. Siapkan API key

Pendaftaran mandiri belum dibuka: minta API key ke operator seamless.ai.id. Isi saldo dari dashboard (QRIS) sebelum memanggil model berbayar. Simpan key di variabel lingkungan, jangan di kode:

export SEAMLESS_API_KEY='sk-seamless-...'

2. Pasang SDK OpenAI

npm install openai

Setiap program di halaman ini dijalankan otomatis terhadap gateway dengan SDK openai 7.45.1.

3. Panggilan pertama

Simpan sebagai halo.mjs lalu jalankan node halo.mjs (Node.js 22 ke atas, yang dibutuhkan SDK openai versi 7). Kode yang sama berjalan sebagai TypeScript.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.seamless.ai.id/v1",
  apiKey: process.env.SEAMLESS_API_KEY,
});

const reply = await client.chat.completions.create({
  model: "qwen/qwen2.5-0.5b-instruct",
  messages: [{ role: "user", content: "Halo! Apa itu AI gateway?" }],
  max_tokens: 500,
});
console.log(reply.choices[0].message.content);

Streaming

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.seamless.ai.id/v1",
  apiKey: process.env.SEAMLESS_API_KEY,
});

const stream = await client.chat.completions.create({
  model: "qwen/qwen2.5-0.5b-instruct",
  messages: [{ role: "user", content: "Ceritakan sejarah singkat Jakarta." }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Responses API

POST /v1/responses menerima format Responses API OpenAI untuk setiap model chat, dengan harga, saldo yang ditahan, dan tagihan yang sama dengan chat completions. Server tidak menyimpan jawaban: kirim percakapan lengkap di input setiap kali. Yang didukung dan yang ditolak ada di ringkasan.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.seamless.ai.id/v1",
  apiKey: process.env.SEAMLESS_API_KEY,
});

const response = await client.responses.create({
  model: "qwen/qwen2.5-0.5b-instruct",
  instructions: "Jawab singkat dalam bahasa Indonesia.",
  input: "Halo! Apa itu AI gateway?",
  max_output_tokens: 500,
  store: false,
});
console.log(response.output_text);

const stream = await client.responses.create({
  model: "qwen/qwen2.5-0.5b-instruct",
  input: "Ceritakan sejarah singkat Jakarta.",
  stream: true,
  store: false,
});
for await (const event of stream) {
  if (event.type === "response.output_text.delta") process.stdout.write(event.delta);
}

Input gambar

Saat ini tidak ada model di daftar harga yang menerima gambar; request bergambar ke model berbayar ditolak (400 unsupported_content).

Memilih provider

Field gateway ikut di body request; opsi lengkapnya di ringkasan.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.seamless.ai.id/v1",
  apiKey: process.env.SEAMLESS_API_KEY,
});

const reply = await client.chat.completions.create({
  model: "qwen/qwen2.5-0.5b-instruct",
  messages: [{ role: "user", content: "Halo!" }],
  // Field milik gateway, bukan bagian tipe OpenAI (TypeScript perlu baris berikut).
  // @ts-expect-error
  gateway: { routing: { order: ["default"] } },
});
console.log(reply.choices[0].message.content);

Batch API

Untuk pekerjaan besar yang tidak perlu dijawab seketika (ribuan permintaan chat atau embedding): kirim semuanya dalam satu file JSONL, gateway menjalankannya dalam 24 jam, lalu unduh hasilnya. Contoh ini memakai qwen/qwen2.5-0.5b-instruct. Saat batch dibuat, biaya terburuk seluruh barisnya langsung ditahan dari saldo (setiap baris seperti permintaan langsung dengan max_tokens-nya); setiap baris lalu ditagih pemakaiannya saja dan sisanya kembali ke saldo saat baris selesai, batch dibatalkan, atau kedaluwarsa. Isi max_tokens di setiap baris supaya yang ditahan tidak besar. Aturan lengkapnya di ringkasan.

import { createReadStream, writeFileSync } from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.seamless.ai.id/v1",
  apiKey: process.env.SEAMLESS_API_KEY,
});

const questions = ["Apa ibu kota Jawa Barat?", "Sebutkan tiga makanan khas Padang."];
const lines = questions.map((question, i) => JSON.stringify({
  custom_id: `soal-${i + 1}`,
  method: "POST",
  url: "/v1/chat/completions",
  body: {
    model: "qwen/qwen2.5-0.5b-instruct",
    messages: [{ role: "user", content: question }],
    max_tokens: 300,
  },
}));
writeFileSync("permintaan.jsonl", lines.join("\n") + "\n");

const file = await client.files.create({ file: createReadStream("permintaan.jsonl"), purpose: "batch" });
let batch = await client.batches.create({
  input_file_id: file.id,
  endpoint: "/v1/chat/completions",
  completion_window: "24h",
});
console.log(batch.id, batch.status);

while (!["completed", "failed", "expired", "cancelled"].includes(batch.status)) {
  await new Promise((resolve) => setTimeout(resolve, 30_000));
  batch = await client.batches.retrieve(batch.id);
}
console.log(batch.status, batch.request_counts);

if (batch.output_file_id) {
  const output = await (await client.files.content(batch.output_file_id)).text();
  for (const text of output.split("\n").filter(Boolean)) {
    const result = JSON.parse(text);
    console.log(result.custom_id, result.response.body.choices[0].message.content);
  }
}

Jawaban batches.create memuat hold_micro_idr, dana yang ditahan untuk batch itu (mikro-rupiah). Batch yang belum selesai dibatalkan dengan batches.cancel(id). Daftar batch, statusnya, dana yang ditahan, dan file hasilnya juga tampil di tab Batch di Playground dashboard.

Preset: ganti model tanpa deploy ulang

Simpan model, prompt sistem, parameter bawaan, dan batas jawaban sekali sebagai preset, lalu aplikasi cukup mengirim "model": "@preset/asisten-cs" ke /v1/chat/completions atau /v1/responses. Mengganti model atau prompt cukup di preset (panel Preset dashboard atau /v1/presets). Aturannya di ringkasan.

SDK tidak perlu diubah: nama preset dikirim sebagai model, dan reply.model menyebut model yang benar-benar melayani.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.seamless.ai.id/v1",
  apiKey: process.env.SEAMLESS_API_KEY,
});

const reply = await client.chat.completions.create({
  model: "@preset/asisten-cs",
  messages: [{ role: "user", content: "Paket saya belum sampai, bagaimana?" }],
});
console.log(reply.model, reply.choices[0].message.content);

Kalau gagal

Error berformat OpenAI (error.type, error.code, error.param); daftar kode yang paling sering ada di ringkasan.