# Criar funil

`POST /api/v1/pipelines`

Cria um funil no workspace da chave e retorna suas etapas. Exige `settings.pipelines`.
`stages` define as etapas **ativas**, em ordem. Quando omitido ou vazio, cria `Leads`, `Qualificação`, `Proposta`, `Negociação` e `Fechamento`. O sistema acrescenta as etapas finais `Ganho` e `Perda`. Não envie etapas finais nem `isWon`/`isLost`: a API responde `400`.
O primeiro funil ativo torna-se o padrão do workspace. O limite de funis do plano se aplica; quando atingido, a API responde `409 QUOTA_EXCEEDED`. Qualquer `behaviors` exige `PIPELINE_BEHAVIORS`, ou a resposta será `400`.
Para usar `attendance_queue`, crie o funil primeiro. Depois configure `behaviors` e `attendanceQueueStageId` em `PATCH /api/v1/pipelines/{seq}`, usando uma etapa do próprio funil.

## Autenticação

Envie a chave em `Authorization: Bearer pf_live_…`.

## Corpo da requisição

Content-Type: `application/json`

```json
{
  "name": "Pós-venda",
  "description": "Clientes que já compraram",
  "stages": [
    {
      "name": "Onboarding",
      "color": "#3b82f6"
    },
    {
      "name": "Acompanhamento"
    }
  ]
}
```

### Campos

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `name` | `string` | Sim | Até 255 caracteres. |
| `description` | `string` | Não | Opcional. Objetivo do funil; usado como contexto pela CIA. Aceita null. Até 2000 caracteres. |
| `stages` | `array` | Não | Etapas ativas em ordem. Omitir ou enviar lista vazia cria as etapas padrão. O sistema acrescenta as etapas de ganho e perda. Aceita null. |
| `stages[].name` | `string` | Sim | Até 255 caracteres. |
| `stages[].color` | `string` | Não | Cor hexadecimal. Padrão: `#6366f1`. |
| `stages[].description` | `string` | Não | Opcional. Condição esperada para o negócio estar nesta etapa; usada como contexto pela CIA. Aceita null. Até 2000 caracteres. |
| `behaviors` | `array` | Não | Não configure `attendance_queue` na criação: exige uma etapa do próprio funil. Configure por `PATCH` depois de criar. Aceita null. |
| `pipelineType` | `string` | Não | Entrada legada, ignorada. Configure behaviors para definir o comportamento do funil. Valores: standard, recurring_clients. Aceita null. |
| `attendanceQueueStageId` | `string` | Não | A fila exige uma etapa já existente neste funil. Configure após a criação, com PATCH e behaviors. Aceita null. |

## Respostas

### 201

Criado: funil com todas as etapas.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `data` | `Pipeline` | Não |  |
| `data.id` | `string` | Não |  |
| `data.seq` | `integer` | Não | Número sequencial no workspace usado em `/api/v1/pipelines/{seq}`. |
| `data.position` | `integer` | Não | Ordem de exibição entre os funis ativos. |
| `data.name` | `string` | Não |  |
| `data.description` | `string` | Não | Aceita null. |
| `data.isDefault` | `boolean` | Não |  |
| `data.isArchived` | `boolean` | Não |  |
| `data.exitStageId` | `string` | Não | Aceita null. |
| `data.pipelineType` | `string` | Não | Derivado de `behaviors`; mantido por compatibilidade. Valores: standard, recurring_clients. |
| `data.behaviors` | `array` | Não |  |
| `data.attendanceQueueStageId` | `string` | Não | Aceita null. |
| `data.stages` | `array` | Não | Etapas em ordem: ativas primeiro, seguidas das etapas finais de ganho e perda. |
| `data.stages[].id` | `string` | Não | Identificador da etapa usado em `stageId` na API, por exemplo, em `POST /api/v1/deals`. |
| `data.stages[].seq` | `integer` | Não |  |
| `data.stages[].order` | `integer` | Não |  |
| `data.stages[].name` | `string` | Não |  |
| `data.stages[].color` | `string` | Não |  |
| `data.stages[].description` | `string` | Não | Condição esperada para o negócio estar nesta etapa. Usada como contexto pela CIA. Aceita null. |
| `data.stages[].isWon` | `boolean` | Não |  |
| `data.stages[].isLost` | `boolean` | Não |  |
| `data.stages[].isRequired` | `boolean` | Não |  |
| `data.stages[].requiredMilestoneFieldId` | `string` | Não | Aceita null. |
| `data.stages[].dealCount` | `integer` | Não | Formato: int64. |
| `data.createdAt` | `string` | Não | Formato: date-time. |
| `data.updatedAt` | `string` | Não | Formato: date-time. |
| `message` | `string` | Não | Aceita null. |

```json
{
  "type": "object",
  "properties": {
    "data": {
      "$ref": "#/components/schemas/Pipeline"
    },
    "message": {
      "type": "string",
      "nullable": true
    }
  }
}
```

### 400

Falha de validação dos campos; `fieldErrors` contém os erros.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 401

Chave ausente, malformada, desconhecida, revogada ou expirada, ou membro emissor inativo.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 403

Autenticado, mas sem acesso: falta de permissão (`FORBIDDEN`), recurso desligado no workspace (`FEATURE_DISABLED`) ou tentativa de acessar uma agenda não permitida.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 409

Conflito de estado, como um negócio aberto duplicado para o contato/funil, ou limite do plano atingido (`QUOTA_EXCEEDED`), como na criação de um funil além da cota.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 429

Limite de requisições excedido por workspace ou IP.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```
