Perguntas do Mercado Livre via API: notificações, fila e resposta com /answers (Node.js)
Se você já integrou um sistema com o Mercado Livre, sabe que perguntas de compradores são um dos fluxos mais sensíveis ao tempo: quem pergunta normalmente está decidindo a compra naquele momento. Neste post vou mostrar como funciona o ciclo completo pela API oficial: receber a notificação de uma nov

a pergunta, buscar os detalhes, decidir a resposta e publicá-la. Tudo com base na documentação oficial em developers.mercadolivre.com.br, com exemplos em Node.js. Aviso logo de cara: a AppVerix está construindo um produto em cima desse fluxo (o AppVerix Responde). Falo dele só no final.
O resto do texto serve para qualquer pessoa que queira montar a própria integração. Sua aplicação assina o tópico questions no gerenciador de aplicativos do Mercado Livre e informa uma callback URL. Quando chega uma pergunta, o Mercado Livre faz um POST na sua callback com um aviso curto: o recurso (/questions/ID), não a pergunta inteira. Você confirma o recebimento com HTTP 200 imediatamente e coloca o aviso numa fila.
Um worker consulta GET /questions/$QUESTION_ID com o token do vendedor. O worker decide a resposta e chama POST /answers. Vamos por partes. questions Segundo a página Receba notificações, os tópicos são configurados no gerenciador de aplicativos, onde você criou sua aplicação.
Lá você informa a callback URL e marca os tópicos desejados. A lista inclui orders_v2, items, messages, questions e outros. A autorização do vendedor é feita por OAuth: o vendedor autoriza sua aplicação e você recebe um access_token para chamar a API em nome dele. Nada de pedir senha.
A notificação é leve. Ela diz o que mudou e você busca o resto. Um exemplo no formato da documentação: { "resource": "/questions/5036111111", "user_id": 123456789, "topic": "questions", "application_id": 2069392825111111, "attempts": 1, "sent": "2026-11-01T12:00:00.000Z", "received": "2026-11-01T12:00:00.000Z" } O campo importante é resource. O user_id indica de qual vendedor é a conta, o que importa se você atende várias lojas.
Esta é a parte que mais derruba integração. A documentação é explícita: O Mercado Livre envia um POST para a callback URL e espera um HTTP 200. Se não receber, considera a mensagem não entregue e tenta de novo. As novas tentativas acontecem durante 1 hora.
Depois disso, a notificação é descartada. A recomendação é retornar HTTP 200 em até 500 milissegundos. Integrações que falham nisso podem ter os tópicos desativados. Para volume alto, a própria documentação recomenda trabalhar com filas: confirmar na hora e só depois consultar a API.
Ou seja: nada de chamar a API, um LLM ou o banco de dados pesado dentro do handler do webhook. Um exemplo mínimo com Express: import express from "express"; import { enqueue } from "./queue.js"; // Redis, SQS, tabela no Postgres... o que você já usa const app = express(); app.use(express.json()); app.post("/ml/notifications", (req, res) => { const n = req.body; res.sendStatus(200); // confirma primeiro if (n?.topic === "questions" && n?.resource) { enqueue({ resource: n.resource, userId: n.user_id, receivedAt: Date.now(), }).catch((err) => console.error("falha ao enfileirar", err)); } }); app.listen(3000); Duas observações práticas: Idempotência. Como há retentativas, o mesmo resource pode chegar mais de uma vez.
Use o ID da pergunta como chave única na fila ou no banco. Notificações perdidas. Se seu servidor ficou fora do ar, existe o endpoint GET /missed_feeds?app_id=$APP_ID, que lista notificações que não receberam 200 após a última tentativa. Segundo a documentação, ele só guarda notificações de até 2 dias atrás, então vale rodar uma rotina de reconciliação.
curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://api.mercadolibre.com/missed_feeds?app_id=$APP_ID" Com o resource em mãos, o worker consulta a pergunta. A documentação de Perguntas e Respostas mostra a chamada: curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" \ https://api.mercadolibre.com/questions/3957150025 A resposta traz, entre outros campos, id, item_id, seller_id, text, status (UNANSWERED ou ANSWERED) e answer. A documentação também recomenda usar o parâmetro api_version=4 para receber a estrutura nova. Em Node (18+, com fetch nativo): const API = "https://api.mercadolibre.com"; async function getQuestion(resource, token) { const r = await fetch(`${API}${resource}?api_version=4`, { headers: { Authorization: `Bearer ${token}` }, }); if (!r.ok) throw new Error(`GET ${resource} -> ${r.status}`); return r.json(); } Antes de responder, confira se status ainda é UNANSWERED.
O vendedor pode ter respondido pelo app enquanto a mensagem estava na fila. Para montar uma boa resposta, você normalmente vai precisar também dos dados do anúncio (item_id): título, atributos, garantia e assim por diante. Para listar perguntas de um anúncio, existe GET /questions/search?item=$ITEM_ID. A resposta é um POST /answers com o question_id e o text: curl -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"question_id": 3957150025, "text": "Olá!
Sim, enviamos com nota fiscal."}' \ https://api.mercadolibre.com/answers Se der certo, o retorno mostra a pergunta com status: "ANSWERED" e answer.status: "ACTIVE". Em Node: async function answer(questionId, text, token) { const r = await fetch(`${API}/answers`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ question_id: questionId, text }), }); if (!r.ok) throw new Error(`POST /answers -> ${r.status} ${await r.text()}`); return r.json(); } async function handleJob(job) { const token = await getSellerToken(job.userId); // seu storage de OAuth (com refresh) const q = await getQuestion(job.resource, token); if (q.status !== "UNANSWERED") return; // já respondida const draft = await buildAnswer(q); // regras, templates ou IA if (!draft.confident) { await notifySeller(q); // deixa para um humano return; } await answer(q.id, draft.text, token); } O ponto de design mais importante está em buildAnswer: o que fazer quando você não tem certeza. Responder errado no Mercado Livre é pior do que demorar alguns minutos. Na prática, vale ter: Modo sugestão vs.
automático. Comece só sugerindo respostas para o vendedor aprovar. Libere o automático depois, e por tipo de pergunta. Respostas baseadas no anúncio.
Use só fatos que estão no anúncio ou nas regras da loja (prazo, garantia, nota fiscal). Se a informação não existe, não invente. Fallback humano. Pergunta ambígua, reclamação ou negociação vai para a pessoa.
Log de tudo. Guarde a pergunta, o contexto usado e a resposta enviada para revisar depois. [ ] Tópico questions assinado e callback URL pública com HTTPS [ ] Handler responde 200 antes de qualquer processamento (meta: < 500 ms) [ ] Fila com deduplicação pelo ID da pergunta [ ] Rotina de reconciliação com /missed_feeds (janela de 2 dias) [ ] Revalidar status antes de POST /answers [ ] Refresh do access_token funcionando [ ] Caminho claro para "não sei, manda para o humano" Nós, da AppVerix, estamos construindo o AppVerix Responde, que aplica exatamente esse fluxo para vendedores que não querem manter integração própria. A ideia: você conecta a conta pela conexão oficial do Mercado Livre (sem compartilhar senha), informa prazos, garantia e políticas da loja e escolhe se a IA responde sozinha ou só sugere a resposta para você aprovar.
Ela responde com base nos dados do anúncio e, quando não tem certeza, deixa a pergunta para você. Ele ainda não está disponível. Estamos na fase de lista de espera, com preço previsto a partir de R$99/mês e teste grátis no lançamento. Quem entrar na lista recebe condição especial de acesso antecipado.
Se tiver interesse, a lista está aqui: https://appverix.com/mercado-livre/ E se você preferir construir o seu, espero que este passo a passo ajude. Dúvidas e correções são bem-vindas nos comentários.
Key Takeaways
- •Tudo com base na documentação oficial em developers.mercadolivre.com.br, com exemplos em Node.js.
- •This story was reported by Dev.to, covering developments in the dev space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.
📖 Continue reading the full article:
Read Full Article on Dev.to →


