Documentação · API e webhooks

API e webhooks — conecte a Craft ao seu CRM ou site

Como controlar a Craft com requisições autenticadas por chave e receber no seu próprio servidor eventos sobre novos contatos, cliques em botões, pagamentos e posts.

Atualizado: 15 de outubro de 2026

Você pode conectar a Craft ao seu CRM, ao site de um cliente ou a qualquer serviço seu. Tudo o que o conector MCP faz está disponível como uma requisição HTTPS simples com uma chave: funis, contatos, disparos, posts, carrosséis, imagens. Os webhooks funcionam no sentido contrário: a Craft envia um evento para o seu servidor quando aparece um novo contato, alguém clica num botão, atinge a meta de um funil, paga, ou um post é publicado.

Como funciona#

  • Na Craft, você cria uma chave e escolhe o que ela pode fazer: só ler, ou trabalhar com funis, contatos, disparos, posts e assim por diante.
  • Seu servidor envia uma requisição para https://craftopen.space/api/v1/tools/<method> com a chave num cabeçalho. Os parâmetros do método vão no corpo JSON da requisição.
  • A Craft executa o método na sua conta — exatamente como se você fizesse no site ou pedisse à sua IA pelo conector MCP, com as mesmas verificações e limites.
  • Para eventos, você adiciona um webhook — o endereço do seu servidor. A Craft envia para lá uma requisição assinada e tenta de novo se o seu servidor não responder.

O que você precisa#

  • Qualquer plano: chaves e webhooks podem ser criados em todos os planos, inclusive no gratuito.
  • Um servidor ou serviço capaz de enviar e receber requisições HTTPS: seu próprio código, Make, n8n, Zapier ou um CRM com webhooks de entrada.

Passo 1. Crie uma chave#

Menu do perfil → API e webhooks (ou Configurações → API e webhooks) → Nova chave.

  1. Dê à chave um nome que você vá reconhecer depois: "HubSpot", "Site do cliente".
  2. Escolha o que a chave pode fazer. Por padrão, uma chave nova só pode ler. Todo o resto é ativado com caixas de seleção: funis, contatos, disparos, posts, conteúdo, Fábrica de conteúdo, contas. "Tudo" abre todas as capacidades, inclusive as adicionadas depois.
  3. Escolha como a chave publica posts e disparos: - Só rascunhos — tudo é salvo como rascunho e você mesmo envia na Craft; - Agendado — no mínimo em 10 minutos, para dar tempo de cancelar; - Na hora — publica e envia no momento da requisição.
  4. Defina o limite diário de gasto com imagens e quantos disparos por dia a chave pode enviar de um bot.
  5. Clique em Criar chave e copie na hora.

🔴 A chave é mostrada uma única vez. A Craft guarda só a impressão digital dela e não consegue recuperá-la. Perdeu? Revogue e crie uma nova. Nunca coloque a chave no código de uma página do site ou num app de celular — todo visitante a veria. A chave fica só no servidor.

Você pode mudar as permissões e configurações de uma chave a qualquer momento em "Configurações" — as mudanças valem em até um minuto. "Revogar" desativa a chave na hora.

Passo 2. Sua primeira requisição#

curl -X POST https://craftopen.space/api/v1/tools/list_funnels \
  -H "Authorization: Bearer craft_your_key" \
  -H "Content-Type: application/json" \
  -d '{}'

Uma resposta bem-sucedida sempre tem esta forma — os dados em si ficam em data:

{"ok": true, "data": {"funnels": [ ... ]}}

Se algo estiver errado, você recebe "ok": false e um motivo claro:

{"ok": false, "error": {"code": "funnel_not_found", "message": "Воронка не найдена."}}

⚠️ No momento, as mensagens de erro são escritas em russo. Construa sua lógica com base em error.code — ele é estável e não depende do idioma.

Métodos disponíveis#

Todos os métodos e seus parâmetros com descrições:

  • na Craft: GET https://craftopen.space/api/v1/tools com a sua chave — a lista diz qual permissão cada método exige e se esta chave pode chamá-lo;
  • uma descrição OpenAPI: craftopen.space/api/v1/openapi.json — Postman, Insomnia e geradores de clientes a entendem.

