Takeat
Versão da documentação
CatálogoProdutos

Documentação

Gerenciar produtos

Crie, edite e controle a disponibilidade do cardápio por canal.

A Nova API V1.0 permite cadastrar e editar produtos do restaurante sem expor exclusão. Com OAuth, as operações de escrita exigem products:write; consultar um produto ou o catálogo exige products:read, e o menu usa menu:read. A sessão do restaurante também é aceita, sem escopos de integração, e só pode alterar produtos do restaurant_id assinado no token.

Para entender o efeito de cada alteração, consulte a Referência de campos do produto: preços por canal, promoções, esgotamento, venda por peso e padrões na criação.

Antes de começar

Use o access_token obtido pelo OAuth, não a chave tk_ diretamente. Nos exemplos, TAKEAT_API_URL é https://public-api.takeat.app, sem /v1 no final. Substitua os IDs pelos registros do seu restaurante.

Se a credencial OAuth permite mais de um restaurante, acrescente ?restaurant_id=85 à URL de cada chamada, usando o ID autorizado desejado. Com sessão de restaurante, o contexto vem do token; um restaurant_id conflitante é rejeitado. O restaurante não é escolhido pelo corpo JSON.

ObjetivoRotaEscopo OAuth
Listar categorias de produtosGET /v1/product-categoriesproducts:read
Consultar uma categoria de produtosGET /v1/product-categories/{categoryId}products:read
Criar uma categoria de produtosPOST /v1/product-categoriesproducts:write
Editar uma categoria de produtosPUT /v1/product-categories/{categoryId}products:write
Consultar categorias e produtos no formato legadoGET /v1/productsproducts:read
Consultar os campos atuais e a versão de um produtoGET /v1/products/{productId}products:read
Enviar uma imagemPOST /v1/filesproducts:write
Criar até 100 produtos atomicamentePOST /v1/products/bulkproducts:write
Criar um produtoPOST /v1/productsproducts:write
Editar campos, inclusive esgotamentoPUT /v1/products/{productId}products:write
Editar de 1 a 100 produtos atomicamentePUT /v1/products/bulkproducts:write
Alterar somente os canais de vendaPATCH /v1/products/{productId}/availabilityproducts:write
Consultar o menu e o preço efetivo de um canalGET /v1/menumenu:read

Teste também altera dados reais

tk_test_ identifica a credencial, mas não cria um banco sandbox. As chamadas abaixo modificam o cardápio real do restaurante autorizado.

Gerenciar categorias de produtos

As categorias de produtos têm rotas próprias em /v1/product-categories. Elas não são o mesmo recurso que as categorias de complementos. A listagem de categorias retorna somente os cadastros não removidos, ordenados por custom_order e depois por id, sem os produtos aninhados. Para consultar as categorias junto com seus produtos no formato legado, use GET /v1/products.

As rotas aceitam o access token OAuth com products:read para consulta e products:write para criação ou edição. Uma sessão autenticada do restaurante também é aceita. Se a credencial OAuth puder acessar mais de um restaurante, envie ?restaurant_id=<id> em cada chamada; a sessão de restaurante permanece limitada ao restaurante assinado no token.

Consultar categorias

GET /v1/product-categories?restaurant_id=85
Authorization: Bearer <access_token>

GET /v1/product-categories retorna um array de snapshots. Para consultar uma categoria específica, use GET /v1/product-categories/{categoryId}. Registros removidos, inexistentes ou pertencentes a outro restaurante respondem 404 product_category_not_found, sem revelar dados de outro restaurante.

Cada snapshot contém id, restaurant_id, brand_id, name, as disponibilidades por canal, is_exclusive, custom_order, preparation_time, created_at e updated_at:

CampoTipoEfeito
brand_idinteger positivoMarca do restaurante à qual a categoria pertence.
namestring de 1 a 255 caracteresNome da categoria.
availablebooleanDisponibilidade para venda presencial.
available_in_deliverybooleanDisponibilidade para delivery e retirada pelo fluxo de delivery.
available_in_self_servicebooleanDisponibilidade no autosserviço.
available_in_drive_thrubooleanDisponibilidade no drive-thru.
is_exclusivebooleanIndica que a categoria é exclusiva de um canal.
custom_orderinteger de 0 a 2147483647Posição da categoria no cardápio.
preparation_timeinteger de 0 a 2147483647 ou nullTempo de preparo configurado para a categoria.

As flags de disponibilidade são independentes. Desabilitar available não desabilita delivery, e desabilitar available_in_delivery não desabilita a venda presencial. No menu filtrado por disponibilidade, a categoria e o item também precisam estar disponíveis no canal consultado.

Criar uma categoria

