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

# Conectar via API

> Integre sistemas e scripts externos com os modelos do Symphony pelo endpoint de chat completions.

## O que é

Permite que sistemas e scripts externos conversem com os modelos do **Symphony** programaticamente, pelo endpoint de **chat completions**. Use esta integração para automações, back‑ends, testes (Postman) ou integrações com outras ferramentas.

## Pré-requisitos

* Conta ativa no **AI Symphony**.
* Uma **chave de API** (API Key) e/ou **token JWT**.
* O **ID da empresa** (`X-Enterprise-Id`).

## Como obter sua chave de API

<Steps>
  <Step title="Abra o AI Symphony">
    Acesse [symphony.fcamara.com.br](https://symphony.fcamara.com.br/).
  </Step>

  <Step title="Clique no seu nome de usuário">
    No canto inferior esquerdo.
  </Step>

  <Step title="Vá até Configurações" />

  <Step title="Acesse a aba Conta (ou Conexões)">
    Em **Chaves de API**, conforme a versão.
  </Step>

  <Step title="Crie e copie a chave">
    Clique em **Chave de API** (ou "API Key") e **copie** a chave gerada.
  </Step>
</Steps>

<Tip>Cole a chave **completa**, sem espaços extras ou aspas desnecessárias.</Tip>

## Endpoint da API

* **Endpoint:** `POST https://symphony.fcamara.com/api/chat/completions`
* **Autenticação:** `Authorization: Bearer <token>` (token obtido no Symphony).

### Headers obrigatórios

```http theme={null}
POST /api/chat/completions HTTP/1.1
Host: symphony.fcamara.com
Content-Type: application/json
Authorization: Bearer {JWT_TOKEN}
X-CSRF-Token: {CSRF_TOKEN}
X-Enterprise-Id: fcamara-0000-0000-0000-000000000001
```

| Header            | Descrição                                                        |
| ----------------- | ---------------------------------------------------------------- |
| `Authorization`   | Token JWT do usuário (`Bearer eyJhbGciOi...`).                   |
| `X-CSRF-Token`    | Token CSRF para proteção (obrigatório em POST/PUT/PATCH/DELETE). |
| `X-Enterprise-Id` | ID da empresa/tenant.                                            |
| `Content-Type`    | `application/json`.                                              |

## Estrutura do corpo (JSON)

### Campos obrigatórios

| Campo        | Tipo          | Descrição                                                                                  |
| ------------ | ------------- | ------------------------------------------------------------------------------------------ |
| `id`         | string (UUID) | ID único da **mensagem** (UUID v4).                                                        |
| `chat_id`    | string (UUID) | ID da **conversa**; todas as mensagens da mesma conversa usam o mesmo valor.               |
| `session_id` | string        | ID da **sessão** do usuário.                                                               |
| `model`      | string        | ID do modelo LLM, no formato `provider.model-name` (ex.: `azure.gpt-5-chat`).              |
| `stream`     | boolean       | `true` = resposta em streaming; `false` = resposta completa de uma vez.                    |
| `messages`   | array         | Mensagens da conversa; cada item tem `role` (`user`, `assistant` ou `system`) e `content`. |

### Campos recomendados

| Campo            | Tipo   | Descrição                                                                                |
| ---------------- | ------ | ---------------------------------------------------------------------------------------- |
| `params`         | object | Parâmetros do modelo: `temperature` (0.0–2.0), `max_tokens`, `top_p` (0.0–1.0).          |
| `tool_servers`   | array  | Servidores de ferramentas; vazio se não usar ferramentas.                                |
| `features`       | object | Recursos habilitados: `image_generation`, `code_interpreter`, `web_search` (true/false). |
| `variables`      | object | Variáveis de contexto (ex.: `{{USER_NAME}}`, `{{CURRENT_DATE}}`, `{{USER_LANGUAGE}}`).   |
| `model_item`     | object | Detalhes do modelo (`id`, `name`, `owned_by`, `info`).                                   |
| `stream_options` | object | Opções de streaming, ex.: `include_usage` (incluir estatísticas de uso).                 |

### Exemplo completo

```json theme={null}
{
  "id": "2e0aab0c-1202-48d4-8461-2a61f3f09a89",
  "chat_id": "ca49f9ae-c8fc-4a2c-807e-4ee1e73d4c01",
  "session_id": "mRiO2bEEkTnLsb8oAAPS",
  "model": "azure.gpt-5-chat",
  "stream": false,
  "messages": [
    { "role": "user", "content": "Olá chat." },
    { "role": "assistant", "content": "Olá! Como posso ajudá-lo?" },
    { "role": "user", "content": "Explique API" }
  ],
  "params": { "temperature": 0.7, "max_tokens": 2000 },
  "tool_servers": [],
  "features": {
    "image_generation": false,
    "code_interpreter": false,
    "web_search": false
  },
  "variables": {
    "{{USER_NAME}}": "Leonardo Pereira",
    "{{USER_LOCATION}}": "São Paulo, Brasil",
    "{{CURRENT_DATE}}": "2026-06-17",
    "{{USER_LANGUAGE}}": "pt-BR"
  },
  "model_item": {
    "id": "azure.gpt-5-chat",
    "name": "Azure gpt-5-chat",
    "owned_by": "openai"
  },
  "stream_options": { "include_usage": true }
}
```

### Resposta de sucesso (200 OK)

```json theme={null}
{
  "id": "chatcmpl-DXttDwwlWkL6YkzARekAPP2cuFUX2",
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "API significa Application Programming Interface..." },
      "finish_reason": "stop"
    }
  ],
  "model": "gpt-5-chat-2025-08-07",
  "usage": { "completion_tokens": 293, "prompt_tokens": 42, "total_tokens": 335 }
}
```

## Exemplo em Python

```python theme={null}
import requests
import uuid
from datetime import datetime
import pytz

BASE_URL = "https://symphony.fcamara.com"
JWT_TOKEN = "seu_token_jwt_aqui"
CSRF_TOKEN = "seu_csrf_token_aqui"
ENTERPRISE_ID = "fcamara-0000-0000-0000-000000000001"

now = datetime.now(pytz.timezone('America/Sao_Paulo'))

payload = {
    "id": str(uuid.uuid4()),
    "chat_id": str(uuid.uuid4()),
    "session_id": str(uuid.uuid4()),
    "model": "azure.gpt-5-chat",
    "stream": False,
    "messages": [{"role": "user", "content": "Explique API"}],
    "params": {},
    "features": {"image_generation": False, "code_interpreter": False, "web_search": False},
    "variables": {"{{USER_LANGUAGE}}": "pt-BR"},
    "stream_options": {"include_usage": True}
}

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {JWT_TOKEN}",
    "X-CSRF-Token": CSRF_TOKEN,
    "X-Enterprise-Id": ENTERPRISE_ID
}

response = requests.post(f"{BASE_URL}/api/chat/completions", json=payload, headers=headers)
if response.status_code == 200:
    data = response.json()
    print(data['choices'][0]['message']['content'])
    print(f"Tokens usados: {data['usage']['total_tokens']}")
else:
    print(f"Erro {response.status_code}:", response.json())
```

## Autenticação — obtendo os tokens

### Token JWT

1. Faça login na plataforma Symphony.
2. O token é armazenado em `localStorage` com a chave `token`.
3. Use‑o em todas as requisições autenticadas (`Authorization: Bearer <token>`).

### Token CSRF

Obrigatório para POST/PUT/PATCH/DELETE. Há duas formas:

<Tabs>
  <Tab title="Via endpoint (recomendado)">
    ```bash theme={null}
    curl -X GET https://symphony.fcamara.com/api/v1/configs/csrf-token \
      -H "Authorization: Bearer seu_token_aqui" \
      --cookie "token=seu_token_aqui"
    ```

    Resposta:

    ```json theme={null}
    { "csrf_token": "7cQ46iNeuCBKE71bs2yhWWPShYjJUlQ7ZTMn7q4Pk7o...." }
    ```
  </Tab>

  <Tab title="Via DevTools do navegador">
    Abra o DevTools (F12) → aba **Application → Cookies** → copie o valor do cookie `csrf_token`.
  </Tab>
</Tabs>

<Note>
  Se fizer requisições via cURL/API, inclua os headers `Authorization` e `X-CSRF-Token` e use `--cookie`/`withCredentials: true` para enviar os cookies.
</Note>

## Outros endpoints úteis

Todos exigem o header `Authorization: Bearer <chave>`.

| Ação                         | Método e endpoint                                                   |
| ---------------------------- | ------------------------------------------------------------------- |
| Listar modelos disponíveis   | `GET /api/models`                                                   |
| Configuração do servidor     | `GET /api/config`                                                   |
| Listar conversas do usuário  | `GET /api/v1/chats` (query `page`, padrão 1)                        |
| Criar nova conversa          | `POST /api/v1/chats/new`                                            |
| Dados do usuário atual       | `GET /api/v1/users/me`                                              |
| Permissões do usuário        | `GET /api/v1/users/permissions`                                     |
| Listar bases de conhecimento | `GET /api/v1/knowledge`                                             |
| Upload de documento          | `POST /api/v1/knowledge/upload` (multipart/form-data, campo `file`) |
| Listar ferramentas           | `GET /api/v1/tools`                                                 |
| Listar prompts               | `GET /api/v1/prompts`                                               |

## Erros comuns

| Código | Significado                     | Solução                                                              |
| -----: | ------------------------------- | -------------------------------------------------------------------- |
|    400 | Campos obrigatórios faltando    | Inclua `id`, `chat_id`, `session_id`, `model`, `stream`, `messages`. |
|    401 | Token ausente/inválido/expirado | Verifique o header `Authorization`.                                  |
|    403 | Sem permissão para o modelo     | Verifique as permissões do usuário para aquele modelo.               |
|    404 | Modelo não encontrado           | Confirme o `model` com `GET /api/models`.                            |
|    429 | Limite de requisições excedido  | Aguarde; implemente backoff exponencial; reduza a frequência.        |
|    500 | Erro no servidor                | Tente novamente e verifique os logs.                                 |

Estrutura de erro:

```json theme={null}
{ "detail": "Mensagem de erro descritiva" }
```

## Streaming (Server-Sent Events)

Para respostas em tempo real, envie `"stream": true` e leia o corpo em pedaços. As linhas começam com `data: ` e a transmissão termina em `data: [DONE]`; o conteúdo incremental está em `choices[0].delta.content`.

## Boas práticas de segurança

<Columns cols={2}>
  <Card title="Faça" icon="circle-check">
    * Armazene a chave em **variáveis de ambiente**.
    * Use **HTTPS** em todas as requisições.
    * Implemente **retry com backoff exponencial** e **timeouts** (≈30s).
    * **Valide** as respostas antes de processar.
  </Card>

  <Card title="Não faça" icon="circle-xmark">
    * Não exponha a chave no **código‑fonte**, em **URLs** ou parâmetros de query.
    * Não armazene a chave em **cookies** ou `localStorage`.
    * Não **compartilhe** a chave nem reutilize a mesma em vários ambientes.
  </Card>
</Columns>

## Limites e quotas

* **Rate limit:** varia conforme o plano (consulte o administrador).
* **Timeout:** \~30 segundos por requisição.
* **Tamanho máximo da requisição:** 10 MB.
* **Tamanho máximo da resposta:** sem limite fixo (depende do modelo).

## Perguntas frequentes

<AccordionGroup>
  <Accordion title="Qual modelo devo usar no campo model?">
    Um dos `id` retornados por `GET /api/models` (ex.: `azure.gpt-5-chat`).
  </Accordion>

  <Accordion title="Recebo 401 mesmo com a chave correta.">
    Confirme o prefixo `Bearer` e, em métodos POST, o header `X-CSRF-Token`.
  </Accordion>

  <Accordion title="Preciso do X-Enterprise-Id?">
    Sim — ele identifica a empresa/tenant da requisição.
  </Accordion>
</AccordionGroup>

## Limitações conhecidas

* O acesso a cada modelo depende das **permissões** da conta/empresa.
* Tokens **JWT/CSRF** expiram; renove‑os quando necessário.
* A lista de modelos muda conforme a configuração do administrador — consulte sempre `GET /api/models`.
