Changelog da API
Todas as mudanças na API pública, das mais recentes para as mais antigas.
Dentro de uma versão, as mudanças são aditivas (veja versionamento): novos endpoints, campos, valores de enum e códigos de erro podem aparecer a qualquer momento e são listados aqui. Qualquer mudança incompatível sai em uma nova versão ou com um período de descontinuação anunciado aqui antes.
2026-09-29: novos prefixos de token
Aditiva. Os tokens novos levam o prefixo do produto; os antigos continuam funcionando:
- Os tokens de API da loja agora começam com
mobi_st_(antesbod_). Os tokensbod_existentes são aceitos até serem rotacionados ou revogados; rotacionar um deles retorna um valormobi_st_. - Os refresh tokens agora começam com
mobi_rt_(antesbpr_). Um tokenbpr_ainda pode ser trocado emPOST /v1/auth/refresh, por ummobi_rt_.
Trate os tokens como opacos: não os valide pelo prefixo nem pelo tamanho.
2026-09-29: pergunte à documentação
Aditiva. Nova tag Help:
POST /docs/ask: responde uma pergunta com base na documentação, em streaming no formato de mensagens de UI do AI SDK (text/event-stream), com as páginas citadas como partessource-url. Público, sem token; 20 perguntas por hora por visitante,rate_limited(429) acima disso. O painel Perguntar à IA deste site usa o endpoint.
2026-09-29: planos, cobrança e configuração
Aditiva. O Mobiari agora é vendido em planos self-service; estes endpoints expõem a assinatura da organização.
- Nova tag
Billing:GET /billing/plans: os planos à venda, com preços (centavos de BRL) e limites. Público, sem token.GET /tenants/{tenant_id}/subscription: plano, status (trialing,active,past_due,suspended,canceled), fim do período de teste, período pago, a fatura em aberto e o uso em relação aos limites do plano.PUT /tenants/{tenant_id}/subscription: troca o plano ou o ciclo de cobrança (somente o dono;usage_exceeds_planquando a organização não caberia no plano).POST /tenants/{tenant_id}/subscription/cancel,.../resume,.../pay(emite ou devolve a fatura a pagar, com um Pix "copia e cola").GET /tenants/{tenant_id}/invoices: umaPagede faturas.
- Novo
GET /stores/{store_id}/onboarding: o checklist de configuração da loja (produtos, pagamentos, frete, marca, WhatsApp, equipe, domínio próprio, primeiro pedido), calculado a partir dos dados dela. POST /tenantsaceita umplan_codeopcional (o plano a experimentar). Uma nova organização começa com 14 dias de teste e usa por padrãoBRL,America/Sao_Pauloe o idioma de quem faz a chamada.- Novos códigos de erro, status 402:
plan_limit_reached(comlimit,max,used,planemdetails) emPOST /storesePOST /stores/{store_id}/invites;subscription_inactivenesses mesmos endpoints e no chat do assistente quando a assinatura está suspensa ou cancelada. GET /stores/{store_id}/assistant/usage:capagora é o limite mensal do plano por loja, em vez de um valor fixo de 500.- Temas da loja virtual: novo
routes.products_url(prefixo das páginas de produto), eshop.currencyé a moeda da loja (BRL), então| moneyimprimeR$ 19,90.
v1 (2026-10)
A API ganha uma versão, um formato único de erro, um formato único de lista
e sessões renováveis. Os caminhos sem versão continuam respondendo durante
a transição, mas com o novo comportamento: as mudanças abaixo afetam uma
integração existente, quer ela passe para /v1 ou não.
Migração
- Aponte seu cliente para
https://api.mobiari.com/v1e troque cada caminho movido pelo novo. - Tome decisões com base no
codedo erro, não no texto deerror; espere 422validation_failedonde você tratava 400. - Trate qualquer 2xx como sucesso: muitas criações agora respondem 201 e muitas ações respondem 204 sem corpo.
- Leia listas a partir do envelope
Page(data,next_cursor) e envieinclude_total=trueonde você exibe um total. - Envie um
Idempotency-Keynos POSTs que você repete, como pedidos, reembolsos e mensagens. - Se você faz login com senha, guarde o
refresh_tokene chamePOST /v1/auth/refreshquando o token de acesso expirar. Tokens de API da loja (bod_…) não precisam de mudança. - Aceite valores de enum que você não conhece: muitos campos de texto viraram enums nesta versão, e novos valores podem aparecer sem uma nova versão.
Caminho base com versão
- A API fica em
https://api.mobiari.com/v1. A Storefront API fica em/v1/storefront-api/.... - Os caminhos sem versão continuam respondendo, com o novo comportamento,
mais os cabeçalhos
Deprecation,Link: <…>; rel="successor-version"e, quando houver uma data definida,Sunset. Veja Descontinuação. - Um caminho desconhecido em
/v1retorna 404route_not_found. - Dois documentos OpenAPI descrevem a superfície documentada:
admin.jsonestorefront.json. A referência da API é gerada a partir deles.
Erros têm um code
- Toda resposta de erro agora é
{"error": "<message>", "code": "<stable_code>", "details"?: {...}}. codeé novo e estável: baseie suas decisões nele.errormantém a mensagem, então clientes que leemerrorcontinuam funcionando, mas o texto pode mudar.- Corpos de erro que usavam outros formatos (
{"message": …},{"ok": false, "message": …}, texto puro, códigos de status sem corpo) agora usam este. Campos extras que eles traziam foram movidos paradetails. - Falhas de validação são 422
validation_failed, com mensagens por campo emdetails.fields.
Veja Erros.
Um único envelope de lista: Page
- Listas retornam
{"data": [...], "has_more": bool, "next_cursor": string | null}, maistotalquando você enviainclude_total=true. - Isso substitui arrays simples e os envelopes específicos de cada
endpoint, como
{"orders": [...], "total", "limit", "offset"}e{"products": [...], "total", "page"}. - A paginação usa
limit(de 1 a 200, padrão 50) e umcursoropaco;offsetcontinua disponível para saltar para uma página, no lugar dos parâmetrospage. totalnão é mais calculado por padrão.
Veja Paginação.
Chaves de idempotência
- Novo: envie
Idempotency-Keyem um POST para tornar as repetições seguras. Repetições dentro de 24 horas retornam a resposta original comIdempotent-Replayed: true. - Novos códigos de erro: 409
idempotency_request_in_progress, 422idempotency_key_reused.
Veja Idempotência.
Limites de requisições
- Novo: cotas por chamador em janelas de um minuto (por padrão, 1200
requisições por minuto autenticadas e 300 anônimas), informadas em
RateLimit-Limit,RateLimit-RemainingeRateLimit-Reset. - Acima da cota: 429
rate_limitedcomRetry-After.
Veja Limites de requisições.
Sessões com refresh tokens
- Novo:
POST /v1/auth/loginretornatoken,refresh_token(bpr_…),expires_inetoken_type, ou um desafio de dois fatores, diferenciados porstatus. Ele substituiPOST /login, cujo token durava 24 horas e não podia ser renovado. - Novo:
POST /v1/auth/refreshtroca um refresh token por um novo par. Os refresh tokens são rotacionados a cada uso; reutilizar um deles revoga a sessão inteira (401refresh_token_reused). - Novo:
POST /v1/auth/logout,GET /v1/me/sessionseDELETE /v1/me/sessions/{session_id}. - Os tokens de API da loja (
bod_…) não mudaram.
Veja Autenticação.
Sem mudanças
- Payloads e assinaturas dos webhooks enviados.
- Valores monetários em centavos inteiros, datas e horas em RFC 3339 UTC, ids UUID.
Mudanças por endpoint
O que muda em cada área, agrupado como na referência da API. Os caminhos são relativos à URL base e levam à página de referência correspondente.
- Caminhos movidos aparecem como
old → new(antigo → novo). Quando uma linha diz "o caminho antigo continua respondendo", o caminho antigo sem versão continua funcionando com o novo comportamento, mas não tem forma em/v1e não envia o cabeçalhoDeprecation: passe a usar o novo caminho. Pageindica uma lista que agora responde com o envelopePage; o formato antigo aparece em seguida quando não era um array simples.- Em todas as áreas, falhas de validação que eram 400 (muitas vezes em
texto puro) agora são 422
validation_failed. Só as demais mudanças estão listadas.
Autenticação
POST /register→POST /auth/register, responde 201. O caminho antigo continua respondendo.POST /login→POST /auth/login. O caminho antigo continua respondendo, com a nova resposta.- O login responde
{"status": "authenticated" | "two_factor_required", ...}e acrescentarefresh_token,token_type,expires_in,refresh_token_expires_inesession_id. - E-mail ou senha incorretos: 401
invalid_credentials(era 400 em texto puro). POST /verify-totp→POST /auth/2fa/totp/verify. O caminho antigo continua respondendo. Ele aceita apenas um token de desafio de login (401invalid_challenge) e não falha mais com 500 quando recebe um token inválido.- Erros de dois fatores e de código de uso único são 401 ou 400 com códigos
como
invalid_code,no_pending_codeetoo_many_attempts(enviar código, verificar código). - Um token de acesso cuja sessão foi revogada é recusado. Desativar um usuário revoga todas as sessões dele.
POST /auth/refresh: repetir a chamada com o refresh token anterior em até 30 segundos, enquanto o substituto ainda não foi usado, emite um novo par em vez de encerrar a sessão.- O refresh token de uma sessão encerrada de propósito (logout, revogação
de dispositivo, troca de senha) gera 401
invalid_refresh_token, nãorefresh_token_reused.
Minha conta
GET /totp-setup→GET /me/2fa/totp/setup. O caminho antigo continua respondendo.POST /enable-totp→POST /me/2fa/totp/enable. O caminho antigo continua respondendo.- 204 sem corpo (era texto ou
{"status": ...}): ativar TOTP, desativar TOTP, confirmar 2FA por WhatsApp, desativar 2FA por WhatsApp, trocar senha. - Ativar o TOTP duas vezes gera 409
totp_already_enabled; uma senha atual incorreta gera 400incorrect_password. PATCH /me:localeaceita apenaspt-BRouen-US; outros valores são rejeitados (antes eram convertidos).- Trocar a senha encerra todas as outras sessões.
Organizações
GET /tenants:Page.POST /tenantsresponde 201; um nome duplicado gera 409slug_taken.- Segurança: ler e atualizar uma organização exige a permissão naquela organização, não em qualquer loja da qual você faça parte.
Lojas
GET /stores:Page.POST /storesresponde 201; ele verifica a permissão na organização de destino (403missing_permission) e um nome duplicado gera 409slug_taken.PATCH /stores/{store_id}/settings: valores inválidos geram 422validation_failed(eram 400).
Equipe
Page:GET /users, membros, convites, papéis, papéis de um usuário, auditoria de papéis.- Segurança:
GET /userslista apenas os usuários das suas equipes (antes listava todos os usuários da plataforma). - 204 sem corpo: remover membro, cancelar convite.
- 409 com código: remover o dono (
cannot_remove_owner), excluir um papel do sistema (system_role), alterar os papéis do dono (owner_roles_locked). - Segurança: aceitar um convite para
um e-mail que já tem conta exige a senha dessa conta
(401
invalid_credentials); uma conta com 2FA não recebe sessão a partir de um convite.
Tokens de API
GET /stores/{store_id}/api-tokens:Page.- Segurança: rotacionar o
token de outro usuário gera 403
not_token_owner(antes retornava o segredo desse token).
Webhooks
/webhook-events→GETePOST /stores/{store_id}/webhooks/{webhook_id}/events,DELETE .../events/{event}. O caminho antigo continua respondendo.Page: webhooks, entregas, eventos do webhook.POST /stores/{store_id}/webhooksresponde 201.- Segurança:
DELETEverifica se o webhook pertence à loja do caminho.
Eventos
GET /stores/{store_id}/events:Page(era{events, total, limit, offset}).
Auditoria
GET /stores/{store_id}/audit:Pagede eventos (era{events, actions}). A lista de ações foi movida paraGET /stores/{store_id}/audit/actions.- O log de auditoria estava sempre vazio (um erro de consulta); agora ele retorna os registros.
Endereços
GET /places/autocomplete:Page.
Produtos
/product-variants→/stores/{store_id}/products/{product_id}/variantse/stores/{store_id}/variants/{variant_id}. O caminho antigo continua respondendo./product-variants/{id}/optionse/variant-options→/stores/{store_id}/variants/{variant_id}/options. Os caminhos antigos continuam respondendo./option-groups→/stores/{store_id}/products/{product_id}/option-groupse/stores/{store_id}/option-groups/{option_group_id}. O caminho antigo continua respondendo./option-values→/stores/{store_id}/option-groups/{option_group_id}/valuese/stores/{store_id}/option-values/{option_value_id}. O caminho antigo continua respondendo.GET /stores/{store_id}/products:Page(era{products, total, page, limit});page,per_pageesort_orderdeixaram de existir.Page: variantes, grupos de opções (agora com seus valores), valores de opções, imagens, produtos sugeridos, redirecionamentos de slug, sugestões de especificações (era{values}).- O
statusdo produto é snake_case (draft,active,archived); a entrada com inicial maiúscula continua aceita. Ogroup_typeda opção é um enum. Os payloads de webhook mantêm a grafia antiga. - Obter, criar e atualizar retornam o produto completo; criar responde 201 (era um resumo com 6 campos). Um slug em conflito passa a ser tornado único (era um 500).
- 201 na criação de variantes, grupos de opções e valores de opções. Atribuir uma opção à variante retorna a variante com suas opções; definir sugestões responde 204.
- Novos códigos de erro:
product_not_found,variant_not_found,sku_taken,slug_taken,invalid_color,image_not_found; 409product_has_orders,variant_has_orders,variant_has_stock,option_group_in_use,option_value_in_use. - Excluir um produto remove as variantes dele (era um 500); um produto com pedidos é recusado.
nullexplícito limpa o código de barras, o preço "de", o custo e o prazo de produção de uma variante.- Especificações do produto: um
valor inválido gera 422
invalid_spec_value(era 400). - Atualizar um produto não descarta mais os campos de promoção, envio, rótulo personalizado e número personalizado.
- Segurança: produtos sugeridos, reordenação de variantes, edição de imagens e valores de opções de variantes são verificados em relação à loja e ao produto do caminho.
- Removido:
DELETE /dev/products, que apagava o catálogo de todas as lojas para qualquer usuário logado.
Categorias
GET /stores/{store_id}/categories:Page, com todas as categorias por padrão; filtre comparent_idouroot_only.- Criar responde 201 e exige
categories.write(eracategories.read); criar e atualizar não falham mais com 500. - Adicionar um produto a uma categoria
responde 204 (era
{message}). - Novos códigos de erro:
category_not_found,category_has_children.nullexplícito limpadescriptione a categoria pai. GET /taxonomy/search:Page(era{categories}), sem necessidade de token.GET /taxonomy/by-idretorna uma categoria ou 404taxonomy_category_not_found.
Coleções
GET /collection-products→GET /stores/{store_id}/collections/{collection_id}/products. O caminho antigo continua respondendo.Page: coleções, produtos da coleção (linhas{product_id, title, position}, antes eram ids), coleções de um produto (linhas de coleção, antes eram ids).- Criar responde 201;
adicionar um produto
responde 204 (era
{message}); ids desconhecidos geram 404collection_not_found.nullexplícito limpadescription. - Segurança: atualizar não consegue mais alterar a coleção de outra loja.
Feeds de produtos
/product-feeds,/product-feeds/{id}e/product-feeds/{id}/generate→/stores/{store_id}/product-feeds/.... Os caminhos antigos continuam respondendo./product-feed-overrides→/stores/{store_id}/product-feeds/{feed_id}/overrides. O caminho antigo continua respondendo.Page: feeds, substituições. As criações respondem 201.- O
channeldo feed é snake_case. Novos códigos de errofeed_not_found,override_not_found. - Segurança: substituições para o produto de outra loja são recusadas.
Arquivos
GET /tenants/{tenant_id}/files:Page(era{files, total, limit, offset}).Page: arquivos da pasta, busca, produtos vinculados.- Excluir responde 204 (era 200); criar uma pasta responde 201.
- Novos códigos de erro:
file_not_found,folder_not_found,folder_exists,file_not_image,invalid_image, 413file_too_large. nullexplícito tira um arquivo da pasta em que ele está.
Estoque
- As rotas que pertencem a uma loja passaram de
?store_id=ou de umstore_idno corpo para/stores/{store_id}/...:/inventory-locations,/stock,/stock/overview,/stock/export,/stock/movements,/stock/bulk-adjust,/stock/bulk-reorder,/reservations,/stock-counts. Os caminhos antigos continuam respondendo. /stock/levels/{id}→GET /stores/{store_id}/variants/{variant_id}/stock;/stock/history/{id}→.../stock/movements. Os caminhos antigos continuam respondendo./stock/adjuste/stock/transfer→POST .../variants/{variant_id}/stock/adjuste.../transfer;/stock/reorder→PUT .../stock/reorder(agora PUT). Os caminhos antigos continuam respondendo./stock-items,/component-inventory,/inventory-eventse/product-variants/{id}/set-stockficam apenas na raiz, sem documentação.Pageem todas as listas (eram arrays simples,{items, total, limit, offset},{events, total},{movements, ...}ou{levels}).- Uma contagem de estoque foi
achatada:
{count, items}→ os campos da contagem maisitems. - As criações respondem 201 com o recurso (eram
{id}); as atualizações retornam o recurso (eram 204). - Liberar e
consumir retornam a
reserva e o estoque (eram
{ok: true}). - Os filtros de movimentações
item_id,from,to→variant_id,created_after,created_before;created_até RFC 3339 (era epoch em milissegundos). reason,kindestatussão enums: um motivo desconhecido gera 422 (antes era gravado comocorrection).- Um ajuste negativo além do estoque disponível gera 409
insufficient_stock(antes era limitado); o código de transferênciainsufficient_availablevirouinsufficient_stock. - Escritas de estoque geram 409
logical_stock_readonlyem kits e 409inventory_managed_externallyem lojas cujo estoque é controlado por um ERP (a menos que se useforce). - O endereço de um local de estoque é texto puro (era codificado em JSON).
- Segurança:
/stock-itemse/component-inventorylistavam o estoque de todas as lojas; ajustes e contagens aceitavam variantes e locais de outras lojas. Agora os dois ficam restritos à loja.
Compras
/suppliers,/purchase-orderse/stock/reorder-draft→/stores/{store_id}/suppliers,/stores/{store_id}/purchase-orders,/stores/{store_id}/stock/reorder-draft. Os caminhos antigos continuam respondendo.Pagenas listas; as criações respondem 201 com o recurso.- Um pedido de compra foi
achatado:
{order, lines, receipts}→ os campos do pedido maislinesereceipts. - Segurança: pedidos de compra, recebimentos e rascunhos de reposição recusam fornecedores e variantes de outras lojas.
Produção
/componentse/build-jobs→/stores/{store_id}/components,/stores/{store_id}/build-jobs. Os caminhos antigos continuam respondendo./product-variants/{id}/components→/stores/{store_id}/kits/{variant_id}/bom. O caminho antigo continua respondendo.Pagenas listas; as criações respondem 201 com o recurso.- Segurança: a criação de componentes e as linhas da lista de materiais recusam variantes de outras lojas.
Caixas de envio
/shipping-boxes→/stores/{store_id}/shipping-boxes. O caminho antigo continua respondendo./product-variants/{id}/shipping-boxes→/stores/{store_id}/variants/{variant_id}/shipping-boxes. O caminho antigo continua respondendo.- As dimensões das caixas são números (eram strings decimais).
- Segurança: as caixas de uma variante recusam a caixa de outra loja.
Integrações
- Logs de sincronização do ERP:
Page(era{logs}) e legíveis apenas na própria loja. - Um provedor de ERP não suportado gera 422
unsupported_erp_provider(era 400); um token ausente geraprovider_token_missing. - Segurança: criar ou atualizar um provedor de ERP mascara os segredos dele (antes eram devolvidos na resposta).
Pedidos
GET /stores/{store_id}/orders: semprePage(era um array simples ou{orders, total, limit, offset}).statusé um enum (valores desconhecidos geram 400).- As linhas da lista deixam de trazer
freight_quote_id,freight_snapshot_json,freight_external_order_codee os campos de NF-e; leia esses dados no pedido. - Obter,
criar e
alterar o status retornam o
pedido completo (envios, reembolsos,
refundable_cents,allowed_status_transitions, ...); criar responde 201. PATCH .../statusaplica o ciclo de vida: 409invalid_status_transition.shipped,delivered,confirmedeprocessingnão são mais aceitos (422); o códigostatus_not_settabledeixou de existir.POST .../orders/manualresponde 201. Os erros trazem códigos: 422invalid_manual_discount,invalid_shipping,invalid_postal_code,pix_intent_failed; 404variant_not_found; 409insufficient_stock,insufficient_component_stock(campos extras foram movidos paradetails)./order-item-adjustments→/stores/{store_id}/orders/{order_id}/adjustments. O caminho antigo foi removido (sempre falhava com 500).- Removidos:
/fulfillmentse/fulfillments/{id}(sempre falhavam com 500). - Segurança:
POST /ordersrecusa variantes, clientes e canais de venda de outras lojas; uma mudança de status verifica a loja antes de liberar estoque.
Carrinhos
GET /stores/{store_id}/carts:Page;statusé um enum e as linhas ganhamkind.GET .../carts/{cart_id}retorna os campos do carrinho comitems(era{cart, items}).
Orçamentos
GET /stores/{store_id}/quotes:Page(era{quotes}, limitado a 200).- O
statusdo orçamento éopen,expiredouconverted(eraaberta,expirada,convertida). - Criar responde 201. Os erros
trazem códigos: 422
empty_quote,invalid_max_installments,invalid_discount; 409insufficient_stock; 404variant_not_found,customer_not_found,sales_channel_not_found. - Segurança: um orçamento recusa o cliente e o canal de venda de outra loja.
Envios
Page: envios de um pedido, itens não enviados, motivos de cancelamento de frete.- Os erros trazem códigos: 409
no_freight_order, 422nfe_requirede códigosfreight_*(422, 404 ou 502). - Cotar um envio recebe
invoice_amount_cents;invoice_amountestá descontinuado.
Pagamentos
POST .../orders/{order_id}/refundresponde 201 com o reembolso (era{ok, intent_id, ..., provider_response}).- Reembolsos:
amount_centsmenor que 1 gera 422; acima do saldo reembolsável gera 422refund_exceeds_refundable(antes era limitado sem aviso); sem pagamento aprovado gera 409no_refundable_payment. - Pedidos reembolsados são marcados como
refundedoupartially_refunded; o status do pagamento ganhapartially_refunded. - O seu
Idempotency-Keyem um reembolso é repassado ao Mercado Pago. GET /stores/{store_id}/payment-providers:Page.- Criar ou
atualizar um provedor
mascara os segredos dele; um provedor duplicado gera 409
payment_provider_exists. - Segurança:
GET /payment-providers?store_id=continua respondendo na raiz, mas mascara os segredos (antes os expunha) e exige a permissão de gerenciamento. - Removidos (sempre falhavam com 500):
/refunds(vejaGET /stores/{store_id}/refunds),/payments,/payments/{id}/status,POST /payment-providers. - Removido: o
/webhooks/paymentssem assinatura. Os webhooks dos gateways de pagamento não são servidos em/v1.
Frete
- Provedores de frete:
Page; um provedor duplicado gera 409freight_provider_exists; os erros de tipos de carga trazem códigos. - Segurança: criar ou atualizar um provedor mascara os segredos dele (os tokens das transportadoras eram devolvidos na resposta).
- Zonas de entrega:
Page; criar responde 201 com a zona (era{id}); atualizar responde 200 com a zona (era 204).
Locais
GET /stores/{store_id}/locations:Page.- 409
location_slug_takenpara um slug duplicado; 409location_in_useao excluir.
Descontos
/discount-codes,/discount-codes/{id}e/discount-codes/validate→/stores/{store_id}/discount-codes/...;store_idsai do corpo e da query. Os caminhos antigos continuam respondendo.- Códigos de desconto:
Page; criar responde 201;expires_até uma data e hora (entrada inválida gera 422, antes era um erro de servidor); 409discount_code_exists,discount_code_in_use. - Validar responde
discount_type: null(era"unknown") e um enumreason. - Descontos automáticos:
Page;kindecondition_payment_methodsão enums. nullexplícito limpa campos anuláveis na atualização, tanto de códigos quanto de descontos automáticos.
Canais de venda
/sales-channelse/sales-channels/{id}→/stores/{store_id}/sales-channels/.... Os caminhos antigos continuam respondendo.Page; criar responde 201;channel_typeé um enum.- Códigos 409:
web_channel_exists,web_channel_protected(era um 409 sem código),sales_channel_in_use. - Gerar chave de API
responde
{key, prefix}.
Avaliações
GET /stores/{store_id}/reviews:Page(era{items, total, pending_count}).PATCH .../reviews/{review_id}exigestatus(um enum; caso contrário, 422).
Clientes
GET /stores/{store_id}/customers:Page(era{customers, total, page, per_page, vip_threshold_cents});pageeper_pagedeixaram de existir;lifecycleé um filtro enum.- A busca de clientes também encontra nome completo, empresa, documento e dígitos do telefone.
GET .../customers/{customer_id}deixa de trazerrecent_orders;orderscontém os 50 mais recentes.- Criar responde 201; um
e-mail duplicado gera 409
customer_email_exists; ids desconhecidos geram 404customer_not_found. - Interações:
Page; 404 para um cliente de outra loja. /customer-addressese/customer-addresses/{id}foram removidos (falhavam em todas as chamadas); useGET .../customers/{customer_id}/addresses(Page).Page: linha do tempo (era{events}), duplicados (era{groups}).- Mesclar responde
{into, removed, tables}(semok); mesclar um cliente com ele mesmo gera 422same_customer. - Apagar dados responde
{erased, skipped}(semok). - Os endpoints de CRM (grafo, consentimento, mesclagem, linha do tempo,
duplicados, exportação, remoção de dados) respondem 403
missing_permission(era um 403 vazio). - A atividade de e-mail
de um cliente desconhecido gera 404 (era
{summary: null, events: []}).
Conversas
GET /stores/{store_id}/conversations:Page(era{conversations, counts}); as contagens foram movidas paraGET .../conversations/counts.- Na lista,
q→searchechannel→channel_kind;status,priorityesortsão enums (allnão é mais aceito); as conversas abertas não aparecem mais primeiro. - Mensagens:
Page, das mais recentes para as mais antigas;beforerecebe um id de mensagem (era um timestamp). - Enviar uma mensagem
responde 201; 422
empty_message,message_too_long,whatsapp_window_closed(eram 400 ou uma falha posterior). - Notas respondem 201; excluir uma nota desconhecida gera 404 (era 204).
- Ticket de socket
responde 201
{ticket, expires_in}. - Atualização em massa
responde
{updated}(semok); uma ação ou um valor desconhecido gera 422. GET .../cartretorna o carrinho ou 404no_cart(era{cart}); os endpoints de itens retornam o carrinho (eram{cart}ou{cart, conversation}).PUT .../cart/customerretorna apenas o estado; reiniciar responde 204; enviar e PIX respondem 201.- Os erros do carrinho trazem códigos:
no_cart,empty_cart,insufficient_stock,variant_unavailable,missing_info,checkout_failed,pix_failed,freight_quote_failed,freight_option_invalid. - Busca no carrinho:
q→search;Page(era{variants}). - Uma mensagem de WhatsApp aceita pela Meta fica como
sent(eradelivered). - Segurança:
PATCHrecusa o cliente de outra loja e responsáveis fora da equipe da loja (422); os eventos de digitação ficam limitados às conversas da loja.
Configurações de conversas
Page: canais, respostas prontas. As criações respondem 201.- Excluir um canal ou uma resposta pronta desconhecida gera 404 (era 204).
GETePUT .../conversations-aiusam configurações do bot em formato plano (era{settings, flags}).
Base de conhecimento
Page: coleções, artigos;q→search.- As criações respondem 201; excluir uma coleção ou um artigo desconhecido gera 404 (era 204).
- Segurança: um artigo recusa a coleção de outra loja.
Page: modelos, campanhas, destinatários da campanha.- Segmentos:
Page(era{segments, fields}); os campos foram movidos paraGET .../email/segments/fields. - Membros do segmento:
Page(era{count, members}, limitado a 500). Page: formulários (era{forms}), produtos (era{products}).- Inscrições em produtos:
Page(era{summary, subscriptions}); as contagens foram movidas para.../summary. - O envio de teste do modelo
responde 204 e falha com 502
email_send_failed(era{ok}). - Enviar campanha responde 202 com a campanha; cancelar responde 200 com ela.
provider,inbox_mode,modeematchsão enums: valores desconhecidos geram 422 (antes eram ignorados).- Novos códigos 409:
broadcast_in_flight,broadcast_sending,broadcast_not_sendable,broadcast_not_cancellable,email_form_slug_taken. - Novos códigos 422:
no_unopened_recipients,csv_missing_file,csv_empty,csv_missing_email_column. Recursos do assistente: 503assistant_unavailable, 502assistant_error. - Excluir um modelo, formulário ou segmento desconhecido gera 404 (era 204); uma campanha desconhecida gera 404 (era 409).
- Cadastros por formulário e importações de CSV de e-mails novos se perdiam sem aviso; agora são gravados.
- Segurança: campanhas recusam o modelo de outra loja, e formulários recusam o modelo de boas-vindas de outra loja.
- A exportação de segmento em CSV neutraliza fórmulas de planilha.
E-mail transacional
GET .../email-templates:Page(era um array simples).- Os envios de teste
e de teste das configurações
respondem 204 e falham com 502
email_send_failed(eram 200{ok}, 422{ok: false}ou 502{error: "send_failed"}). - Restaurar um evento desconhecido gera 404.
Entregabilidade de e-mail
Page: domínios (era{domains, region}), supressões (era{suppressions}).- Adicionar um domínio
responde 201; 409
email_domain_taken; 502ses_error. - Adicionar uma supressão responde 201 com o registro (era 204).
- Excluir um domínio ou uma supressão desconhecida gera 404.
Anúncios
- Públicos:
Page(era{audiences, meta_configured}); a flag foi movida paraGET .../ads/connection. - Criar responde 201 com o
público (era
{id, name, status}); sincronizar retorna o público (era{ok, count}) e falha com 502meta_sync_failed. - Excluir um público desconhecido gera 404.
- Segurança: os erros de desempenho não incluem mais o token de acesso da Meta.
Automações
Page: workflows, execuções de um workflow, versões, segredos.- Execuções da loja:
Page(era{runs, total, limit, offset}). - Disparar e
tentar de novo respondem
202 com a execução (eram
{run_id}). - Salvar um segredo
retorna o resumo dele (era
{name}). kinde ostatusque pode ser definido são enums (valores desconhecidos geram 422, antes eram 400).- Publicar com erros gera 422
workflow_invalidcomdetails.problems(era{problems}). - Novos códigos: 409
workflow_not_published(retomar),run_not_active(cancelar),run_active(tentar de novo),run_not_awaiting_approval(aprovação); 422run_not_retryable. GET .../runs/{run_id}gera 404 para uma execução de outro workflow.- Restaurar uma versão funciona (antes sempre falhava com 500).
- Segurança: disparar e
testar nó recusam o
customer_idde outra loja (422).
Assistente
/assistant/chat,/assistant/conversations(lista),/assistant/prefs,/assistant/usage,/assistant/actions,/assistant/actions/{id}/undo,/assistant/phones,/assistant/phones/verify-starte/assistant/phones/verify-complete→/stores/{store_id}/assistant/.... Os caminhos antigos continuam respondendo.store_idsai do corpo do chat.Page: conversas (?search=;?q=continua aceito), ações (antes eram as 100 mais recentes), telefones.- 429
assistant_cap_reached(era texto puro); 503assistant_unavailable; 403not_a_memberoumissing_permission. - Desfazer: 409
action_already_undone, 422undo_not_supported(eram texto). - Renomear uma conversa retorna a conversa (era 204); parar sempre responde 204 (era 202 quando nada estava em execução).
- Iniciar verificação
responde
{phone_e164, expires_in_seconds}e falha com 502whatsapp_send_failed(era 200{ok: false, message}). - Concluir verificação
retorna o telefone vinculado (era
{verified: true}); um código incorreto gera 422invalid_verification_code(era 400).
Notificações
Page: canais, logs e caixa de entrada (eram arrays simples limitados a 200 ou 100; a caixa de entrada aceita?unread=).- Inscrições em alertas:
Page(era{subscriptions}). - O teste de canal
responde 204 (era um 200 vazio) e falha com 502
notification_send_failed(era texto puro). PUT .../alert-subscriptions/{user_id}retorna a inscrição (era{ok: true}); 404 para quem não é membro; eventos desconhecidos geram 422 (antes eram descartados).channel_type, os eventos de alerta e os tipos de canal de alerta são enums (valores desconhecidos geram 422); destinos de alerta vazios geram 422 (antes eram ignorados).- Marcar como lido um log desconhecido gera 404 (era 204).
- Segurança: os segredos dos canais aparecem como
"__stored__"(antes eram retornados paramarketing.read); enviar esse valor de volta mantém o segredo armazenado.
Marca
- Os erros trazem códigos (eram texto puro ou status sem corpo): 503
assistant_unavailable; 422brand_sources_missing,brand_system_missing,file_missing,invalid_package,invalid_asset; 404brand_job_not_found; 403missing_permission. - Exportar sem um sistema de
marca gera 404
brand_system_missing. - O upload de asset responde 201 (era 200).
- Registros de jobs:
kindestatussão enums;started_até um timestamp;already_runningé omitido quando é falso. PUT .../brand-kitresponde{kit, font_presets}, como oGET(era{kit}); importar falha com 422brand_import_failed.
Loja virtual
GET /stores/{store_id}/pages:Page(era um array simples); criar responde 201 (era 200).- Páginas: um slug duplicado gera 409
page_slug_taken; campos em branco ou longos demais geram 422 (eram 500). - Segurança: as páginas exigem
cms.readoucms.write(qualquer usuário logado conseguia ler e editar as páginas de qualquer loja). - Deploys:
Page(eram os 20 mais recentes em um array simples);statusetriggered_bysão enums. - Promover: 409
deployment_not_readyoustorefront_repo_not_connected(eram texto puro). POST /preview-auth/grant:expires_até RFC 3339 (era um timestamp Unix).- Domínios:
Page; adicionar responde 201 e não falha mais com 500; 422invalid_hostnameoureserved_suffix(eram 400). - Definir como domínio principal
um domínio não verificado gera 409
domain_not_verified. - Repositórios do GitHub:
Page.
Conteúdo
Page: coleções do CMS, documentos do CMS.
Análises
GET /dashboard/stats?store_id=→GET /stores/{store_id}/dashboard/stats;GET /dashboard/attention?store_id=→GET /stores/{store_id}/dashboard/attention. Os caminhos antigos continuam respondendo.- Estatísticas do painel:
revenue_this_month(um float) →revenue_this_month_cents, que por sua vez agora está descontinuado em favor derevenue_centserevenue_change_pct. - A receita do painel conta apenas pedidos pagos:
revenue_seriesnão inclui mais pedidos não pagos. - Os dias do painel seguem o fuso horário da loja (retornado como
timezone):7d,30de90dsão dias locais completos terminando hoje. - As estatísticas do painel e todos os relatórios de rastreamento
respondem 500 em caso de erro no banco de dados (antes retornavam zeros
ou listas vazias); o
PATCHda configuração de rastreamento não informa mais sucesso quando a gravação falhou. Page: páginas mais acessadas, principais origens, principais eventos (eram arrays simples com?limitde até 200).- Eventos recentes:
Pagecom cursor (era um array simples paginado por?before=). - Visitantes:
Page; a busca é?search=(?q=continua aceito). A lista estava sempre vazia (um erro de consulta); agora ela retorna os visitantes. - Conversões:
Page(era{deliveries, total, limit, offset});capi_meta_statusegoogle_ads_statussão enums (sending,sent,failed,skipped), e o motivo de ignorar foi movido paragoogle_ads_skip_reason. - Insights:
touché um enum; valores desconhecidos geram 400 (antes eram lidos comolast_touch). - Um visitante desconhecido gera
404
visitor_not_found(era um 200 vazio). - Reenviar: 422
order_not_captured(era{"error": "not_captured", ...}). - Sincronização do catálogo:
422
meta_catalog_not_configured, 502meta_catalog_error;resulténullquando nada foi enviado (era o texto"no active variants").
Storefront API
- Os endpoints para compradores mantêm caminhos, requisições e respostas;
os temas publicados continuam funcionando sem mudanças.
/v1também responde nos domínios das lojas. - Segurança:
POST /storefront/ordersaceita apenas produtos e variantes da própria loja do canal. - O checkout de tema desativado
POST /storefront-api/{store_slug}/checkout(sempre 410) não é servido em/v1.