Ir para o conteúdo
ZeynAPI

Referência da API, versão 1

API e webhooks da Zeyn

Ligue o seu ERP, CRM, loja ou planilha ao WhatsApp do negócio. Crie e baixe cobranças, mantenha os clientes sincronizados, mande avisos pelo número da empresa e receba no seu servidor, na hora, cada mensagem, pagamento e horário marcado.

  1. 1No painel da Zeyn, abra Configurações e depois API e webhooks. A API faz parte dos planos Pro e Agency.
  2. 2Crie uma chave com um nome que diga onde ela vai ficar. A chave aparece inteira uma única vez.
  3. 3Guarde em uma variável de ambiente e faça a primeira chamada. A resposta mostra a empresa e o plano.
Primeira chamada
curl https://zeyn.app.br/api/v1/me \
  -H "Authorization: Bearer $ZEYN_API_KEY"

Tudo é JSON em UTF-8, com campos em snake_case, datas em ISO 8601 (UTC), telefones no formato +5585988887777 e dinheiro em centavos inteiros, para que nenhuma soma perca um centavo.


Autenticação

Toda requisição leva a chave no cabeçalho Authorization. As chaves começam com zk_live_, formato que os verificadores de segredos reconhecem se uma delas parar num repositório. Use uma chave por sistema: se uma vazar, revogue só ela no painel e o resto continua funcionando.

A chave dá acesso a toda a conta. Use sempre do seu servidor, nunca no navegador ou num aplicativo.

Cabeçalho
Authorization: Bearer zk_live_a1b2c3d4_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Erros

Os erros usam o código HTTP certo e sempre o mesmo corpo. O campo type é estável, e é nele que o seu código deve se basear. message explica para quem lê o log, e param aponta o campo com problema. Mande o request_id quando falar com a gente.

Resposta 400
{
  "error": {
    "type": "invalid_request",
    "message": "amount_cents é um inteiro em centavos: 15000 é R$ 150,00.",
    "param": "amount_cents",
    "request_id": "req_7d1f2a9c4b3e8f6a0d5c"
  }
}
typeHTTPQuando
authentication_failed401Chave ausente, inválida ou revogada.
plan_required403O plano não inclui a API, ou um limite do plano foi atingido.
invalid_request400Um campo faltou ou veio errado. param diz qual.
not_found404O objeto não existe nesta conta.
conflict409A ação não combina com o estado atual, como cancelar uma cobrança paga.
rate_limited429Muitas requisições. Espere os segundos de Retry-After.
window_closed422O cliente não escreveu nas últimas 24 horas. Use um modelo.
template_not_approved422Nenhum modelo aprovado com esse nome e idioma.
recipient_opted_out422O cliente pediu para não receber mensagens da empresa.
whatsapp_not_connected409A conta não tem um número de WhatsApp conectado.
idempotency_mismatch422A Idempotency-Key já foi usada com outra requisição.
send_failed502O WhatsApp recusou o envio. message traz o motivo.
internal_error500Falha do nosso lado. Pode tentar de novo.

Paginação

Listas devolvem { "object": "list", "data": [...], "has_more": true }. Peça até 100 por vez com limit e continue passando em starting_after o id do último item recebido, enquanto has_more for verdadeiro. O cursor não pula nem repete itens, mesmo com dados chegando no meio da leitura.

Próxima página
curl "https://zeyn.app.br/api/v1/charges?limit=50&starting_after=c0a8012e-..." \
  -H "Authorization: Bearer $ZEYN_API_KEY"

Idempotência

Redes caem no meio de uma resposta. Envie um cabeçalho Idempotency-Key nas requisições POST e PATCH e, se precisar repetir, a Zeyn devolve a mesma resposta da primeira vez, com Idempotent-Replayed: true, sem mandar a mensagem de novo. A chave vale por 24 horas. Reusar a mesma chave com outro corpo responde 422 idempotency_mismatch.

Em cobranças, external_id faz o mesmo papel de forma permanente: é o jeito certo de sincronizar notas e pedidos.

Requisição segura de repetir
curl -X POST https://zeyn.app.br/api/v1/messages \
  -H "Authorization: Bearer $ZEYN_API_KEY" \
  -H "Idempotency-Key: pedido-1234-saiu" \
  -H "Content-Type: application/json" \
  -d '{"to":"85988887777","template":{"name":"pedido_enviado","variables":{"nome":"Marina","numero":"1234"}}}'

