curl --request POST \
--url https://api.apimart.ai/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Idempotency-Key: 6baf0940-25d6-4ec2-9131-925250840fa7' \
--data '{
"model": "grok-imagine-2.0-ext",
"operation": "segment",
"image_urls": ["https://upload.apimart.ai/f/image/..."],
"cache_only": true,
"include_mask_rle": false
}'
{
"code": 200,
"data": [{ "status": "submitted", "task_id": "task_..." }]
}
Grok Imagine 2.0 Ext
Lapisan dan Pengeditan Wilayah Grok Imagine 2.0 Ext
Gunakan segment untuk mengambil lapisan objek dan mask presisi, lalu edit poligon, kotak, atau objek terdeteksi dengan region_edit.
POST
/
v1
/
images
/
generations
curl --request POST \
--url https://api.apimart.ai/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Idempotency-Key: 6baf0940-25d6-4ec2-9131-925250840fa7' \
--data '{
"model": "grok-imagine-2.0-ext",
"operation": "segment",
"image_urls": ["https://upload.apimart.ai/f/image/..."],
"cache_only": true,
"include_mask_rle": false
}'
{
"code": 200,
"data": [{ "status": "submitted", "task_id": "task_..." }]
}
segment dan region_edit menggunakan endpoint gambar asinkron yang sama. Simpan task_id, lalu polling Dapatkan status tugas; permintaan pembuatan tidak langsung mengembalikan lapisan atau gambar final.Jangan pernah mengekspos API Key di bundle browser, LocalStorage, URL, atau log frontend. Panggil APIMart melalui backend atau BFF Anda.
curl --request POST \
--url https://api.apimart.ai/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Idempotency-Key: 6baf0940-25d6-4ec2-9131-925250840fa7' \
--data '{
"model": "grok-imagine-2.0-ext",
"operation": "segment",
"image_urls": ["https://upload.apimart.ai/f/image/..."],
"cache_only": true,
"include_mask_rle": false
}'
{
"code": 200,
"data": [{ "status": "submitted", "task_id": "task_..." }]
}
Ringkasan operasi
| Tujuan | Input utama | Hasil selesai | Penagihan |
|---|---|---|---|
segment: Mendeteksi objek serta mengambil lapisan, kotak, dan mask presisi | source_task_id atau image_urls berisi satu gambar unggahan | image_id, image_url, objects | Gratis |
region_edit: Mengedit poligon, persegi panjang, atau objek terdeteksi | image_id, prompt, pilihan | URL baru dan image_id | Ditagih per tugas selesai |
task_id selesai ─────────────┐
├→ segment → image_id + mask_rle
URL publik gambar unggahan ──┘ → selection_regions → region_edit → task_id + image_id baru
Pilih tepat satu sumber
segment: source_task_id atau image_urls. Field tersebut dan image_id tidak dapat dipertukarkan; region_edit tetap memakai ID aset yang dikembalikan segment. Untuk melakukan segmentasi ulang gambar hasil edit, gunakan ID tugas region_edit yang selesai sebagai source_task_id baru.Header permintaan
GunakanAuthorization: Bearer <APIMART_API_KEY>, Content-Type: application/json, dan Accept: application/json.
Idempotency-Key bersifat opsional dan sangat disarankan untuk permintaan region_edit berbayar. Nilainya mendukung 1–191 karakter ASCII yang terlihat; UUID disarankan. Gunakan key baru untuk setiap operasi logis baru. Retry jaringan untuk permintaan yang sama harus memakai ulang key dan body yang identik. Jika hasil tidak pasti, jangan retry otomatis dengan key baru.
Alur tugas asinkron
Pembuatan yang berhasil mengembalikan HTTP200 dan data[0].task_id. Poll GET /v1/tasks/{task_id}?language=id mulai tiap 2 detik, naik hingga maksimum 5 detik, dengan batas total 10 menit. Hentikan polling lama saat gambar sumber berubah.
Kueri tugas dapat mengembalikan HTTP
200 ketika data.status bernilai failed. Tentukan hasil dari data.status dan tampilkan data.error bila ada.segment
Parameter permintaan
| Kolom | Tipe | Wajib | Deskripsi |
|---|---|---|---|
model | string | ✅ | Tetap grok-imagine-2.0-ext |
operation | string | ✅ | Tetap segment |
nsfw_check | boolean | — | Default: false.true: periksa gambar sumber dengan omni-moderation-latest.false atau dihilangkan: tidak mengirim permintaan moderasi. |
source_task_id | string | Bersyarat | Tugas Grok satu gambar yang selesai dan dimiliki pengguna saat ini; tidak boleh bersama image_urls |
image_urls | string[] | Bersyarat | Tepat satu URL HTTP(S) absolut yang dapat diakses publik; tidak boleh bersama source_task_id. Unggah gambar lokal melalui POST /v1/uploads/images, lalu gunakan url yang dikembalikan |
include_mask_rle | boolean | — | Default: true; false menghilangkan mask RLE, tetapi tetap mengembalikan ID aset, indeks objek, dan kotak |
cache_only | boolean | — | Default: false; wajib true bersama image_urls; hanya periksa cache segmentasi |
cached_only | boolean | — | Default: false; petunjuk cache upstream khusus sumber tugas, bukan jaminan lokal |
refresh | boolean | — | Default: false; lewati cache khusus sumber tugas; jangan gunakan dalam alur normal |
segment tidak memerlukan prompt. Jangan kirim image_id, image_index, billing_model_name, n, size, atau response_format. Kirim tepat satu dari source_task_id dan image_urls. Mode URL gambar memerlukan cache_only=true dan tidak mendukung cached_only atau refresh.
Contoh permintaan
- Gunakan ID tugas
- Gunakan gambar unggahan
- Periksa cache tugas
{
"model": "grok-imagine-2.0-ext",
"operation": "segment",
"source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
"include_mask_rle": true,
"cached_only": false
}
{
"model": "grok-imagine-2.0-ext",
"operation": "segment",
"image_urls": ["https://upload.apimart.ai/f/image/..."],
"cache_only": true,
"include_mask_rle": false
}
{
"model": "grok-imagine-2.0-ext",
"operation": "segment",
"source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
"include_mask_rle": true,
"cache_only": true
}
cache_status (hit atau miss) atau from_cache; jangan menyimpulkan hit dari cached.
Unggah gambar lokal
Unggah file lokal terlebih dahulu dan baca URL publik dari respons:curl --request POST \
--url https://api.apimart.ai/v1/uploads/images \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/source.png'
url yang dikembalikan sebagai satu-satunya elemen image_urls. Polling, respons selesai, dan region_edit selanjutnya sama seperti penggunaan ID tugas: baca result.image_id dan objects, lalu kirim edit pilihan. URL unggahan bersifat sementara dan disimpan selama 72 jam secara default.
image_urls hanya menerima tepat satu URL HTTP(S) absolut yang dapat diakses publik. Mode URL gambar hanya mendukung cache_only=true; jangan kirim juga source_task_id, cached_only, atau refresh.Respons selesai
Untuksegment, data.result langsung berisi hasil segmentasi dan tidak dibungkus dalam images.
{
"code": 200,
"data": {
"id": "task_...",
"status": "completed",
"progress": 100,
"cost": 0,
"credits_cost": 0,
"result": {
"source_task_id": "task_...",
"image_id": "6b78a7c3-5f9e-4a3d-a928-9e9b42113a3f",
"image_url": "https://.../source.jpg",
"from_cache": true,
"cache_status": "hit",
"objects": [{
"index": 0,
"name": "red sports car",
"box_xyxy": [38.1, 689.8, 945.8, 1065.4],
"score": 0.9765625,
"mask_size": [1792, 1008],
"mask_url": "",
"mask_rle": { "size": [1792, 1008], "counts": "..." }
}]
}
}
}
| Kolom | Deskripsi |
|---|---|
result.image_id | ID aset untuk region_edit |
result.image_url | URL HTTP(S) yang sejajar dengan image_id |
objects[].index | Indeks server asli; pertahankan untuk object_indices |
objects[].box_xyxy | Kotak piksel mask [x1,y1,x2,y2] |
objects[].score | Skor keyakinan; dapat berupa null |
objects[].mask_size | Selalu [height,width]; jangan hard-code dimensi |
objects[].mask_rle | COCO compressed RLE untuk kontur presisi |
objects[].mask_url | URL gambar mask opsional; dapat kosong |
mask_rle atau mask_url yang valid hanya dapat memakai edit kotak perkiraan.
Dekode mask_rle
mask_rle.counts adalah string hitungan terkompresi COCO, bukan Base64 atau zlib. Data dibuka per kolom; run pertama adalah latar, lalu bergantian antara depan dan latar.
TypeScript berikut mengubahnya menjadi mask biner per baris yang sesuai untuk browser:
export interface CocoRLE {
size: [height: number, width: number];
counts: string;
}
export interface BinaryMask {
width: number;
height: number;
data: Uint8Array; // data[y * width + x]
}
function decodeCompressedCounts(counts: string): number[] {
const runs: number[] = [];
let cursor = 0;
while (cursor < counts.length) {
let value = 0;
let shift = 0;
let more = true;
while (more) {
if (cursor >= counts.length) throw new Error("Truncated COCO RLE counts");
const current = counts.charCodeAt(cursor++) - 48;
value |= (current & 0x1f) << shift;
more = (current & 0x20) !== 0;
shift += 5;
if (!more && (current & 0x10) !== 0) value |= -1 << shift;
}
if (runs.length > 2) value += runs[runs.length - 2] ?? 0;
if (value < 0) throw new Error(\`Invalid COCO RLE run: \${value}\`);
runs.push(value);
}
return runs;
}
export function decodeCocoRLE(rle: CocoRLE): BinaryMask {
const [height, width] = rle.size;
if (!Number.isInteger(height) || !Number.isInteger(width) || height <= 0 || width <= 0) {
throw new Error(\`Invalid mask size: \${JSON.stringify(rle.size)}\`);
}
const pixelCount = width * height;
if (!Number.isSafeInteger(pixelCount) || pixelCount > 32_000_000) {
throw new Error(\`Mask exceeds the frontend safety limit: \${pixelCount}\`);
}
if (!rle.counts) throw new Error("Missing COCO RLE counts");
const data = new Uint8Array(pixelCount);
const runs = decodeCompressedCounts(rle.counts);
let position = 0;
let foreground = false;
for (const run of runs) {
if (position + run > data.length) throw new Error("COCO RLE exceeds mask_size");
if (foreground) {
for (let offset = 0; offset < run; offset++) {
const index = position + offset;
const y = index % height;
const x = (index - y) / height;
data[y * width + x] = 1;
}
}
position += run;
foreground = !foreground;
}
if (position !== data.length) throw new Error("COCO RLE does not cover the mask");
return { width, height, data };
}
mask_rle.counts ke log, analitik, URL, atau pelaporan error.
Ubah mask menjadi pilihan presisi
interface SelectionBoundary { points: number[] }
interface SelectionRegion { outer: SelectionBoundary; holes?: SelectionBoundary[] }
0–1. Tiap ring memerlukan minimal 3 titik berbeda, area tidak nol, dan tidak boleh berpotongan sendiri. Simpan maksimal 16 region terbesar per lapisan dan 400 titik per ring.
mask_size adalah [height,width] dan memakai koordinat mask sumber, bukan ukuran CSS. Dengan object-fit: contain, kurangi offset letterbox, skala sesuai area gambar aktual, dan batasi hasil ke 0–1.mask_url memerlukan CORS. Tetapkan crossOrigin = "anonymous" sebelum src, atau fetch Blob. Dekode mask_rle langsung menghindari dependensi ini.
Edit wilayah: region_edit
Parameter permintaan
| Kolom | Tipe | Wajib | Deskripsi |
|---|---|---|---|
model | string | ✅ | Tetap grok-imagine-2.0-ext |
operation | string | ✅ | region_edit |
nsfw_check | boolean | — | Default: false.true: periksa prompt edit dan gambar input dengan omni-moderation-latest.false atau dihilangkan: tidak mengirim permintaan moderasi. |
image_id | string | ✅ | ID aset sumber; pertama gunakan image_id dari segment, lalu hasil edit terbaru |
prompt | string | ✅ | Instruksi tidak kosong yang menjelaskan perubahan |
selection_regions | array | * | Poligon 0–1 dengan outer dan holes opsional; direkomendasikan |
boxes | number[][] | * | Persegi panjang [x1,y1,x2,y2]; kotak piksel memerlukan mask_size |
object_indices | integer[] | * | Nilai asli objects[].index; hanya edit kotak perkiraan |
mask_size | integer[] | * | Wajib untuk kotak piksel; [height,width] berupa integer positif |
selection_regions, boxes, atau object_indices harus tidak kosong. API menerima kombinasi, tetapi frontend sebaiknya memakai satu metode per permintaan.
Jangan kirim
billing_model_name, size, aspect_ratio, source_aspect_ratio, source_size, atau image_urls. Hilangkan n atau isi 1; hilangkan claim_asset atau isi false; hilangkan response_format atau isi url. Base64 dan stream=true tidak didukung.Metode pilihan
| Metode | Sumber pilihan | Presisi | Penggunaan |
|---|---|---|---|
selection_regions | Poligon frontend | Presisi, termasuk lubang | Edit lapisan atau kuas produksi |
boxes | Persegi panjang frontend | Perkiraan kotak | Alat kotak atau MVP |
object_indices | Indeks segment asli | Perkiraan kotak | Uji integrasi cepat |
- Poligon presisi
- Kotak ternormalisasi
- Kotak piksel
- Indeks objek
{
"model": "grok-imagine-2.0-ext",
"operation": "region_edit",
"image_id": "<SOURCE_IMAGE_ID>",
"prompt": "Change the selected car to bright red and preserve the rest",
"selection_regions": [{
"outer": { "points": [0.12, 0.20, 0.48, 0.20, 0.48, 0.61, 0.12, 0.61] },
"holes": [{ "points": [0.30, 0.35, 0.38, 0.35, 0.38, 0.45, 0.30, 0.45] }]
}]
}
points dapat berupa array datar atau pasangan bertingkat. Setiap nilai harus terbatas dan berada pada 0–1; tiap ring membutuhkan minimal 3 pasangan.{
"model": "grok-imagine-2.0-ext",
"operation": "region_edit",
"image_id": "<SOURCE_IMAGE_ID>",
"prompt": "Change the car inside the box to bright red",
"boxes": [[0.04, 0.385, 0.938, 0.594]]
}
{
"model": "grok-imagine-2.0-ext",
"operation": "region_edit",
"image_id": "<SOURCE_IMAGE_ID>",
"prompt": "Change the car inside the box to bright red",
"boxes": [[40, 689.6, 945.9, 1064.4]],
"mask_size": [1792, 1008]
}
{
"model": "grok-imagine-2.0-ext",
"operation": "region_edit",
"image_id": "<SOURCE_IMAGE_ID>",
"prompt": "Change the selected car to bright red",
"object_indices": [0]
}
image_id yang sama. Jangan ganti dengan indeks dari array frontend yang difilter, diurutkan, atau dikelompokkan.Respons selesai
{
"code": 200,
"data": {
"id": "task_...",
"status": "completed",
"progress": 100,
"cost": 0.016,
"credits_cost": 0.16,
"result": {
"images": [{
"url": ["https://.../result.jpg"],
"image_ids": ["<NEW_IMAGE_ID>"],
"items": [{
"url": "https://.../result.jpg",
"image_id": "<NEW_IMAGE_ID>",
"source_image_id": "<SOURCE_IMAGE_ID>",
"role": "region_edit"
}],
"expires_at": 1787040000
}]
}
}
}
result.images[0].items[0]. Untuk respons lama, pasangkan url[0] dan image_ids[0] hanya jika panjang array sama. Lanjutkan hanya setelah memperoleh URL HTTP(S) dan image_id baru.
Gunakan expires_at sebagai acuan kedaluwarsa URL; jangan hard-code jumlah jam. Unduh atau simpan aset yang dibutuhkan jangka panjang.
Pengeditan berkelanjutan
Setelah edit selesai, perbarui URL tampilan, ID aset saat ini, dan ID tugas sumber secara bersamaan, lalu hapus lapisan dan status polling lama.- Segmentasi ulang: gunakan ID tugas
region_editini sebagaisource_task_id - Edit ulang: gunakan
image_idbaru yang dikembalikan - Jangan pernah mengirim
image_idkesegmentdan jangan terus mengedit ID gambar sebelumnya.
Penanganan error
| HTTP / status | Penyebab umum | Penanganan |
|---|---|---|
| 400 sumber atau operasi tidak valid | Operasi salah; kedua sumber atau tidak ada sumber; tugas tidak dapat dipakai; URL tidak valid; atau image_id/image_index dikirim ke segment | Pilih tepat satu sumber valid. Untuk unggahan, kirim satu URL HTTP(S) publik dengan cache_only=true |
| 400 pilihan tidak valid | Prompt kosong, pilihan tidak ada, atau poligon, kotak, indeks tidak valid | Validasi prompt dan pilihan sebelum mengirim |
| 400 opsi tidak didukung | claim_asset, n, format, ukuran, atau stream tidak valid | Hapus field tidak didukung dan gunakan output URL |
| 401 / 403 | Key tidak valid atau izin model tidak ada | Periksa key server dan akses akun |
| 402 | Saldo tidak cukup | Minta top up sebelum retry |
| 409 | Permintaan idempoten sedang berjalan, berubah, atau tidak pasti | Ikuti respons; jangan ganti key otomatis |
| 429 / 5xx | Rate limit atau gangguan sementara | Ikuti Retry-After dan lakukan backoff terbatas |
| failed / task_failed | Eksekusi asinkron gagal | Hentikan polling dan tampilkan data.error.message |
Penagihan
segmentgratis dan selesai dengancost=0sertacredits_cost=0, tetapi tetap memerlukan autentikasi dan input sumber valid.region_editberbayar. Gunakancostdancredits_costdari tugas selesai; jangan hard-code harga di frontend.- Jangan pernah mengirim field internal
billing_model_name.
Daftar periksa frontend
- Simpan API Key hanya di backend atau BFF.
- Kirim satu sumber ke
segment:source_task_idatauimage_urlsberisi satu URL publik. Jangan kirimimage_idatauimage_index. - Bersama
image_urls, tetapkancache_only=truedan hilangkancached_onlysertarefresh. - Gunakan
image_iddari segment untukregion_editdan sediakan minimal satu metode pilihan. - Gunakan
selection_regionsuntuk edit presisi;object_indiceshanya perkiraan kotak. - Selalu baca
mask_sizesebagai[height,width]dan tangani skala serta letterbox. - Gunakan ulang idempotency key asli untuk retry yang sama dan validasi URL serta
image_idbaru.