ZippyVendas

API Externa

ZippyVendas fornece uma API externa abrangente para consultar registros de execução de workflows e configurar webhooks para notificações em tempo real quando workflows são completados.

Autenticação

Todas as requisições de API requerem uma chave de API passada no header x-api-key:

curl -H "x-api-key: YOUR_API_KEY" \
  https://zippyvendas.com/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID

Você pode gerar chaves de API nas suas configurações de usuário no dashboard do ZippyVendas.

API de Logs

Todas as respostas da API incluem informações sobre seus limites de execução de workflow e uso:

"limits": {
  "workflowExecutionRateLimit": {
    "sync": {
      "limit": 60,        // Max de execuções de workflow sincronos por minuto
      "remaining": 58,    // Execuções de workflow síncronos restantes
      "resetAt": "..."    // Quando a janela é resetada
    },
    "async": {
      "limit": 60,        // Max de execuções de workflow assincronos por minuto
      "remaining": 59,    // Execuções de workflow assincronos restantes
      "resetAt": "..."    // Quando a janela é resetada
    }
  },
  "usage": {
    "currentPeriodCost": 1.234,  // Uso do período de faturamento atual em USD
    "limit": 10,                  // Limite de uso em USD
    "plan": "pro",                // Plano de assinatura atual
    "isExceeded": false           // Se o limite foi excedido
  }
}

Nota: Os limites de taxa no corpo da resposta são para execuções de workflow. Os limites de taxa para chamar este endpoint de API estão nos headers da resposta (X-RateLimit-*).

Consultar Logs

Consulte registros de execução de workflows com opções extensivas de filtros.

GET /api/v1/logs

Parâmetros Obrigatórios:

  • workspaceId - Seu ID de workspace

Filtros Opcionais:

  • workflowIds - IDs de workflow separados por vírgula
  • folderIds - IDs de pasta separados por vírgula
  • triggers - Tipos de trigger separados por vírgula: api, webhook, schedule, manual, chat
  • level - Filtrar por nível: info, error
  • startDate - Timestamp ISO para início do intervalo de datas
  • endDate - Timestamp ISO para fim do intervalo de datas
  • executionId - Correspondência exata de ID de execução
  • minDurationMs - Duração mínima de execução em milissegundos
  • maxDurationMs - Duração máxima de execução em milissegundos
  • minCost - Custo mínimo de execução
  • maxCost - Custo máximo de execução
  • model - Filtrar por modelo de IA usado

Paginação:

  • limit - Resultados por página (padrão: 100)
  • cursor - Cursor para próxima página
  • order - Ordem de classificação: desc, asc (padrão: desc)

Nível de Detalhe:

  • details - Nível de detalhe da resposta: basic, full (padrão: basic)
  • includeTraceSpans - Incluir trace spans (padrão: false)
  • includeFinalOutput - Incluir saída final (padrão: false)
{
  "data": [
    {
      "id": "log_abc123",
      "workflowId": "wf_xyz789",
      "executionId": "exec_def456",
      "level": "info",
      "trigger": "api",
      "startedAt": "2025-01-01T12:34:56.789Z",
      "endedAt": "2025-01-01T12:34:57.123Z",
      "totalDurationMs": 334,
      "cost": {
        "total": 0.00234
      },
      "files": null
    }
  ],
  "nextCursor": "eyJzIjoiMjAyNS0wMS0wMVQxMjozNDo1Ni43ODlaIiwiaWQiOiJsb2dfYWJjMTIzIn0",
  "limits": {
    "workflowExecutionRateLimit": {
      "sync": {
        "limit": 60,
        "remaining": 58,
        "resetAt": "2025-01-01T12:35:56.789Z"
      },
      "async": {
        "limit": 60,
        "remaining": 59,
        "resetAt": "2025-01-01T12:35:56.789Z"
      }
    },
    "usage": {
      "currentPeriodCost": 1.234,
      "limit": 10,
      "plan": "pro",
      "isExceeded": false
    }
  }
}

Obter Detalhes de Log