Limites

Cada chave faz até 120 requisições por minuto. Toda resposta traz X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Acima do limite, a resposta é 429 com Retry-After em segundos.

O envio de mensagens tem um segundo limite, do número de WhatsApp, que protege a reputação dele com a Meta. Para avisos em massa, use os Disparos no painel: eles cuidam do ritmo e das regras de opt-out por você.


Contatos

Quem já falou com o negócio ou foi cadastrado. O telefone é a identidade: enviar o mesmo número de novo atualiza o contato em vez de criar outro.

Criar ou atualizar um contato

POST/v1/contacts

Procura pelo telefone, em qualquer formato com DDD. Se existe, atualiza os campos enviados e responde 200. Se não, cria e responde 201.

Corpo

  • phonetextoobrigatório

    Com DDD. Aceita +55, espaços e traços.

  • nametexto

    Até 200 caracteres.

  • emailtexto

    E-mail do cliente.

  • notestexto

    Observações visíveis para a equipe.

Requisição
curl -X POST https://zeyn.app.br/api/v1/contacts \
  -H "Authorization: Bearer $ZEYN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+55 85 98888-7777",
    "name": "Marina Costa"
  }'
Resposta
{
  "object": "contact",
  "id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "name": "Marina Costa",
  "phone": "+5585988887777",
  "email": "[email protected]",
  "stage": "lead",
  "lead_status": "warm",
  "source": "api",
  "notes": null,
  "last_message_at": "2026-11-07T13:02:11.000Z",
  "created_at": "2026-11-01T10:00:00.000Z"
}

Listar contatos

GET/v1/contacts

Do mais novo para o mais antigo.

Parâmetros de consulta

  • phonetexto

    Filtra pelo telefone.

  • emailtexto

    Filtra pelo e-mail.

  • limitinteiro

    De 1 a 100. Padrão 25.

  • starting_afterid

    O id do último objeto da página anterior.

Requisição
curl https://zeyn.app.br/api/v1/contacts?phone=85988887777 \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "list",
  "data": [
    {
      "object": "contact",
      "id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
      "name": "Marina Costa",
      "phone": "+5585988887777",
      "email": "[email protected]",
      "stage": "lead",
      "lead_status": "warm",
      "source": "api",
      "notes": null,
      "last_message_at": "2026-11-07T13:02:11.000Z",
      "created_at": "2026-11-01T10:00:00.000Z"
    }
  ],
  "has_more": false
}

Buscar um contato

GET/v1/contacts/{id}

Pelo id da Zeyn.

Requisição
curl https://zeyn.app.br/api/v1/contacts/6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "contact",
  "id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "name": "Marina Costa",
  "phone": "+5585988887777",
  "email": "[email protected]",
  "stage": "lead",
  "lead_status": "warm",
  "source": "api",
  "notes": null,
  "last_message_at": "2026-11-07T13:02:11.000Z",
  "created_at": "2026-11-01T10:00:00.000Z"
}

Atualizar um contato

PATCH/v1/contacts/{id}

Só os campos enviados mudam.

Corpo

  • nametexto

    Nome do cliente.

  • emailtexto

    E-mail, ou null para apagar.

  • notestexto

    Observações, ou null para apagar.

  • stagetexto

    lead, qualified, customer ou churned.

Requisição
curl -X PATCH https://zeyn.app.br/api/v1/contacts/6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f \
  -H "Authorization: Bearer $ZEYN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "stage": "customer"
  }'
Resposta
{
  "object": "contact",
  "id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "name": "Marina Costa",
  "phone": "+5585988887777",
  "email": "[email protected]",
  "stage": "customer",
  "lead_status": "warm",
  "source": "api",
  "notes": null,
  "last_message_at": "2026-11-07T13:02:11.000Z",
  "created_at": "2026-11-01T10:00:00.000Z"
}

Cobranças

Valores a receber. A Zeyn lembra o cliente pelo WhatsApp nos dias da régua e manda o Pix copia e cola quando ele pede. Quando o seu sistema confirmar o pagamento, avise: os lembretes param na hora.

Criar uma cobrança

POST/v1/charges

Com external_id, chamar de novo com o mesmo valor devolve a cobrança que já existe com 200, sem duplicar. Use o número da nota ou do pedido do seu sistema.