Crie a categoria com name e brand_id. A marca deve existir, não estar removida e pertencer ao restaurante autorizado. Use a consulta de marcas para obter o ID; a categoria não aceita uma marca de outro restaurante.

POST /v1/product-categories?restaurant_id=85
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "name": "Hambúrgueres",
  "brand_id": 3,
  "available": true,
  "available_in_delivery": true,
  "available_in_self_service": false,
  "available_in_drive_thru": true,
  "custom_order": 100,
  "preparation_time": 15
}

POST retorna 201 com o snapshot da categoria criada. Os padrões quando os campos opcionais são omitidos são true para available, available_in_delivery e available_in_self_service, false para available_in_drive_thru e is_exclusive, 100 para custom_order e null para preparation_time. A criação sempre gera um cadastro manual, não gerenciado por integração.

Editar uma categoria

PUT /v1/product-categories/{categoryId} é parcial: campos omitidos permanecem inalterados. A marca não é editável; não envie brand_id para uma categoria existente. Para proteger uma edição baseada em uma leitura, copie o updated_at consultado para expected_updated_at:

PUT /v1/product-categories/10?restaurant_id=85
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "available": false,
  "available_in_delivery": true,
  "preparation_time": 20,
  "expected_updated_at": "2026-09-30T12:00:00.000Z"
}

O campo expected_updated_at é opcional, não é uma alteração por si só e deve ser o valor devolvido pela consulta. Se a categoria tiver mudado desde essa consulta, a API retorna 409 product_category_conflict; consulte novamente, revise a proposta e só então reenvie. Sem esse campo, a edição não faz a verificação otimista de versão.

Categorias gerenciadas por integração não podem ser alteradas. Isso inclui cadastros vinculados a iFood, Neemo, multistore ou com código de integração; essas tentativas retornam 400 invalid_product_category. A API também não expõe DELETE /v1/product-categories/{categoryId}. Imagens, horários, configurações de impressão, KDS e vínculos de produtos não são gerenciados por estas rotas.

Para criar ou editar categorias de complementos, use a gestão de categorias de complementos.

Enviar a imagem do produto

Faça upload antes de criar ou editar o produto. POST /v1/files exige products:write ou uma sessão de restaurante e aceita um único campo multipart file. Não defina Content-Type manualmente: o cliente gera o boundary.

curl -X POST "$TAKEAT_API_URL/v1/files?restaurant_id=85" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -F "file=@/caminho/burger.png"

Aceita JPEG, PNG e WebP de até 10 MiB e 25 megapixels. O servidor verifica o conteúdo real, rejeita animações, aplica a orientação da câmera e converte a imagem em WebP sem metadados, com dimensão máxima de 1600 pixels e miniatura com dimensão máxima de 400 pixels. SVG, GIF, PDF e outros arquivos são rejeitados.

A resposta 201 inclui id, name, path, url, thumbnail_url, content_type e size (bytes da imagem processada). Envie esse id como image_id em POST /v1/products, POST /v1/products/bulk, PUT /v1/products/{productId} ou PUT /v1/products/bulk.

{ "image_id": 123 }

Na edição, image_id: null remove a imagem; omitir o campo preserva a atual. A resposta do produto inclui image_id; o menu retorna a imagem e sua miniatura em presentation.image. Só é permitido associar imagens enviadas por este endpoint para o mesmo restaurante. IDs ausentes, de outro restaurante ou de arquivos genéricos retornam 404 product_image_not_found.

O upload sozinho não altera o produto. Se uma criação ou edição falhar, o arquivo continua disponível para uma nova tentativa. O upload não oferece exclusão de arquivos nem uma rota genérica de mídia. Storage sem configuração responde 503 image_upload_unavailable; falhas de persistência respondem 503 image_upload_failed. Arquivo grande demais recebe 413.

Criar vários produtos

POST /v1/products/bulk aceita um array de 1 a 100 objetos com os mesmos campos obrigatórios da criação individual. A resposta 201 é um array na ordem do pedido. Todas as criações ocorrem em uma transação serializável: uma categoria inválida, imagem não autorizada ou outro erro impede a criação do lote inteiro. Lotes separados são transações independentes.

Criar um produto

O produto deve apontar para uma categoria não removida do mesmo restaurante. Uma categoria indisponível não é removida: ela pode receber produtos, mas continuará oculta no menu filtrado por disponibilidade.

O produto não recebe brand_id diretamente: a marca vem da categoria. Ao alterar product_category_id, o produto passa a usar a marca da categoria de destino, além de ser reposicionado ao final dela.

curl -X POST "$TAKEAT_API_URL/v1/products" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Takeat Burger",
    "product_category_id": 10,
    "price": 28.00,
    "delivery_price": 31.00,
    "available": true,
    "available_in_delivery": true
  }'

