Reten Docs
Atividades

Criar Atividades em Lote

Criar múltiplas atividades em uma única requisição.

POST /api/activities/bulk

Crie até 200 atividades em uma única requisição. Cada item segue o mesmo esquema do endpoint individual Criar Atividade.

Auth: Obrigatório — permissão activity:create

Corpo da Requisição

CampoTipoObrigatórioDescrição
itemsarraySimArray de objetos de atividade (mín. 1, máx. 200)

Cada item em items tem os mesmos campos que o corpo da requisição de Criar Atividade:

CampoTipoObrigatórioDescrição
typestringSimTASK
reasonstringSimCódigo do motivo: apenas letras minúsculas, dígitos e _ (^[a-z0-9_]+$), máximo de 100 caracteres. Um código que não está no catálogo de motivos do tenant é adicionado a ele na hora
channelstringSimSALESMAN, CALLCENTER
commerce_idUUIDCondicionalID do comércio alvo. Envie este campo ou commerce_external_id: pelo menos um é obrigatório. Se você enviar os dois, commerce_id prevalece
commerce_external_idstringCondicionalComércio alvo por ID externo (máximo de 255 caracteres). Se nenhum comércio o tiver, a API cria um comércio placeholder com esse ID externo
idempotency_keystringSimChave única por tenant (evita duplicados)
scheduled_atISO 8601SimQuando a atividade deve ser executada
intent_categorystringNãoONBOARDING, MARKETING, COLLECTION, RETENTION, NOTIFICATION, SURVEY ou VALIDATION. Padrão NOTIFICATION
suggested_execution_timeISO 8601NãoHorário sugerido para execução
user_statusstringNãoContexto de status do usuário
scoreintegerNãoPontuação de prioridade
assignment_reasonstringNãoMotivo da atribuição
activity_detailsobjectSim, para TASKAtribuição de rota e operador (ver Criar Atividade). Um item TASK sem este campo falha com validation_error

Exemplo

curl -X POST https://api.reten.ai/api/activities/bulk \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "type": "TASK",
        "reason": "monthly_visit",
        "channel": "SALESMAN",
        "commerce_id": "880e8400-e29b-41d4-a716-446655440000",
        "idempotency_key": "task-2025-01-15-001",
        "scheduled_at": "2025-01-16T09:00:00.000Z",
        "activity_details": {
          "assigned_route_id": "dd0e8400-e29b-41d4-a716-446655440000",
          "assigned_operator_id": "cc0e8400-e29b-41d4-a716-446655440000"
        }
      },
      {
        "type": "TASK",
        "reason": "monthly_visit",
        "channel": "CALLCENTER",
        "commerce_external_id": "SHOP-0042",
        "idempotency_key": "task-2025-01-15-002",
        "scheduled_at": "2025-01-16T09:00:00.000Z",
        "activity_details": {
          "assigned_route_external_id": "ROUTE-07",
          "assigned_operator_external_id": "AGENT-15"
        }
      }
    ]
  }'
const response = await fetch("https://api.reten.ai/api/activities/bulk", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <token>",
    "x-tenant-id": "<tenant-id>",
    "x-project-id": "<project-id>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    items: [
      {
        type: "TASK",
        reason: "monthly_visit",
        channel: "SALESMAN",
        commerce_id: "880e8400-e29b-41d4-a716-446655440000",
        idempotency_key: "task-2025-01-15-001",
        scheduled_at: "2025-01-16T09:00:00.000Z",
        activity_details: {
          assigned_route_id: "dd0e8400-e29b-41d4-a716-446655440000",
          assigned_operator_id: "cc0e8400-e29b-41d4-a716-446655440000",
        },
      },
      {
        type: "TASK",
        reason: "monthly_visit",
        channel: "CALLCENTER",
        commerce_external_id: "SHOP-0042",
        idempotency_key: "task-2025-01-15-002",
        scheduled_at: "2025-01-16T09:00:00.000Z",
        activity_details: {
          assigned_route_external_id: "ROUTE-07",
          assigned_operator_external_id: "AGENT-15",
        },
      },
    ],
  }),
});
const result = await response.json();
import requests