Corpo

  • contact_idid

    Um contato existente. Ou envie contact.

  • contactobjeto

    { phone, name }. Encontra pelo telefone ou cria.

  • descriptiontextoobrigatório

    O que está sendo cobrado. Até 80 caracteres.

  • amount_centsinteiroobrigatório

    Em centavos: 15000 é R$ 150,00.

  • due_datedataobrigatório

    AAAA-MM-DD, no horário de Brasília.

  • external_idtexto

    O id da cobrança no seu sistema.

  • payment_urlurl

    Boleto ou checkout, enviado junto com o Pix.

  • repeat_monthlybooleano

    Gera uma cobrança por mês no mesmo dia.

Requisição
curl -X POST https://zeyn.app.br/api/v1/charges \
  -H "Authorization: Bearer $ZEYN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact": {
      "phone": "85988887777",
      "name": "Marina Costa"
    },
    "description": "Mensalidade de novembro",
    "amount_cents": 15000,
    "due_date": "2026-11-10",
    "external_id": "NF-1001"
  }'
Resposta
{
  "object": "charge",
  "id": "c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00",
  "external_id": "NF-1001",
  "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "description": "Mensalidade de novembro",
  "amount_cents": 15000,
  "currency": "BRL",
  "due_date": "2026-11-10",
  "status": "open",
  "customer_reported_at": null,
  "reminders_paused": false,
  "paid_at": null,
  "paid_via": null,
  "canceled_at": null,
  "payment_url": null,
  "pix_code": "00020101021226580014br.gov.bcb.pix0136financeiro@suaempresa.com.br5204000053039865406150.005802BR5913SUA EMPRESA6009FORTALEZA62130509ZEYNC0A86304A1B2",
  "recurring": false,
  "created_at": "2026-11-01T10:00:00.000Z"
}

Listar cobranças

GET/v1/charges

Da mais nova para a mais antiga.

Parâmetros de consulta

  • statustexto

    open, paid ou canceled.

  • contact_idid

    Só as de um contato.

  • external_idtexto

    Encontra pelo id do seu sistema.

  • limitinteiro

    De 1 a 100. Padrão 25.

  • starting_afterid

    O id do último objeto da página anterior.

Requisição
curl https://zeyn.app.br/api/v1/charges?status=open \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "list",
  "data": [
    {
      "object": "charge",
      "id": "c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00",
      "external_id": "NF-1001",
      "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
      "description": "Mensalidade de novembro",
      "amount_cents": 15000,
      "currency": "BRL",
      "due_date": "2026-11-10",
      "status": "open",
      "customer_reported_at": null,
      "reminders_paused": false,
      "paid_at": null,
      "paid_via": null,
      "canceled_at": null,
      "payment_url": null,
      "pix_code": "00020101021226580014br.gov.bcb.pix0136financeiro@suaempresa.com.br5204000053039865406150.005802BR5913SUA EMPRESA6009FORTALEZA62130509ZEYNC0A86304A1B2",
      "recurring": false,
      "created_at": "2026-11-01T10:00:00.000Z"
    }
  ],
  "has_more": false
}

Buscar uma cobrança

GET/v1/charges/{id}

Inclui o pix_code enquanto ela está em aberto.

Requisição
curl https://zeyn.app.br/api/v1/charges/c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00 \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "charge",
  "id": "c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00",
  "external_id": "NF-1001",
  "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "description": "Mensalidade de novembro",
  "amount_cents": 15000,
  "currency": "BRL",
  "due_date": "2026-11-10",
  "status": "open",
  "customer_reported_at": null,
  "reminders_paused": false,
  "paid_at": null,
  "paid_via": null,
  "canceled_at": null,
  "payment_url": null,
  "pix_code": "00020101021226580014br.gov.bcb.pix0136financeiro@suaempresa.com.br5204000053039865406150.005802BR5913SUA EMPRESA6009FORTALEZA62130509ZEYNC0A86304A1B2",
  "recurring": false,
  "created_at": "2026-11-01T10:00:00.000Z"
}

Marcar como paga

POST/v1/charges/{id}/pay

Para os lembretes e registra paid_via api. Chamar de novo numa cobrança já paga responde 200 sem mudar nada, então a conciliação pode rodar quantas vezes precisar.