Obrigatórios: name, product_category_id e price. Quando não informadas, as duas disponibilidades começam como true, sold_off, use_weight e has_starting_price como false, e charge_service_tax como true.

Editar um produto

Consulte GET /v1/products/{productId} para obter os campos editáveis e o updated_at atual. Produtos removidos ou de outro restaurante retornam 404.

PUT /v1/products/{productId} é parcial: envie somente os campos que devem mudar. Campos ausentes permanecem intactos; preços promocionais e de delivery aceitam null para remover o valor.

description também aceita null para limpar. Envie preços como números JSON (por exemplo, 34.90), embora a consulta os retorne como strings ("34.90"). Não envie campos somente de leitura, como restaurant_id, created_at e updated_at, no corpo de edição.

Na edição, price: 0 é permitido; valores negativos ou com mais de duas casas decimais são rejeitados. A criação continua exigindo price positivo. Salão e delivery são independentes: não altere os dois canais sem intenção explícita.

Opcionalmente envie expected_updated_at com o updated_at consultado. Se o produto mudou desde a consulta, a API responde 409 product_update_conflict. Consulte novamente e peça uma nova aprovação; não repita a escrita automaticamente.

curl -X PUT "$TAKEAT_API_URL/v1/products/42" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Takeat Burger Duplo", "price": 34.90 }'

Não existe DELETE /v1/products/{productId} nesta API.

Editar vários produtos

PUT /v1/products/bulk recebe um array diretamente no corpo, com 1 a 100 objetos. Cada objeto contém id e os campos parciais que devem mudar:

[
  { "id": 42, "price": 0, "expected_updated_at": "2026-08-26T14:00:00.000Z" },
  { "id": 43, "delivery_price": 0 }
]

IDs repetidos são rejeitados com 400 duplicate_product_ids, mesmo quando os objetos alteram campos diferentes. Um campo inválido, alteração vazia, produto/categoria inexistente ou versão desatualizada impede todo o lote. A operação é atômica e retorna um array de produtos na ordem recebida.

Para agentes de IA, mostre todos os valores atuais e propostos e aguarde a aprovação do operador antes da chamada. A API exige credenciais válidas, mas a aplicação integradora é responsável por obter essa aprovação humana.

Campos fiscais são enviados em fiscal_info como alterações parciais; null limpa um campo. O identificador interno fiscal_group_id não é exposto nem editável. As respostas incluem fiscal e o alias compatível fiscal_info; veja a explicação de cada atributo fiscal.

Alterar disponibilidade

Use a rota focada quando a alteração for somente de canal:

curl -X PATCH "$TAKEAT_API_URL/v1/products/42/availability" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "available": false,
    "available_in_delivery": true
  }'
CampoCanal
availableVenda presencial, balcão e consumo no local
available_in_deliveryDelivery e retirada pelo fluxo de delivery

Os campos são independentes e ao menos um deles deve ser enviado. Depois da alteração, GET /v1/menu?only_available=true passa a refletir o novo estado no canal correspondente.

Para sinalizar falta temporária, envie { "sold_off": true } no PUT individual ou em lote; sold_off não é aceito no PATCH /availability. O menu exclui esgotados com only_available=true. Com false, retorna availability.sold_out e o motivo em availability.resolved.reason. Horários e escolhas obrigatórias também afetam a elegibilidade. Confira as regras do menu.

Resposta

Criação, edição e disponibilidade retornam o produto atualizado. Valores monetários são strings com duas casas. Exemplo abreviado:

{
  "id": 42,
  "restaurant_id": 85,
  "product_category_id": 10,
  "name": "Takeat Burger Duplo",
  "price": "34.90",
  "delivery_price": "31.00",
  "available": false,
  "available_in_delivery": true,
  "created_at": "2026-08-26T12:00:00.000Z",
  "updated_at": "2026-08-26T14:00:00.000Z"
}

O produto e a categoria são sempre verificados contra o restaurante resolvido pela credencial. IDs de outro restaurante respondem 404, sem revelar que o registro existe.

Erros comuns

HTTP / keyComo resolver
400 por corpo inválidoConfira tipos, limite de duas casas decimais, campos aceitos e pelo menos uma alteração efetiva.
400 product_changes_requiredEnvie um campo editável; apenas id, expected_updated_at ou um objeto fiscal vazio não bastam.
400 duplicate_product_idsAgrupe as mudanças de cada produto em um único objeto do lote.
404 product_not_foundConfira o ID e o restaurante autorizado; o produto pode ter sido removido.
404 product_category_not_foundEscolha uma categoria não removida do mesmo restaurante.
409 product_update_conflictConsulte os valores atuais e revise a proposta antes de reenviar. No lote, nenhum produto foi alterado.

