> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xtracky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Enviar conversão

> POST /api/integrations/api — envio manual de conversão.

Endpoint universal pra reportar qualquer evento de conversão à xTracky. Use quando seu gateway não está na [lista de integrações prontas](/plataformas/lista) ou quando você quer controle total do payload.

<Card icon="paper-plane">
  **POST** `https://api.xtracky.com/api/integrations/api`
</Card>

## Corpo da requisição

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.xtracky.com/api/integrations/api \
    -H "Content-Type: application/json" \
    -d '{
      "orderId": "ORDER_123",
      "amount": 9990,
      "status": "paid",
      "platform": "CUSTOM",
      "utm_source": "TT-1763007625226-yn4xita3qylwh",
      "leadName": "João Silva",
      "leadEmail": "joao@email.com",
      "leadPhone": "+5511999999999",
      "leadDocument": "123.456.789-00"
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch('https://api.xtracky.com/api/integrations/api', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      orderId: 'ORDER_123',
      amount: 9990,
      status: 'paid',
      platform: 'CUSTOM',
      utm_source: 'TT-1763007625226-yn4xita3qylwh',
      leadName: 'João Silva',
      leadEmail: 'joao@email.com',
      leadPhone: '+5511999999999',
      leadDocument: '123.456.789-00',
    }),
  });
  ```

  ```php PHP theme={null}
  <?php
  $data = [
    'orderId'      => 'ORDER_123',
    'amount'       => 9990,
    'status'       => 'paid',
    'platform'     => 'CUSTOM',
    'utm_source'   => 'TT-1763007625226-yn4xita3qylwh',
    'leadName'     => 'João Silva',
    'leadEmail'    => 'joao@email.com',
    'leadPhone'    => '+5511999999999',
    'leadDocument' => '123.456.789-00',
  ];

  $ch = curl_init('https://api.xtracky.com/api/integrations/api');
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $http     = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  echo "HTTP $http\n$response\n";
  ```

  ```python Python theme={null}
  import requests

  payload = {
      'orderId': 'ORDER_123',
      'amount': 9990,
      'status': 'paid',
      'platform': 'CUSTOM',
      'utm_source': 'TT-1763007625226-yn4xita3qylwh',
      'leadName': 'João Silva',
      'leadEmail': 'joao@email.com',
      'leadPhone': '+5511999999999',
      'leadDocument': '123.456.789-00',
  }

  r = requests.post(
      'https://api.xtracky.com/api/integrations/api',
      json=payload,
  )
  print(r.status_code, r.json())
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  func main() {
      payload := map[string]interface{}{
          "orderId":      "ORDER_123",
          "amount":       9990,
          "status":       "paid",
          "platform":     "CUSTOM",
          "utm_source":   "TT-1763007625226-yn4xita3qylwh",
          "leadName":     "João Silva",
          "leadEmail":    "joao@email.com",
          "leadPhone":    "+5511999999999",
          "leadDocument": "123.456.789-00",
      }

      body, _ := json.Marshal(payload)
      resp, err := http.Post(
          "https://api.xtracky.com/api/integrations/api",
          "application/json",
          bytes.NewBuffer(body),
      )
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      fmt.Println("Status:", resp.Status)
  }
  ```
</CodeGroup>

## Parâmetros

### Obrigatórios

<ParamField path="orderId" type="string" required>
  Identificador único da venda no seu sistema. Reutilize o mesmo ao longo do ciclo (`waiting_payment` → `paid` → `refunded`).
</ParamField>

<ParamField path="amount" type="integer" required>
  Valor da venda **em centavos** (R\$ 99,90 → `9990`). Sempre inteiro.
</ParamField>

<ParamField path="status" type="enum" required>
  Um de: `waiting_payment`, `paid`, `initiate_checkout`, `failed`, `refunded`. Ver [Status de Pagamento](/conceitos/status-pagamento).
</ParamField>

<ParamField path="utm_source" type="string" required>
  O `LeadId` gerado pelo script V2 (ex: `TT-1763007625226-yn4xita3qylwh`) ou o valor do `utm_source` capturado da URL (V1).
</ParamField>

### Opcionais

<ParamField path="platform" type="string" default="CUSTOM">
  Nome da plataforma de origem. Detectado automaticamente pelo prefixo do `utm_source` no V2.
</ParamField>

<ParamField path="leadName" type="string">
  Nome completo do comprador. Melhora o matching na API de conversão da Meta.
</ParamField>

<ParamField path="leadEmail" type="string">
  E-mail do comprador. **Hash SHA-256 é aplicado automaticamente** antes de enviar pra Meta/TikTok/etc.
</ParamField>

<ParamField path="leadPhone" type="string">
  Telefone no formato E.164 (`+5511999999999`). Também é hasheado.
</ParamField>

<ParamField path="leadDocument" type="string">
  CPF ou CNPJ. Usado apenas pra dedup local, nunca enviado às redes de anúncio.
</ParamField>

<ParamField path="currency" type="string" default="BRL">
  Moeda ISO-4217. Padrão `BRL`. Suporta `USD`, `EUR`, `MXN`, etc.
</ParamField>

## Respostas

<AccordionGroup>
  <Accordion title="200 OK — Aceito">
    ```json theme={null}
    {
      "success": true,
      "eventId": "evt_01H8ZQXYAB1234",
      "dedupped": false
    }
    ```

    `dedupped: true` significa que o evento chegou mas foi ignorado por já ter sido processado.
  </Accordion>

  <Accordion title="400 Bad Request">
    ```json theme={null}
    {
      "success": false,
      "error": "invalid_status",
      "message": "status deve ser um de: waiting_payment, paid, initiate_checkout, failed, refunded"
    }
    ```
  </Accordion>

  <Accordion title="401 Unauthorized">
    ```json theme={null}
    {
      "success": false,
      "error": "invalid_token",
      "message": "Product ID não encontrado ou produto inativo"
    }
    ```
  </Accordion>

  <Accordion title="429 Too Many Requests">
    ```json theme={null}
    {
      "success": false,
      "error": "rate_limited",
      "retryAfter": 12
    }
    ```

    Retry após `retryAfter` segundos.
  </Accordion>
</AccordionGroup>

## Proteção contra duplicatas

Requisições com o mesmo `orderId` + `utm_source` são processadas apenas uma vez. Você pode reenviar à vontade — retries, replays de fila, testes — que a xTracky garante que o evento na plataforma de anúncio dispara apenas uma vez. Ver [Deduplicação](/conceitos/deduplicacao).
