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
Camadas e edição de regiões do Grok Imagine 2.0 Ext
Use segment para obter camadas de objetos e máscaras precisas e edite polígonos, caixas ou objetos detectados com 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 e region_edit usam o endpoint assíncrono de imagens existente. Salve o task_id retornado e consulte Obter status da tarefa; a solicitação de criação não retorna diretamente as camadas ou imagens finais.Nunca exponha uma API Key no bundle do navegador, LocalStorage, URL ou logs do frontend. Chame a APIMart pelo backend ou BFF.
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_..." }]
}
Visão geral das operações
| Finalidade | Entrada principal | Resultado concluído | Cobrança |
|---|---|---|---|
segment: Detectar objetos e obter camadas, caixas e máscaras precisas | source_task_id ou image_urls com uma imagem enviada | image_id, image_url, objects | Grátis |
region_edit: Editar um polígono, retângulo ou objeto detectado | image_id, prompt, seleção | Nova URL e image_id | Cobrado por tarefa concluída |
task_id concluída ────────────┐
├→ segment → image_id + mask_rle
URL pública da imagem enviada┘ → selection_regions → region_edit → nova task_id + image_id
Escolha exatamente uma origem para
segment: source_task_id ou image_urls. Esses campos e image_id não são intercambiáveis; region_edit continua usando o ID do ativo retornado por segment. Para segmentar uma imagem editada, use o ID da tarefa region_edit concluída como novo source_task_id.Cabeçalhos da solicitação
UseAuthorization: Bearer <APIMART_API_KEY>, Content-Type: application/json e Accept: application/json.
Idempotency-Key é opcional e fortemente recomendado para solicitações region_edit pagas. Aceita de 1 a 191 caracteres ASCII visíveis; recomenda-se UUID. Use uma nova chave por operação lógica. Uma repetição de rede da mesma solicitação deve reutilizar a chave e o body originais. Se o resultado for indeterminado, não repita automaticamente com outra chave.
Fluxo de tarefa assíncrona
Uma criação bem-sucedida retorna HTTP200 e data[0].task_id. Consulte GET /v1/tasks/{task_id}?language=pt a cada 2 segundos, aumentando até 5 segundos, com limite total de 10 minutos. Interrompa a consulta anterior quando a imagem de origem mudar.
A consulta pode retornar HTTP
200 enquanto data.status é failed. Determine sempre o resultado por data.status e mostre data.error quando existir.segment
Parâmetros da solicitação
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
model | string | ✅ | Fixo em grok-imagine-2.0-ext |
operation | string | ✅ | Fixo em segment |
nsfw_check | boolean | — | Padrão: false.true: verificar a imagem de origem com omni-moderation-latest.false ou omitido: não enviar solicitação de moderação. |
source_task_id | string | Condicional | Tarefa Grok concluída de uma única imagem do usuário atual; incompatível com image_urls |
image_urls | string[] | Condicional | Exatamente uma URL HTTP(S) absoluta e acessível publicamente; incompatível com source_task_id. Envie imagens locais via POST /v1/uploads/images e use a url retornada |
include_mask_rle | boolean | — | Padrão: true; false omite máscaras RLE, mas ainda retorna o ID do ativo, índices e caixas |
cache_only | boolean | — | Padrão: false; deve ser true com image_urls; consulta apenas o cache de segmentação |
cached_only | boolean | — | Padrão: false; dica de cache upstream somente para origens de tarefa |
refresh | boolean | — | Padrão: false; ignora o cache somente para origens de tarefa; não usar no fluxo normal |
segment não precisa de prompt. Não envie image_id, image_index, billing_model_name, n, size ou response_format. Envie exatamente um entre source_task_id e image_urls. O modo de URL exige cache_only=true e não aceita cached_only nem refresh.
Exemplos de solicitação
- Usar ID da tarefa
- Usar imagem enviada
- Consultar cache da tarefa
{
"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 ou from_cache; não deduza um hit por cached.
Enviar uma imagem local
Envie primeiro o arquivo local e leia a URL pública na resposta:curl --request POST \
--url https://api.apimart.ai/v1/uploads/images \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/source.png'
url retornada como o único item de image_urls. A consulta, a resposta concluída e region_edit funcionam depois como com um ID de tarefa: leia result.image_id e objects, então envie a edição de seleção. As URLs enviadas são temporárias e mantidas por 72 horas por padrão.
image_urls aceita exatamente uma URL HTTP(S) absoluta e acessível publicamente. O modo de URL aceita somente cache_only=true; não envie também source_task_id, cached_only ou refresh.Resposta concluída
Emsegment, data.result contém diretamente o resultado da segmentação e não fica dentro de 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": "..." }
}]
}
}
}
| Campo | Descrição |
|---|---|
result.image_id | ID do ativo usado por region_edit |
result.image_url | URL HTTP(S) alinhada ao image_id |
objects[].index | Índice original do servidor; preserve para object_indices |
objects[].box_xyxy | Caixa de pixels da máscara [x1,y1,x2,y2] |
objects[].score | Confiança da detecção; pode ser null |
objects[].mask_size | Sempre [height,width]; não fixe dimensões |
objects[].mask_rle | COCO compressed RLE para contornos precisos |
objects[].mask_url | URL opcional da máscara; pode estar vazia |
mask_rle ou mask_url válido só permite edição aproximada por caixa.
Decodificar mask_rle
mask_rle.counts é uma string de contagens compactadas COCO, não Base64 nem zlib. Ela é expandida por colunas; o primeiro trecho é fundo e depois alterna primeiro plano e fundo.
O TypeScript abaixo converte para uma máscara binária por linhas adequada ao navegador:
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 para logs, análises, URLs ou relatórios de erro.
Converter máscaras em seleções precisas
interface SelectionBoundary { points: number[] }
interface SelectionRegion { outer: SelectionBoundary; holes?: SelectionBoundary[] }
0–1. Cada anel precisa de pelo menos 3 pontos distintos, área diferente de zero e não pode se cruzar. Mantenha no máximo 16 regiões maiores por camada e 400 pontos por anel.
mask_size é [height,width] e usa coordenadas da máscara original, não dimensões CSS. Com object-fit: contain, desconte as margens, escale pela área realmente desenhada e limite o resultado a 0–1.mask_url requer CORS. Defina crossOrigin = "anonymous" antes de src ou obtenha um Blob. Decodificar mask_rle diretamente evita essa dependência.
Editar uma região: region_edit
Parâmetros da solicitação
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
model | string | ✅ | Fixo em grok-imagine-2.0-ext |
operation | string | ✅ | region_edit |
nsfw_check | boolean | — | Padrão: false.true: verificar o prompt de edição e a imagem de entrada com omni-moderation-latest.false ou omitido: não enviar solicitação de moderação. |
image_id | string | ✅ | ID do ativo de origem; primeiro use o image_id de segment e depois o resultado de edição mais recente |
prompt | string | ✅ | Instrução não vazia descrevendo a alteração |
selection_regions | array | * | Polígonos normalizados em 0–1 com outer e holes opcionais; recomendado |
boxes | number[][] | * | Retângulos [x1,y1,x2,y2]; caixas em pixels exigem mask_size |
object_indices | integer[] | * | Valores originais de objects[].index; apenas aproximação por caixa |
mask_size | integer[] | * | Obrigatório para caixas em pixels; [height,width] com inteiros positivos |
selection_regions, boxes ou object_indices deve conter dados. A API aceita combinações, mas o frontend deve usar um método por solicitação.
Não envie
billing_model_name, size, aspect_ratio, source_aspect_ratio, source_size ou image_urls. Omita n ou use 1; omita claim_asset ou use false; omita response_format ou use url. Base64 e stream=true não são aceitos.Métodos de seleção
| Método | Origem da seleção | Precisão | Uso recomendado |
|---|---|---|---|
selection_regions | Polígonos do frontend | Precisa, incluindo furos | Edição de camada ou pincel em produção |
boxes | Retângulos do frontend | Aproximação por caixa | Ferramenta de caixa ou MVP |
object_indices | Índices originais de segment | Aproximação por caixa | Teste rápido de integração |
- Polígono preciso
- Caixa normalizada
- Caixa em pixels
- Índice do objeto
{
"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 pode ser uma lista plana ou pares aninhados. Cada valor deve ser finito e estar em 0–1; cada anel exige pelo menos 3 pares.{
"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. Não os substitua por índices de uma lista filtrada, ordenada ou agrupada no frontend.Resposta concluída
{
"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]. Em respostas antigas, associe url[0] a image_ids[0] somente quando os arrays tiverem o mesmo tamanho. Continue apenas após obter uma URL HTTP(S) e um novo image_id.
Use expires_at como referência de expiração; não fixe um número de horas. Baixe ou armazene ativos necessários a longo prazo.
Edição contínua
Após concluir uma edição, atualize juntos a URL exibida, o ID do ativo atual e o ID da tarefa de origem, e limpe camadas e consultas antigas.- Segmentar novamente: usar o ID desta tarefa
region_editcomosource_task_id - Editar novamente: usar o novo
image_idretornado - Nunca envie
image_idparasegmentnem continue editando o ID da imagem anterior.
Tratamento de erros
| HTTP / status | Causa comum | Tratamento |
|---|---|---|
| 400 origem ou operação inválida | Operação incorreta; ambas as origens ou nenhuma; tarefa inutilizável; URL inválida; ou image_id/image_index enviado a segment | Escolher exatamente uma origem válida. Para uploads, enviar uma URL HTTP(S) pública com cache_only=true |
| 400 seleção inválida | Prompt vazio, seleção ausente ou polígono, caixa ou índice inválido | Validar prompt e seleção antes de enviar |
| 400 opção não aceita | claim_asset, n, formato, tamanho ou streaming inválido | Remover campos não aceitos e usar saída URL |
| 401 / 403 | Chave inválida ou sem permissão do modelo | Verificar a chave do servidor e o acesso da conta |
| 402 | Saldo insuficiente | Solicitar recarga antes de tentar novamente |
| 409 | Solicitação idempotente em andamento, alterada ou indeterminada | Seguir a resposta e não trocar a chave automaticamente |
| 429 / 5xx | Limite ou falha temporária | Respeitar Retry-After e aplicar backoff limitado |
| failed / task_failed | Falha na execução assíncrona | Interromper a consulta e mostrar data.error.message |
Cobrança
segmenté gratuito e termina comcost=0ecredits_cost=0, mas exige autenticação e uma origem válida.region_edité pago. Usecostecredits_costda tarefa concluída; não fixe preços no frontend.- Nunca envie o campo interno
billing_model_name.
Checklist do frontend
- Manter a API Key somente no backend ou BFF.
- Enviar uma origem para
segment:source_task_idouimage_urlscom uma URL pública. Não enviarimage_idouimage_index. - Com
image_urls, definircache_only=truee omitircached_onlyerefresh. - Usar o
image_idde segment emregion_edite fornecer ao menos um método de seleção. - Usar
selection_regionspara edição precisa;object_indicesé apenas aproximação por caixa. - Sempre interpretar
mask_sizecomo[height,width]e compensar escala e margens. - Reutilizar a chave idempotente original no mesmo retry e validar a URL e o novo
image_id.