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

# Criar transações em lote

> Criar múltiplas transações em uma única chamada para cenários de alto volume — na API de monitoramento de transações gu1 para fraude e AML.

## Visão geral

Cria múltiplas transações em uma única operação em lote. Este endpoint é otimizado para alto volume.

**Limites:**

* **Um único lote:** até **100.000 transações** por requisição; corpo da requisição não deve exceder **50 MB**.
* **Múltiplos arquivos em uma chamada:** use `POST /transactions/batch/background-multi` com array `sources` (até **5 arquivos**, 100.000 transações cada); limite do corpo **150 MB**.
* **Carga por arquivos (multipart):** use `POST /transactions/batch/upload` para enviar arquivos CSV, Excel ou JSON diretamente; máx. **5 arquivos** por requisição. O limite por arquivo depende do seu [plano](#limites-por-plano).

**Comportamento (endpoint síncrono):**

* A API mantém a conexão aberta por até **30 segundos**.
* Se o lote **terminar em 30 segundos**, retorna **200** com o resumo completo (criadas, ignoradas, regras executadas, tempo, etc.).
* Se **ultrapassar 30 segundos**, retorna **202** com um `jobId` e continua processando em segundo plano. Ao terminar, o cliente é notificado no dashboard (e via socket em tempo real se conectado).

**Endpoints em segundo plano (sempre assíncronos):**

* `POST /transactions/batch/background` — Um único lote; retorna 202 imediatamente e notifica via socket ao terminar.
* `POST /transactions/batch/background-multi` — Múltiplos arquivos em uma requisição (máx. 5); retorna 202 e uma notificação quando todos forem processados.
* `POST /transactions/batch/upload` — **Multipart form-data:** envie um ou mais arquivos (CSV, Excel, JSON) no campo `file`; o servidor faz o parse e executa o mesmo fluxo. Ideal quando você tem arquivos em vez de JSON.

Ideal para: importar histórico, arquivos grandes (CSV, Excel, JSON), processadores de alto volume, migração de dados.

## Endpoints

```
POST http://api.gu1.ai/transactions/batch
POST http://api.gu1.ai/transactions/batch/background
POST http://api.gu1.ai/transactions/batch/background-multi
POST http://api.gu1.ai/transactions/batch/upload   (multipart/form-data)
```

## Carga por arquivos (multipart)

Use **`POST /transactions/batch/upload`** quando tiver arquivos CSV, Excel ou JSON e quiser que o servidor faça o parse. A requisição deve ser **`multipart/form-data`** (FormData), não JSON.

* **Máx. 5 arquivos** por requisição.
* **Formatos aceitos:** CSV (`.csv`), Excel (`.xlsx`, `.xls`), JSON (`.json`).
* **Limite de transações por arquivo** conforme o plano da organização (ver [Limites por plano](#limites-por-plano)).
* **Query:** `validateGap` (padrão `false`). Se você enviar `validateGap=true` com vários arquivos, a API verifica se não há intervalo de 30 minutos ou mais entre o fim de um arquivo e o início do próximo (por `transactedAt`). Se houver, retorna **400** com `code: "GAP_VALIDATION_REQUIRED"` e a lista de intervalos. Por padrão a validação está desativada; use `?validateGap=true` para ativá-la.

### Campos do form

| Campo                    | Tipo   | Obrigatório | Descrição                                                                           |
| ------------------------ | ------ | ----------- | ----------------------------------------------------------------------------------- |
| `file`                   | File   | Sim         | Um ou mais arquivos (CSV, Excel, JSON). Repita o campo `file` para vários arquivos. |
| `executeRules`           | string | Não         | `"true"` (padrão) ou `"false"`                                                      |
| `skipDuplicates`         | string | Não         | `"true"` (padrão) ou `"false"`                                                      |
| `validateExistingEntity` | string | Não         | `"true"` (padrão) ou `"false"`                                                      |

### Exemplo: envio com FormData (JavaScript)

```javascript theme={null}
const form = new FormData();
form.append('file', fileInput.files[0]);
form.append('executeRules', 'true');
form.append('skipDuplicates', 'true');
form.append('validateExistingEntity', 'true');

const response = await fetch('http://api.gu1.ai/transactions/batch/upload', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: form   // Não defina Content-Type; o navegador define o boundary multipart
});
const data = await response.json();
```

### Exemplo: cURL

```bash theme={null}
curl -X POST http://api.gu1.ai/transactions/batch/upload \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@transacoes.csv" \
  -F "executeRules=true" \
  -F "skipDuplicates=true"
```

## Limites por plano

O **máximo de transações por arquivo** (tanto no upload quanto no background-multi) depende do plano da organização:

| Plano                   | Máx. transações por arquivo |
| ----------------------- | --------------------------- |
| Freemium                | 4.000                       |
| Startup                 | 12.000                      |
| Growth                  | 30.000                      |
| Enterprise              | 100.000                     |
| Por uso (pay-as-you-go) | 100.000                     |

Se a carga batch estiver desabilitada para sua organização, os endpoints retornam **403**. Entre em contato com o suporte para habilitar ou alterar o plano.

## Modelos (templates)

Para montar arquivos CSV, Excel ou JSON que atendam ao esquema:

1. **Dashboard:** Em **Monitoramento de transações**, abra o modal **Carga em lote**. Use os botões **Baixar CSV**, **Baixar Excel** ou **Baixar JSON** para obter modelos com os cabeçalhos corretos e uma linha de exemplo. É a forma mais fácil de começar.
2. **Campos obrigatórios por linha:** Cada transação deve incluir pelo menos `externalId`, `type`, `amount` e `currency`. Recomendados: `transactedAt`, `status`, `originName`, `destinationName`, `description`. Esquema completo em [Criar transação](/pt/api-reference/transactions/create).
3. **CSV/Excel:** Os nomes das colunas podem ser camelCase (`externalId`, `transactedAt`) ou snake\_case (`external_id`, `transacted_at`); o servidor normaliza. Data em ISO 8601 (ex. `2025-01-15T10:30:00.000Z`).

Não há URL pública para baixar modelos fora do dashboard; use o modal de carga em lote para obter os modelos atualizados.

## Autenticação

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Corpo (sync e background)

<ParamField body="transactions" type="array" required>
  Array de objetos de transação (mín. 1, máx. 100.000 por requisição). Mesma estrutura de [Criar transação](/pt/api-reference/transactions/create). Corpo máx. 50 MB.

  **`exchangeRate` opcional por linha:** somente quando a conversão automática falha; ver [Conversão de moeda](/pt/api-reference/transactions/create#conversão-de-moeda).
</ParamField>

<ParamField body="executeRules" type="boolean" default="true">
  Se as regras são executadas para todas as transações do lote
</ParamField>

<ParamField body="skipDuplicates" type="boolean" default="true">
  Ignorar transações com `externalId` duplicado em vez de falhar todo o lote
</ParamField>

<ParamField body="validateExistingEntity" type="boolean" default="true">
  Com **`true`** (padrão no lote): por linha, cada lado (origem/destino) só é validado se você enviar pelo menos um identificador daquele lado (`*EntityId`, `*ExternalId` ou `*TaxId` na raiz). Cada campo enviado deve existir na org; senão **400** `INVALID_ENTITY_REFERENCES` e nenhuma linha criada (conforme `batchErrorHandling`). Ordem de auto-vinculação: entityId → externalId → taxId.

  Com **`false`**: comportamento permissivo como [Criar transação](/pt/api-reference/transactions/create) (padrão **`false`** lá).
</ParamField>

Se o passo 2 ou 3 tiver sucesso, preenche `*EntityId` e pode preencher nome/país a partir da entidade, como no create único.

Com lado vinculado (inclusive quando você já enviou `*EntityId`), **`originTaxId` / `originExternalId` e `destinationTaxId` / `destinationExternalId` são sempre sincronizados a partir da entidade** antes do insert — mesma denormalização canônica de [Criar transação — origem](/pt/api-reference/transactions/create#origem-entidade).

### Corpo (apenas background-multi)

<ParamField body="sources" type="array" required>
  Array de objetos: `{ "fileName": "opcional", "transactions": [ ... ] }`. Mín. 1, máx. 5 fontes. Cada `transactions`: máx. 100.000 (ou o limite do seu plano por arquivo). Corpo total máx. 150 MB.
</ParamField>

## Resposta 200 (concluído em 30 s)

<ResponseField name="success" type="boolean">
  Se a operação em lote foi concluída com sucesso
</ResponseField>

<ResponseField name="created" type="number">
  Número de transações criadas
</ResponseField>

<ResponseField name="skipped" type="number">
  Ignoradas (duplicados ou erros de validação)
</ResponseField>

<ResponseField name="failed" type="number">
  Falhas
</ResponseField>

<ResponseField name="transactions" type="array">
  Transações criadas
</ResponseField>

<ResponseField name="errors" type="array">
  Erros por transação: `index`, `externalId`, `error`, `code`
</ResponseField>

<ResponseField name="processingTime" type="string">
  Tempo total de processamento
</ResponseField>

## Resposta 202 (processamento > 30 s ou background)

<ResponseField name="jobId" type="string">
  Identificador do job; correlacione com a notificação em tempo real ao concluir
</ResponseField>

<ResponseField name="status" type="string">
  `"processing"`
</ResponseField>

<ResponseField name="message" type="string">
  Mensagem indicando que o processo continua em segundo plano e será notificado no dashboard
</ResponseField>

<ResponseField name="fileCount" type="number">
  (Apenas background-multi.) Número de arquivos em processamento
</ResponseField>

## Exemplo de uso

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST http://api.gu1.ai/transactions/batch \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "transactions": [
        {
          "externalId": "txn_001",
          "type": "PAYMENT",
          "amount": 50.00,
          "currency": "USD",
          "originExternalId": "customer_001",
          "destinationExternalId": "merchant_100",
          "channel": "web_browser"
        }
      ],
      "executeRules": true,
      "skipDuplicates": true
    }'
  ```

  ```python Python theme={null}
  import requests
  response = requests.post(
      'http://api.gu1.ai/transactions/batch',
      headers={'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'},
      json={
          'transactions': transactions,
          'executeRules': True,
          'skipDuplicates': True
      }
  )
  result = response.json()
  print(f"Criadas: {result['created']}, Ignoradas: {result['skipped']}, Falhas: {result['failed']}")
  ```
</CodeGroup>

## Erros

* **400** - Lote vazio ou tamanho excedido (máx. 100.000 por requisição)
* **413** - Corpo > 50 MB (ou 150 MB no multi). Dividir em lotes menores.

## Boas práticas

1. Respeitar limites: 100.000 por requisição, 50 MB (150 MB no multi).
2. Sempre usar `skipDuplicates: true`.
3. Para importação histórica: `executeRules: false` e opcionalmente `validateExistingEntity: false`.
4. Tratar 200 vs 202: 200 = resultado no corpo; 202 = job em background, aguardar notificação.
5. Validar campos obrigatórios conforme [Criar transação](/pt/api-reference/transactions/create).
6. Usar background-multi para muitos arquivos (até 10 em uma chamada).

## Próximos passos

* [Criar transação](/pt/api-reference/transactions/create) - Uma transação
* [Alterar status da transação](/pt/use-cases/transaction-monitoring/change-status-api) - Alterar status
* [Monitoramento de transações](/pt/use-cases/transaction-monitoring/overview) - Detecção de fraude