Recupere informações detalhadas sobre uma entrada de log específica.

GET /api/v1/logs/{id}
{
  "data": {
    "id": "log_abc123",
    "workflowId": "wf_xyz789",
    "executionId": "exec_def456",
    "level": "info",
    "trigger": "api",
    "startedAt": "2025-01-01T12:34:56.789Z",
    "endedAt": "2025-01-01T12:34:57.123Z",
    "totalDurationMs": 334,
    "workflow": {
      "id": "wf_xyz789",
      "name": "My Workflow",
      "description": "Process customer data"
    },
    "executionData": {
      "traceSpans": [...],
      "finalOutput": {...}
    },
    "cost": {
      "total": 0.00234,
      "tokens": {
        "prompt": 123,
        "completion": 456,
        "total": 579
      },
      "models": {
        "gpt-4o": {
          "input": 0.001,
          "output": 0.00134,
          "total": 0.00234,
          "tokens": {
            "prompt": 123,
            "completion": 456,
            "total": 579
          }
        }
      }
    },
    "limits": {
      "workflowExecutionRateLimit": {
        "sync": {
          "limit": 60,
          "remaining": 58,
          "resetAt": "2025-01-01T12:35:56.789Z"
        },
        "async": {
          "limit": 60,
          "remaining": 59,
          "resetAt": "2025-01-01T12:35:56.789Z"
        }
      },
      "usage": {
        "currentPeriodCost": 1.234,
        "limit": 10,
        "plan": "pro",
        "isExceeded": false
      }
    }
  }
}

Obter Detalhes de Execução

Recupere detalhes de execução, incluindo um snapshot do estado do workflow.

GET /api/v1/logs/executions/{executionId}
{
  "executionId": "exec_def456",
  "workflowId": "wf_xyz789",
  "workflowState": {
    "blocks": {...},
    "edges": [...],
    "loops": {...},
    "parallels": {...}
  },
  "executionMetadata": {
    "trigger": "api",
    "startedAt": "2025-01-01T12:34:56.789Z",
    "endedAt": "2025-01-01T12:34:57.123Z",
    "totalDurationMs": 334,
    "cost": {...}
  }
}

Notificações

Receba notificações em tempo real quando execuções de workflow são completadas via webhook, e-mail ou Slack. As notificações são configuradas no nível do workspace a partir da página de Logs.

Configuração

Configure notificações a partir da página de Logs clicando no botão de menu e selecionando "Configurar Notificações".

Canais de Notificação:

  • Webhook: Enviar requisições HTTP POST para seu endpoint
  • E-mail: Receber notificações por e-mail com detalhes de execução
  • Slack: Postar mensagens em um canal Slack

Seleção de Workflow:

  • Selecionar workflows específicos para monitorar
  • Ou escolher "Todos os Workflows" para incluir workflows atuais e futuros

Opções de Filtro:

  • levelFilter: Níveis de log a receber (info, error)
  • triggerFilter: Tipos de trigger a receber (api, webhook, schedule, manual, chat)

Dados Opcionais:

  • includeFinalOutput: Incluir a saída final do workflow
  • includeTraceSpans: Incluir trace spans detalhados de execução
  • includeRateLimits: Incluir informações de limite de taxa (limites síncronos/assincronos e restantes)
  • includeUsageData: Incluir uso do período de faturamento e limites

Regras de Alerta

Em vez de receber notificações para cada execução, configure regras de alerta para ser notificado apenas quando problemas são detectados:

Falhas Consecutivas

  • Alerta após X execuções falhadas consecutivas (ex: 3 falhas seguidas)
  • Reseta quando uma execução sucede

Taxa de Falha

  • Alerta quando a taxa de falha excede X% nas últimas Y horas
  • Requer mínimo de 5 execuções na janela
  • Só dispara após a janela de tempo completa ter transcorrido

Limite de Latência

  • Alerta quando qualquer execução leva mais de X segundos
  • Útil para detectar workflows lentos ou travados

Pico de Latência

  • Alerta quando execução é X% mais lenta que a média
  • Compara contra a duração média durante a janela de tempo configurada
  • Requer mínimo de 5 execuções para estabelecer baseline