response = requests.post(
    "https://api.reten.ai/api/activities/bulk",
    headers={
        "Authorization": "Bearer <token>",
        "x-tenant-id": "<tenant-id>",
        "x-project-id": "<project-id>",
    },
    json={
        "items": [
            {
                "type": "TASK",
                "reason": "monthly_visit",
                "channel": "SALESMAN",
                "commerce_id": "880e8400-e29b-41d4-a716-446655440000",
                "idempotency_key": "task-2025-01-15-001",
                "scheduled_at": "2025-01-16T09:00:00.000Z",
                "activity_details": {
                    "assigned_route_id": "dd0e8400-e29b-41d4-a716-446655440000",
                    "assigned_operator_id": "cc0e8400-e29b-41d4-a716-446655440000",
                },
            },
            {
                "type": "TASK",
                "reason": "monthly_visit",
                "channel": "CALLCENTER",
                "commerce_external_id": "SHOP-0042",
                "idempotency_key": "task-2025-01-15-002",
                "scheduled_at": "2025-01-16T09:00:00.000Z",
                "activity_details": {
                    "assigned_route_external_id": "ROUTE-07",
                    "assigned_operator_external_id": "AGENT-15",
                },
            },
        ],
    },
)
result = response.json()

Resposta 201 Created

Depois que o corpo passa na validação, a API sempre responde 201 Created, mesmo que todos os itens falhem. Os itens são processados um de cada vez, em ordem, e um item que falha não afeta os demais. O corpo informa o resultado de cada item; index é a posição do item em items, contando a partir de 0.

CampoTipoDescrição
summaryobjectContadores: total (itens recebidos), created, skipped e failed
itemsarrayAtividades criadas: index, idempotencyKey, activityId
skippedarrayItens cuja idempotency_key já pertence a uma atividade do projeto ativo: index, idempotencyKey, existingActivityId. Nada é criado nem alterado, qualquer que seja o status dessa atividade
errorsarrayItens que falharam: index, idempotencyKey, error, message

error é um destes códigos, e message é a mensagem da API para esse item:

errorQuandoExemplo de message
validation_errorO item passa na validação do corpo, mas viola uma regra de criaçãoSe requiere al menos uno de los campos commerce_id o commerce_external_id., TASK activities require activityDetails, assigned_route_id is required for TASK activities
not_foundcommerce_id, assigned_route_id ou assigned_operator_id não existeCommerce not found, Route not found, Operator not found
creation_errorQualquer outra falha — por exemplo, a idempotency_key já é usada por uma atividade de outro projeto do tenantLa clave de idempotencia ya está en uso.

Uma idempotency_key já usada em outro projeto é informada como um item creation_error, nunca como um HTTP 409.

Exemplo para um lote de três itens: o primeiro é criado, o segundo tem uma idempotency_key que já existe no projeto e o terceiro referencia um comércio que não existe.

{
  "summary": {
    "total": 3,
    "created": 1,
    "skipped": 1,
    "failed": 1
  },
  "items": [
    {
      "index": 0,
      "idempotencyKey": "task-2025-01-15-001",
      "activityId": "ee0e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "skipped": [
    {
      "index": 1,
      "idempotencyKey": "task-2025-01-14-007",
      "existingActivityId": "ff0e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "errors": [
    {
      "index": 2,
      "idempotencyKey": "task-2025-01-15-003",
      "error": "not_found",
      "message": "Commerce not found"
    }
  ]
}

Respostas de Erro

StatusDescrição
400Corpo inválido: items está vazio ou tem mais de 200 elementos, ou um item tem um campo inválido ou ausente, ou um campo que o endpoint não aceita. Nada é criado
401Token de autenticação ausente ou inválido
403Falta a permissão activity:create