Requisição
curl -X POST https://zeyn.app.br/api/v1/charges/c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00/pay \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "charge",
  "id": "c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00",
  "external_id": "NF-1001",
  "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "description": "Mensalidade de novembro",
  "amount_cents": 15000,
  "currency": "BRL",
  "due_date": "2026-11-10",
  "status": "paid",
  "customer_reported_at": null,
  "reminders_paused": false,
  "paid_at": "2026-11-09T14:30:00.000Z",
  "paid_via": "api",
  "canceled_at": null,
  "payment_url": null,
  "pix_code": null,
  "recurring": false,
  "created_at": "2026-11-01T10:00:00.000Z"
}

Cancelar

POST/v1/charges/{id}/cancel

Tira a cobrança da régua. Uma cobrança paga não pode ser cancelada (409).

Requisição
curl -X POST https://zeyn.app.br/api/v1/charges/c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00/cancel \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "charge",
  "id": "c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00",
  "external_id": "NF-1001",
  "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "description": "Mensalidade de novembro",
  "amount_cents": 15000,
  "currency": "BRL",
  "due_date": "2026-11-10",
  "status": "canceled",
  "customer_reported_at": null,
  "reminders_paused": false,
  "paid_at": null,
  "paid_via": null,
  "canceled_at": "2026-11-08T09:00:00.000Z",
  "payment_url": null,
  "pix_code": null,
  "recurring": false,
  "created_at": "2026-11-01T10:00:00.000Z"
}

Mensagens

Mensagens do seu sistema para o cliente, pelo número do negócio, seguindo as regras do WhatsApp. Tudo o que sai aparece na caixa de entrada, e a resposta do cliente cai no agente como qualquer conversa.

Enviar uma mensagem

POST/v1/messages

Texto livre só sai se o cliente escreveu nas últimas 24 horas. Fora dessa janela a resposta é 422 window_closed, e o caminho é um modelo aprovado pela Meta na sua conta, enviado em template com todas as variáveis preenchidas.

Corpo

  • totexto

    Telefone com DDD. Ou envie contact_id.

  • contact_idid

    Um contato existente.

  • nametexto

    Nome, se o telefone ainda não for um contato.

  • texttexto

    Mensagem livre, dentro da janela de 24 horas.

  • templateobjeto

    { name, language, variables } de um modelo aprovado.

Requisição
curl -X POST https://zeyn.app.br/api/v1/messages \
  -H "Authorization: Bearer $ZEYN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "85988887777",
    "template": {
      "name": "pedido_enviado",
      "variables": {
        "nome": "Marina",
        "numero": "1234"
      }
    }
  }'
Resposta
{
  "object": "message",
  "id": "9b2e7c1a-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
  "conversation_id": "1d2c3b4a-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
  "direction": "outbound",
  "author": "system",
  "text": "Oi, Marina! Seu pedido 1234 saiu para entrega.",
  "media_type": null,
  "template_name": "pedido_enviado",
  "status": "sent",
  "created_at": "2026-11-07T13:05:00.000Z"
}

Agenda

Os horários marcados pelo agente ou pela equipe, em ordem de acontecimento.

Listar horários

GET/v1/appointments

Do mais cedo para o mais tarde.

Parâmetros de consulta

  • fromdata e hora

    ISO 8601, como 2026-11-12T00:00:00-03:00.

  • todata e hora

    ISO 8601. Exclusivo.

  • statustexto

    scheduled, confirmed, cancelled ou completed.

  • contact_idid

    Só os de um contato.

  • limitinteiro

    De 1 a 100. Padrão 25.

  • starting_afterid

    O id do último objeto da página anterior.

Requisição
curl https://zeyn.app.br/api/v1/appointments?from=2026-11-12T00:00:00-03:00 \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "list",
  "data": [
    {
      "object": "appointment",
      "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
      "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
      "title": "Corte e escova",
      "starts_at": "2026-11-12T17:00:00.000Z",
      "ends_at": "2026-11-12T18:00:00.000Z",
      "status": "scheduled",
      "source": "ai",
      "notes": "Primeira vez no salão.",
      "cancel_reason": null,
      "canceled_at": null,
      "created_at": "2026-11-07T13:10:00.000Z"
    }
  ],
  "has_more": false
}

Conta

Para conferir se a chave está certa antes de qualquer outra chamada.

Quem é esta chave

GET/v1/me

A empresa, o plano e o limite de requisições da chave.

Requisição
curl https://zeyn.app.br/api/v1/me \
  -H "Authorization: Bearer $ZEYN_API_KEY"
Resposta
{
  "object": "account",
  "organization": {
    "id": "org_8f2a",
    "name": "Sua Empresa"
  },
  "plan": "Pro",
  "api_key": {
    "id": "4b1d",
    "name": "ERP"
  },
  "rate_limit_per_minute": 120
}