Se a escrita foi aceita, mas o produto não aparece ou o preço parece diferente, veja o guia de diagnóstico.

Consulte também Gerenciar complementos para editar opções, preços, fiscal e disponibilidade, individualmente ou em lote.

Criar e editar categorias de produtos

AçãoRotaEscopo OAuth
Listar categorias, inclusive vaziasGET /v1/product-categoriesproducts:read
Consultar uma categoriaGET /v1/product-categories/{categoryId}products:read
Criar categoriaPOST /v1/product-categoriesproducts:write
Editar categoria parcialmentePUT /v1/product-categories/{categoryId}products:write

Uma sessão autenticada de restaurante também é aceita. O isolamento segue o mesmo restaurant_id autorizado das rotas de produtos. Consulte GET /v1/brands para obter uma marca real do restaurante. name e brand_id são obrigatórios na criação; a marca de uma categoria existente não pode ser alterada.

POST /v1/product-categories?restaurant_id=85
Authorization: Bearer <access_token>
Content-Type: application/json

{"name":"Hambúrgueres especiais","brand_id":3,"custom_order":10,"available":true,"available_in_delivery":true}

Campos editáveis: name (1–255 caracteres), available, available_in_delivery, available_in_self_service, available_in_drive_thru, is_exclusive (booleanos), custom_order (inteiro não negativo) e preparation_time (inteiro não negativo ou null). Inteiros são limitados a 2147483647. preparation_time: null limpa o tempo de preparo; demais campos não aceitam null. Campos omitidos são preservados. As disponibilidades são independentes entre canais.

As respostas retornam o objeto da categoria com id, restaurant_id, brand_id, campos editáveis, created_at e updated_at. Campos internos de integração, multiloja e dados completos da marca não são expostos. Na edição, envie expected_updated_at devolvido pela consulta para proteger uma revisão. Uma revisão obsoleta recebe 409 product_category_conflict. Um corpo vazio ou apenas com expected_updated_at recebe 400.

Categorias inexistentes, excluídas ou de outro restaurante recebem o mesmo 404 product_category_not_found. Categorias gerenciadas por integração ou multiloja rejeitam edição com 409. Estas rotas não editam imagens, horários, configurações de integração ou vínculos de produtos, e não expõem exclusão. Para mover um produto, use product_category_id na edição do próprio produto; para criar produtos em uma nova categoria, aguarde a resposta da criação e use o id real retornado.

Categorias de complementos são recursos distintos e usam complements:read/write; consulte Gerenciar complementos.

Editar a ordem do cardápio

Use custom_order em PUT /v1/products/:productId ou em PUT /v1/products/bulk para ordenar produtos dentro de cada categoria. Para ordenar as categorias, use o campo já disponível em PUT /v1/product-categories/:categoryId. As escritas exigem products:write ou uma sessão verificada do restaurante; menu:read sozinho não autoriza edição.

O valor deve ser um inteiro entre 0 e 2147483647. Valores menores aparecem primeiro; produtos empatados usam o ID crescente. A ordem é compartilhada entre salão e delivery. Omitir o campo preserva a ordem, exceto ao mover para outra categoria: sem ordem explícita, o produto vai para o final da categoria de destino. Enviar product_category_id junto com custom_order define a categoria e a posição. A API não desloca nem renumera automaticamente os demais produtos.

Consulte o cardápio com only_available=false e sem busca para incluir produtos indisponíveis antes de calcular a sequência. Para categorias vazias, consulte GET /v1/product-categories. Leia os snapshots de produtos para obter updated_at e envie-o como expected_updated_at para detectar alterações concorrentes.

PUT /v1/products/bulk?restaurant_id=85
Authorization: Bearer <access_token>
Content-Type: application/json

[
  { "id": 102, "custom_order": 0, "expected_updated_at": "2026-10-27T12:00:00.000Z" },
  { "id": 101, "custom_order": 1, "expected_updated_at": "2026-10-27T12:00:00.000Z" }
]

Os IDs e horários são exemplos: substitua pelos snapshots atuais da loja. Cada lote aceita de 1 a 100 IDs distintos e é atômico. ID ausente ou de outra loja, versão desatualizada ou campo inválido impede a aplicação do lote inteiro. Conflitos de versão retornam 409; consulte novamente antes de reapresentar a edição. Vários lotes e edições de categorias não formam uma transação única. As respostas de consulta e escrita de produto incluem custom_order.

Depois da escrita, consulte novamente GET /v1/menu para obter a apresentação ordenada. Grupos de escolhas e opções de complementos não têm edição de ordem nessas rotas. As restrições existentes de categorias gerenciadas por integrações ou multilojas continuam valendo.

On this page