Os métodos são os mesmos do conector MCP. Os mais comuns:

Tarefa Método Permissão da chave
Listar funis e suas estatísticas list_funnels, get_funnel_stats leitura
Encontrar inscritos do bot find_contacts leitura
Card do inscrito get_contact leitura
Adicionar ou remover uma tag tag_contacts contatos
Rodar um funil para uma pessoa run_funnel_for_contact contatos, modo "Na hora"
Post agendado list_publishing_accounts → schedule_post posts
Disparo no Telegram save_broadcast_draft → send_broadcast_test → send_broadcast disparos
Carrossel a partir do seu texto create_carousel, render_carousel conteúdo
Imagem por créditos generate_image conteúdo

GET https://craftopen.space/api/v1/me mostra qual chave você está usando, as permissões dela e quantas requisições restam hoje.

Repetir sem duplicar#

Se uma requisição caiu e você não sabe se ela passou, envie de novo com o mesmo cabeçalho Idempotency-Key. O post não sai duas vezes e uma imagem não é cobrada duas vezes.

curl -X POST https://craftopen.space/api/v1/tools/schedule_post \
  -H "Authorization: Bearer craft_your_key" \
  -H "Idempotency-Key: post-2026-09-27-lime-1" \
  -H "Content-Type: application/json" \
  -d '{"account_ids": ["..."], "confirm_usernames": ["@lime_agency"],
       "carousel_id": "...", "caption": "Post text",
       "scheduled_at": "2026-09-27T19:00:00+03:00"}'

⚠️ As confirmações fazem parte da requisição. Onde o site perguntaria "tem certeza?", a API espera uma confirmação nos parâmetros: os @ das contas num post (confirm_usernames), o número exato de destinatários num disparo (confirm_recipients), o nome de um funil ativo que você está editando, o preço de um bloco de pagamento. Se a confirmação não bater com o que a Craft vê, nada é enviado — a resposta diz o valor correto.

Erros e o que fazer#

Status Significado
400 Parâmetros inválidos — message diz quais
401 Sem chave, chave errada ou a chave foi revogada
403 Plano sem API (plan_required), a chave não tem uma permissão (scope_required), ou o modo de publicação não permite a ação
404 Não encontrado: funil, contato, post ou método
409 Os dados mudaram desde que você os leu, ou uma confirmação não bateu — leia de novo
429 Limite de requisições — espere tantos segundos quanto o cabeçalho Retry-After indica
500, 503 Falha temporária — tente de novo em um minuto com o mesmo Idempotency-Key

Limites#

  • 60 requisições por minuto e 10.000 por dia por conta — somando todas as chaves. O dia é contado no horário de Moscou (UTC+3). Precisa de mais? Escreva para o suporte; o limite é aumentado sem mudar de plano.
  • Os webhooks não contam no limite.
  • As imagens gastam créditos pelos mesmos preços do site, e nunca acima do limite diário que você definiu para a chave.
  • Disparos: no máximo o número escolhido por dia por bot. Um teste para você com send_broadcast_test exatamente do mesmo texto é obrigatório antes do envio.

Webhooks#