Limite de Custo

  • Alerta quando uma execução única custa mais de $X
  • Útil para detectar chamadas de LLM caras

Sem Atividade

  • Alerta quando nenhuma execução ocorre em X horas
  • Útil para monitorar workflows agendados que devem rodar regularmente

Contagem de Erros

  • Alerta quando contagem de erros excede X dentro de uma janela de tempo
  • Rastreia erros totais, não consecutivos

Todos os tipos de alerta incluem um cooldown de 1 hora para prevenir spam de notificações.

Configuração de Webhook

Para webhooks, opções adicionais estão disponíveis:

  • url: URL do seu endpoint de webhook
  • secret: Secret opcional para verificação de assinatura HMAC

Estrutura de Payload

Quando uma execução de workflow é completada, ZippyVendas envia o seguinte payload (via webhook POST, e-mail ou Slack):

{
  "id": "evt_123",
  "type": "workflow.execution.completed",
  "timestamp": 1735925767890,
  "data": {
    "workflowId": "wf_xyz789",
    "executionId": "exec_def456",
    "status": "success",
    "level": "info",
    "trigger": "api",
    "startedAt": "2025-01-01T12:34:56.789Z",
    "endedAt": "2025-01-01T12:34:57.123Z",
    "totalDurationMs": 334,
    "cost": {
      "total": 0.00234,
      "tokens": {
        "prompt": 123,
        "completion": 456,
        "total": 579
      },
      "models": {
        "gpt-4o": {
          "input": 0.001,
          "output": 0.00134,
          "total": 0.00234,
          "tokens": {
            "prompt": 123,
            "completion": 456,
            "total": 579
          }
        }
      }
    },
    "files": null,
    "finalOutput": {...},  // Only if includeFinalOutput=true
    "traceSpans": [...],   // Only if includeTraceSpans=true
    "rateLimits": {...},   // Only if includeRateLimits=true
    "usage": {...}         // Only if includeUsageData=true
  },
  "links": {
    "log": "/v1/logs/log_abc123",
    "execution": "/v1/logs/executions/exec_def456"
  }
}

Headers de Webhook

Cada requisição de webhook inclui estes headers (apenas para canal webhook):

  • sim-event: Tipo de evento (sempre workflow.execution.completed)
  • sim-timestamp: Timestamp Unix em milissegundos
  • sim-delivery-id: ID de entrega único para idempotência
  • sim-signature: Assinatura HMAC-SHA256 para verificação (se secret configurado)
  • Idempotency-Key: Igual ao ID de entrega para detecção de duplicatas

Verificação de Assinatura

Se você configurar um secret de webhook, verifique a assinatura para garantir que o webhook é do ZippyVendas:

import crypto from 'crypto';

function verifyWebhookSignature(body, signature, secret) {
  const [timestampPart, signaturePart] = signature.split(',');
  const timestamp = timestampPart.replace('t=', '');
  const expectedSignature = signaturePart.replace('v1=', '');
  
  const signatureBase = `${timestamp}.${body}`;
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(signatureBase);
  const computedSignature = hmac.digest('hex');
  
  return computedSignature === expectedSignature;
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['sim-signature'];
  const body = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook...
});
import hmac
import hashlib
import json