Webhooks

Cadastre um endereço https em Configurações, API e webhooks, e escolha os eventos. A cada acontecimento a Zeyn faz um POST com o evento em JSON. O objeto dentro de data tem exatamente o mesmo formato que a API devolve, então o mesmo código lê os dois.

Responda com qualquer status 2xx em até 10 segundos e faça o trabalho pesado depois, numa fila do seu lado. Use o id do evento para descartar repetições: em raras quedas de rede, o mesmo evento pode chegar duas vezes.

Cabeçalhos
POST /webhooks/zeyn HTTP/1.1
Content-Type: application/json
User-Agent: Zeyn-Webhooks/1.0
Zeyn-Event: charge.paid
Zeyn-Delivery: dlv_6c1e0f9b2a7d4c3e
Zeyn-Signature: t=1794321000,v1=5f2b1c...
Corpo
{
  "id": "evt_3f9a1c7e2b4d4e8f9a0b1c2d3e4f5a6b",
  "type": "charge.paid",
  "created_at": "2026-11-09T14:30:00.000Z",
  "data": {
    "charge": {
      "object": "charge",
      "id": "c0a8012e-5b7d-4f3a-8e21-9d6c4b2a1f00",
      "external_id": "NF-1001",
      "contact_id": "6f1c2d4e-8a3b-4c5d-9e0f-1a2b3c4d5e6f",
      "description": "Mensalidade de novembro",
      "amount_cents": 15000,
      "currency": "BRL",
      "due_date": "2026-11-10",
      "status": "paid",
      "customer_reported_at": null,
      "reminders_paused": false,
      "paid_at": "2026-11-09T14:30:00.000Z",
      "paid_via": "manual",
      "canceled_at": null,
      "payment_url": null,
      "pix_code": null,
      "recurring": false,
      "created_at": "2026-11-01T10:00:00.000Z"
    }
  }
}

Eventos

Conversas

  • message.received

    Um cliente mandou mensagem no WhatsApp.

  • conversation.handed_off

    A conversa passou do agente para alguém da equipe.

  • conversation.resolved

    A conversa foi encerrada, à mão ou sozinha.

  • csat.answered

    O cliente respondeu a avaliação do atendimento.

Contatos e leads

  • contact.created

    Um contato novo apareceu, pelo WhatsApp ou cadastrado.

  • lead.qualified

    O agente classificou um lead como morno ou quente.

Agenda

  • appointment.created

    Um horário foi marcado.

  • appointment.confirmed

    O cliente confirmou o horário pelo lembrete.

  • appointment.canceled

    Um horário foi desmarcado.

Cobranças

  • charge.created

    Uma cobrança foi registrada.

  • charge.customer_reported

    O cliente avisou que pagou e espera conferência.

  • charge.paid

    Uma cobrança foi confirmada como paga.

  • charge.canceled

    Uma cobrança foi cancelada.

Conferir a assinatura

Cada endereço tem um segredo que começa com whsec_. O cabeçalho Zeyn-Signature traz o momento do envio em t e, em v1, um HMAC SHA-256 de {t}.{corpo} com esse segredo.

Calcule do seu lado sobre os bytes exatos que chegaram, compare em tempo constante e recuse eventos com mais de 5 minutos. Sem essa conferência, qualquer pessoa que descubra o endereço consegue fingir um pagamento.

Node.js
import crypto from "node:crypto";

// No Express, use express.raw({ type: "application/json" }) nesta rota:
// a assinatura vale para os bytes exatos, não para o JSON já interpretado.
export function verifyZeynSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((p) => p.split("=")),
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1 ?? "");
  // Recusa reenvios antigos: 5 minutos de tolerância no relógio.
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  return fresh && a.length === b.length && crypto.timingSafeEqual(a, b);
}

Tentativas e pausa automática

Se o endereço não responder 2xx, tentamos de novo depois de 1 minuto, 5 minutos, 30 minutos, 2 horas, 8 horas e 24 horas: sete tentativas ao longo de um dia e meio. Redirecionamentos não são seguidos.

Depois de 10 eventos seguidos sem sucesso, ou de uma resposta 410, o endereço é pausado e o dono da conta recebe um e-mail. No painel dá para ver cada envio com o corpo e a resposta, reenviar e reativar. O histórico fica guardado por 30 dias.