API e webhooks → Adicionar webhook: digite o endereço do seu servidor (só https://) e escolha os eventos. Logo depois da criação, a Craft mostra o segredo de assinatura — guarde, ele não é mostrado de novo (você pode emitir um novo com "Novo segredo").

Testar envia um evento ping e mostra o que o seu servidor respondeu. Registro lista as entregas recentes: o que foi enviado, se chegou, a resposta e um botão "Tentar novamente".

Eventos#

Evento Quando chega
contact.created Alguém se inscreveu num bot ou escreveu pela primeira vez no seu Direct do Instagram
funnel.button_clicked Alguém clicou num botão de um funil
funnel.goal_reached Alguém atingiu a meta do funil
payment.succeeded Um pagamento passou por um bloco de pagamento do funil
post.published Um post foi publicado na rede social
agent.message_received A mensagem de um cliente chegou ao agente de IA — no Instagram ou no Telegram
agent.replied O agente de IA respondeu ao cliente e a resposta foi enviada. Os dados têm o texto da resposta
agent.handed_over O agente de IA passou o cliente para a equipe. Os dados têm o resumo e se foi entregue, e para quem

Os eventos do agente trazem platform (instagram ou telegram), account_id (a conta do Instagram ou o bot), contact_id e um horário, para você poder guardar o histórico das conversas do agente no seu próprio CRM ou serviço.

Exemplo de corpo da requisição:

{
  "id": "6f1c…",
  "type": "contact.created",
  "created_at": "2026-09-26T09:04:11+00:00",
  "data": {
    "platform": "telegram",
    "contact_id": "…",
    "bot_username": "shop_bot",
    "first_name": "Anna",
    "username": "anna",
    "source": {"type": "link", "ref": "promo"}
  }
}

O id do evento é o mesmo em todas as tentativas — use-o para descartar duplicatas.

Verificando que uma requisição veio da Craft#

Toda requisição tem o cabeçalho Craft-Signature: t=<time>,v1=<signature>. A assinatura é o HMAC-SHA256 da string <time>.<request body> com o seu segredo. Calcule e compare:

import hmac, hashlib, time

def craft_signature_ok(header: str, body: bytes, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    if abs(time.time() - int(parts["t"])) > 300:   # older than 5 minutes — reject
        return False
    expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])
const crypto = require("crypto");

function craftSignatureOk(header, rawBody, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

⚠️ A assinatura é calculada sobre o corpo bruto da requisição — exatamente os bytes que chegaram. Se o seu framework interpreta o JSON e o serializa de novo antes, a assinatura não vai bater.

Novas tentativas#

A Craft espera até 10 segundos por uma resposta. Qualquer resposta 2xx conta como entregue. Senão, a Craft tenta de novo depois de 1 minuto, 5 minutos, 30 minutos, 2, 6, 12 e 24 horas — 8 tentativas no total, depois das quais o evento é marcado como "falhou" (você pode reenviá-lo pelo registro).

🔴 Depois de 50 entregas falhas seguidas, o webhook é desativado para não continuar batendo num endereço morto. Corrija o seu servidor e clique em "Ativar" — o contador zera. Os eventos que aconteceram enquanto o webhook estava desativado não são enviados.

Responda rápido e faça o trabalho demorado depois de responder: se o seu servidor levar mais de 10 segundos, a Craft conta a tentativa como falha e envia o evento de novo.

Seu próprio canal: respostas do agente de IA#

Se os clientes te escrevem onde a Craft não está conectada (seu próprio mensageiro, chat do site, CRM), o agente de IA também pode responder lá. Seu sistema envia a mensagem do cliente — a Craft devolve a resposta do agente. Seu sistema a entrega ao cliente.

curl -X POST https://craftopen.space/api/v1/agent/reply \
  -H "Authorization: Bearer craft_…" -H "Content-Type: application/json" \
  -d '{"ig_user_id": "1784…", "contact_id": "client-42", "text": "How much is JET+?", "name": "Ivan"}'
  • De quem é o agente que responde — ig_user_id de uma conta do Instagram ou tg_bot_id de um bot do Telegram com agente configurado. São usadas as regras, a base de conhecimento, o modelo e as configurações de transferência dele.
  • contact_id — o id estável do seu cliente; o agente lembra a conversa por ele. name — opcional, para a transferência à equipe.
  • Resposta: reply — texto para o cliente, handed_over — o agente passou o cliente para a equipe (o lead vai para onde vão os leads do Instagram), paused — o agente fica em silêncio até a equipe devolvê-lo, credits_charged — créditos gastos.
  • As respostas custam créditos, igual no Instagram. Sem créditos — você recebe o erro no_credits.
  • Os eventos agent.message_received, agent.replied e agent.handed_over também disparam para esse canal.

⚠️ Por esse canal, o agente envia só texto — nada de vídeos ou arquivos dos funis.

Ainda não disponível#

  • Bibliotecas de cliente prontas — use a descrição OpenAPI.
  • Criar chaves e webhooks pela própria API — só na página API e webhooks.
  • "Entrar com a Craft" para apps de terceiros: uma chave só dá acesso à sua própria conta.
Não encontrou a resposta?Fale com a gente no Telegram ou em [email protected]: respondemos e completamos o artigo.
Falar no Telegram