def verify_webhook_signature(body: str, signature: str, secret: str) -> bool:
    timestamp_part, signature_part = signature.split(',')
    timestamp = timestamp_part.replace('t=', '')
    expected_signature = signature_part.replace('v1=', '')
    
    signature_base = f"{timestamp}.{body}"
    computed_signature = hmac.new(
        secret.encode(),
        signature_base.encode(),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(computed_signature, expected_signature)

# In your webhook handler
@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('sim-signature')
    body = json.dumps(request.json)
    
    if not verify_webhook_signature(body, signature, os.environ['WEBHOOK_SECRET']):
        return 'Invalid signature', 401
    
    # Process the webhook...

Política de Retry

Entregas de webhook falhadas são retentadas com backoff exponencial e jitter:

  • Máximo de tentativas: 5
  • Atrasos de retry: 5 segundos, 15 segundos, 1 minuto, 3 minutos, 10 minutos
  • Jitter: Até 10% de atraso adicional para prevenir thundering herd
  • Apenas respostas HTTP 5xx e 429 disparam retries
  • Entregas expiram após 30 segundos

Entregas de webhook são processadas assincronamente e não afetam o desempenho de execução do workflow.

Melhores Práticas

  1. Estratégia de Polling: Ao fazer polling para logs, use paginação baseada em cursor com order=asc e startDate para buscar novos logs eficientemente.

  2. Segurança de Webhook: Sempre configure um secret de webhook e verifique assinaturas para garantir que requisições são do ZippyVendas.

  3. Idempotência: Use o header Idempotency-Key para detectar e lidar com entregas duplicadas de webhook.

  4. Privacidade: Por padrão, finalOutput e traceSpans são excluídos das respostas. Apenas habilite estes se você precisa dos dados e entende as implicações de privacidade.

  5. Rate Limiting: Implemente backoff exponencial quando você receber respostas 429. Verifique o header Retry-After para o tempo de espera recomendado.

Limite de Taxa

A API implementa limite de taxa para garantir uso justo:

  • Plano Free: 10 requisições por minuto
  • Plano Pro: 30 requisições por minuto
  • Plano Team: 60 requisições por minuto
  • Plano Enterprise: Limites customizados

Informações de limite de taxa estão incluídas nos headers de resposta:

  • X-RateLimit-Limit: Máximo de requisições por janela
  • X-RateLimit-Remaining: Requisições restantes na janela atual
  • X-RateLimit-Reset: Timestamp ISO quando a janela reseta

Exemplo: Polling para Novos Logs

let cursor = null;
const workspaceId = 'YOUR_WORKSPACE_ID';
const startDate = new Date().toISOString();

async function pollLogs() {
  const params = new URLSearchParams({
    workspaceId,
    startDate,
    order: 'asc',
    limit: '100'
  });

  if (cursor) {
    params.append('cursor', cursor);
  }

  const response = await fetch(
    `https://zippyvendas.com/api/v1/logs?${params}`,
    {
      headers: {
        'x-api-key': 'YOUR_API_KEY'
      }
    }
  );

  if (response.ok) {
    const data = await response.json();

    // Process new logs
    for (const log of data.data) {
      console.log(`New execution: ${log.executionId}`);
    }

    // Update cursor for next poll
    if (data.nextCursor) {
      cursor = data.nextCursor;
    }
  }
}

// Poll every 30 seconds
setInterval(pollLogs, 30000);

Exemplo: Processando Webhooks

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.json());

app.post('/sim-webhook', (req, res) => {
  // Verify signature
  const signature = req.headers['sim-signature'];
  const body = JSON.stringify(req.body);

  if (!verifyWebhookSignature(body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // Check timestamp to prevent replay attacks
  const timestamp = parseInt(req.headers['sim-timestamp']);
  const fiveMinutesAgo = Date.now() - (5 * 60 * 1000);

  if (timestamp < fiveMinutesAgo) {
    return res.status(401).send('Timestamp too old');
  }

  // Process the webhook
  const event = req.body;

  switch (event.type) {
    case 'workflow.execution.completed':
      const { workflowId, executionId, status, cost } = event.data;

      if (status === 'error') {
        console.error(`Workflow ${workflowId} failed: ${executionId}`);
        // Handle error...
      } else {
        console.log(`Workflow ${workflowId} completed: ${executionId}`);
        console.log(`Cost: $${cost.total}`);
        // Process successful execution...
      }
      break;
  }

  // Return 200 to acknowledge receipt
  res.status(200).send('OK');
});

app.listen(3000, () => {
  console.log('Webhook server listening on port 3000');
});
On this page

On this page

Comece a automatizar hoje
Confiado por empresas em todo o Brasil.
Crie fluxos de automação de vendas com IA no WhatsApp de forma visual e intuitiva.
Começar grátis