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

# AI Chat v2 API Integrazione Istruzioni

> AI Dialogue API guide - Ace Data Cloud

AI Chat v2 API (`/aichat2/conversations`) è la nuova generazione di interfaccia di dialogo, una versione completamente aggiornata dell'[AI Chat API](https://platform.acedata.cloud/documents/aichat-conversations). Si basa sulla semplicità e sulla gestione di conversazioni multi-turno della v1, espandendo:

* **Input utente multimodale**: tramite il campo `message` strutturato è possibile inviare direttamente testo + immagini + file, senza dover prima allegare indirettamente tramite `references`.
* **Chiamate a strumenti agent**: include un insieme di strumenti per ricerca online, scraping web, lettura di file, e può montare server MCP autorizzati dall'utente (Google Drive, Notion, Slack, GitHub, ecc.), il modello può chiamare autonomamente strumenti in più turni all'interno di una singola richiesta per completare compiti complessi.
* **Eventi strutturati in streaming**: tramite `accept: text/event-stream` o `application/x-ndjson` è possibile ricevere eventi come `text_delta`, `tool_use`, `tool_result`, `thinking`, `citation`, `card`, `artifact`, ecc., facilitando il rendering front-end per tipo corrispondente.
* **Interrompibile / Recuperabile**: il modello emetterà un evento `ask_user_question` e si fermerà quando ha bisogno di ulteriori informazioni dall'utente; la prossima chiamata può continuare riempiendo la risposta tramite `tool_results`.
* **Nuove azioni CRUD**: completare `retrieve` / `retrieve_batch` / `update` / `delete` tramite il campo `action` sullo stesso endpoint, senza necessità di un'API di gestione delle sessioni aggiuntiva.
* **Elenco di modelli in continuo aggiornamento**: accesso predefinito a GPT-5.4, Claude Opus 4.8, Claude Sonnet 4.6, Gemini 3.1 Pro, GLM 5.1, DeepSeek V4, Kimi K3 e altri modelli contemporanei.

Inoltre, a livello del corpo della richiesta, è **completamente retrocompatibile con v1**: basta inviare `model` + `question` (+ opzionale `stateful` / `id` / `references` / `preset`) per ottenere una risposta JSON `{answer, id}` equivalente a v1, quindi non è necessario riscrivere il client per migrare da `/aichat/conversations`, basta cambiare il percorso in `/aichat2/conversations`.

> Se attualmente stai utilizzando `/aichat/conversations`, l'interfaccia precedente rimarrà attiva, puoi migrare al tuo ritmo.

## Processo di Richiesta

Per utilizzare l'AI Chat v2 API, prima vai al [Pannello di Controllo di Ace Data Cloud](https://platform.acedata.cloud/console/applications) per ottenere il tuo API Token, da tenere come riserva.

![](https://cdn.acedata.cloud/5hmkdg.jpg)

Se non hai ancora effettuato il login o registrato, verrai automaticamente reindirizzato alla pagina di login che ti invita a registrarti e accedere; una volta completato, verrai riportato automaticamente alla pagina corrente.

**Un API Token è sufficiente per accedere a tutti i servizi della piattaforma, senza necessità di richiederne uno separato per ogni servizio.** La prima richiesta ti darà un credito gratuito, per un'esperienza senza costi; quando il credito è insufficiente, puoi ricaricare il saldo generale nel [pannello di controllo](https://platform.acedata.cloud/console/coin).

> 📘 Documentazione completa: [AI Chat v2 API →](https://platform.acedata.cloud/documents/aichat2-conversations)

## Utilizzo di Base

L'uso più semplice è identico a v1: invia `model` + `question` e ricevi `{answer, id}`.

Esempio CURL:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "question": "Introduci AceDataCloud in una frase."
  }'
```

Risultato di ritorno:

```json theme={null}
{
  "answer": "AceDataCloud è una piattaforma API unificata che aggrega modelli AI mainstream e servizi multimodali, consentendo agli sviluppatori di accedere a GPT, Claude, Gemini, Midjourney, Suno, Veo e altri servizi tramite una chiave.",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Esempio Python:

```python theme={null}
import requests

url = "https://api.acedata.cloud/aichat2/conversations"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json",
}

payload = {
    "model": "gpt-5.4",
    "question": "Introduci AceDataCloud in una frase.",
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
```

I valori disponibili per `model` possono essere visualizzati direttamente nel menu a discesa del pannello Try a destra, le categorie comuni includono:

* OpenAI: `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5.2-pro`, `gpt-5.1-all`, `gpt-5-all`, `gpt-4.1`, `gpt-4o`, `gpt-4o-image`, `o3`, `o4-mini`, ecc.
* Anthropic: `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6`, `claude-opus-4-5-20251101`, `claude-sonnet-4-6`, `claude-sonnet-4-5-20250929`, `claude-haiku-4-5-20251001`, ecc.
* Google: `gemini-3.1-pro`, `gemini-3.1-pro-preview`, `gemini-3.1-flash-image-preview`, `gemini-3-pro-preview`, `gemini-2.5-flash-lite`, ecc.
* xAI: `grok-4`, ecc.
* DeepSeek: `deepseek-v4-flash`, `deepseek-v3.2-exp`, `deepseek-r1-0528`, ecc.
* Moonshot: `kimi-k3`, `kimi-k2.6`, `kimi-k2.5`, ecc.
* Zhipu: `glm-5.1`, `glm-5`, `glm-5-turbo`, `glm-4.7`, `glm-4.5v`, ecc.

Le specifiche regole di fatturazione possono essere consultate nella scheda Pricing della pagina dei servizi.

## Conversazione Multi-turno

Come per v1, invia `stateful: true` per attivare il salvataggio della sessione, l'API restituirà un `id`; le richieste successive devono includere l'`id` per continuare la conversazione, senza necessità di mantenere la cronologia dei messaggi.

Prima richiesta:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "question": "Ricorda un numero: 42."
  }'
```

Risposta:

```json theme={null}
{
  "answer": "Va bene, ho già memorizzato 42. Cosa devo farne?",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Seconda richiesta, porta lo stesso `id`:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
    "question": "Qual è il numero che ti ho appena chiesto di ricordare?"
  }'
```

```json theme={null}
{
  "answer": "Il numero che mi hai chiesto di ricordare è 42.",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

> `stateful` è impostato su `true` per impostazione predefinita; omettere e specificare esplicitamente `true` è equivalente. Se non desideri che il server salvi questo turno di conversazione, puoi impostare esplicitamente `stateful: false`.

## Risposta in streaming

v2 supporta due formati di streaming, a seconda dell'intestazione `accept`:

| Scenari                                  | `accept`                         | Forma dei dati                                       |
| ---------------------------------------- | -------------------------------- | ---------------------------------------------------- |
| Frontend Web / EventSource               | `text/event-stream`              | `data: {json}\n\n`, l'ultima riga `data: [DONE]\n\n` |
| Server / CLI / Parsing in streaming Node | `application/x-ndjson`           | Un oggetto JSON per riga                             |
| Non è necessario lo streaming            | `application/json` (predefinito) | Restituzione unica di `{answer, id}`                 |

### Esempio NDJSON

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

url = "https://api.acedata.cloud/aichat2/conversations"

headers = {
    "accept": "application/x-ndjson",
    "authorization": "Bearer {token}",
    "content-type": "application/json",
}

payload = {
    "model": "gpt-5.4",
    "stateful": True,
    "question": "Presenta Hangzhou in tre frasi.",
}

with requests.post(url, json=payload, headers=headers, stream=True) as resp:
    answer = ""
    for line in resp.iter_lines():
        if not line:
            continue
        event = json.loads(line)
        if event.get("type") == "text_delta":
            # Compatibile con v1: frammenti incrementali forniti anche tramite il campo delta_answer
            answer += event["content"]
            print(event["delta_answer"], end="", flush=True)
        elif event.get("type") == "done":
            print()
            print("uso =", event.get("usage"))
```

Ogni riga di NDJSON è un evento strutturato, il più comune è `text_delta`:

```json theme={null}
{"type":"text_delta","content":"杭","delta_answer":"杭","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"州","delta_answer":"州","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"是","delta_answer":"是","id":"f2f4b3e8-..."}
...
{"type":"done","conversation_id":"f2f4b3e8-...","usage":{"prompt_tokens":21,"completion_tokens":58,"total_tokens":79},"terminal_reason":"natural_stop"}
```

### Esempio SSE

Il lato browser utilizza `EventSource` e non supporta corpi di richiesta personalizzati, si consiglia di utilizzare `fetch` + analisi manuale per `\n\n`:

```javascript theme={null}
const resp = await fetch("https://api.acedata.cloud/aichat2/conversations", {
  method: "POST",
  headers: {
    accept: "text/event-stream",
    authorization: "Bearer {token}",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    model: "gpt-5.4",
    stateful: true,
    question: "Presenta Hangzhou in tre frasi.",
  }),
});

const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const blocks = buffer.split("\n\n");
  buffer = blocks.pop() ?? "";
  for (const block of blocks) {
    const dataLine = block.split("\n").find((l) => l.startsWith("data: "));
    if (!dataLine) continue;
    const payload = dataLine.slice(6);
    if (payload === "[DONE]") return;
    const event = JSON.parse(payload);
    if (event.type === "text_delta") process.stdout.write(event.content);
  }
}
```

### Tipi di eventi in streaming

| `type`              | Significato                                                                                                                                                                                                                       |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text_delta`        | Frammenti di testo incrementali della risposta dell'assistente. `content` è il contenuto aggiunto; per compatibilità con v1, lo stesso evento include anche `delta_answer` (uguale a `content`) e `id`.                           |
| `thinking`          | Processo di pensiero del modello (si verifica solo quando il modello selezionato espone il ragionamento).                                                                                                                         |
| `tool_use`          | Il modello decide di chiamare uno strumento, l'evento include `tool_id`, `tool_name`, `input`.                                                                                                                                    |
| `tool_result`       | Risultato dell'esecuzione dello strumento, abbinato all'ultima `tool_use` tramite `tool_id`, `is_error` indica se è fallito.                                                                                                      |
| `card`              | Scheda strutturata prodotta dallo strumento (come immagini, anteprime di link), adatta per il rendering diretto.                                                                                                                  |
| `citation`          | Utilizzato per fornire l'URL di origine del corrispondente frammento di testo.                                                                                                                                                    |
| `ask_user_question` | Il modello emette una richiesta di informazioni aggiuntive dall'utente, la conversazione entra nello stato `awaiting_user_input`, vedere sotto [Ripristinare la conversazione in pausa](#ripristinare-la-conversazione-in-pausa). |
| `artifact`          | Prodotti indipendenti generati dal modello (come blocchi di codice, documenti), possono essere salvati o scaricati.                                                                                                               |
| `system_message`    | Messaggi informativi di sistema (non contenuti dall'utente e dall'assistente), utilizzati solo per suggerimenti UI.                                                                                                               |
| `compact`           | Evento in cui il contesto interno è compresso, non richiede elaborazione speciale.                                                                                                                                                |
| `error`             | Si è verificato un errore in questo turno, `message` descrive il contenuto dell'errore.                                                                                                                                           |
| `done`              | Fine della risposta in streaming, include `usage` (che contiene `prompt_tokens` / `completion_tokens` / `total_tokens`) e `terminal_reason`.                                                                                      |

Per i client che si interessano solo alla risposta finale, concatenare tutti i `content` di `text_delta` è equivalente a `answer` nel formato `application/json`.

## Input multimodale

Se l'input dell'utente include immagini o file, passare `message` (array) al posto di `question`. Ogni elemento dell'array è un blocco di contenuto:

```json theme={null}
{
  "model": "gpt-5.4",
  "stateful": true,
  "message": [
    { "type": "text", "text": "Quante gatti ci sono in questa immagine?" },
    { "type": "image_url", "image_url": { "url": "https://cdn.acedata.cloud/cats.jpg" } }
  ]
}
```

Tipi di blocchi supportati:

* `text` — Testo normale, campo `text` obbligatorio.
* `image_url` — Immagine, campo `image_url.url` obbligatorio.
* `file_url` — File (PDF, CSV, TXT, ecc.), campo `file_url.url` obbligatorio.

### Relazione con `references` di v1

Per compatibilità con i client più vecchi, v2 riconosce ancora il campo `references: ["https://...", ...]`:

* L'estensione dell'URL è `jpg / jpeg / png / gif / bmp / webp / svg / heic / heif`, si trasforma automaticamente in un blocco `image_url`;
* Altre estensioni si trasformano in un blocco `file_url`;
* Se viene fornita anche una `question`, allora la si pone come un blocco `text` in precedenza.

Quindi, se si desidera migrare solo da v1 senza modificare il corpo della richiesta, basta cambiare il percorso in `/aichat2/conversations`, l'uso originale di `references` continuerà a funzionare.

Per un controllo più preciso (ad esempio, per inserire più immagini tra i testi, o se l'ordine è molto importante) si utilizza direttamente l'array `message`.

## Chiamata degli strumenti e MCP

Il punto centrale del miglioramento di v2 è che il modello può chiamare autonomamente strumenti per completare compiti a più fasi, **questo è attivato per impostazione predefinita**, non è necessario che il client faccia alcuna configurazione aggiuntiva nella richiesta. Scenari comuni:

* L'utente chiede "Aiutami a cercare quali nuove mostre ci sono a Shanghai" → il modello chiama la ricerca web integrata → organizza i risultati in una risposta.
* L'utente chiede "Leggi questo PDF e poi scrivi un riassunto" → il modello chiama file\_read → scrive il riassunto.
* L'utente ha già autorizzato Google Drive / GitHub / Notion, ecc. in [Connections](https://platform.acedata.cloud/connections) → il modello può chiamare gli strumenti MCP corrispondenti per leggere e scrivere i suoi dati.

Nella stream NDJSON / SSE, la chiamata degli strumenti viene presentata attraverso eventi di tipo `tool_use` e `tool_result`, ad esempio:

```json theme={null}
{"type":"tool_use","tool_id":"toolu_01ABCDEF","tool_name":"web_search","input":{"query":"上海 2026 春季展览"},"id":"f2f4b3e8-..."}
{"type":"tool_result","tool_id":"toolu_01ABCDEF","output":"...","is_error":false,"id":"f2f4b3e8-..."}
{"type":"text_delta","content":"目前","delta_answer":"目前","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"上海","delta_answer":"上海","id":"f2f4b3e8-..."}
...
```

Se non si desidera visualizzare i dettagli della chiamata degli strumenti nel frontend, è possibile ignorare gli eventi `tool_use` / `tool_result` / `card` / `citation`, l'output finale del modello continuerà a fluire attraverso `text_delta`.

`max_turns` può limitare quante volte il modello può chiamare strumenti autonomamente in questa richiesta, il limite predefinito è deciso dalla piattaforma. Impostarlo basso (ad esempio `max_turns: 1`) può forzare una risposta singola, non consentendo alcuna chiamata agli strumenti.

## Esecuzione asincrona e autorizzazione senza supervisione

Se la tua chiamata proviene da un Webhook di allerta, CI/CD, sistema di monitoraggio o altri compiti in background, puoi impostare `async: true` per far sì che l'interfaccia restituisca immediatamente l'ID del compito, continuando l'esecuzione in background:

```json theme={null}
{
  "model": "gpt-5.5",
  "async": true,
  "question": "Il mio servizio ha segnalato un allerta, usa WeChat personale per notificare il gruppo WeChat 'AceDataCloud team'..."
}
```

Esempio di risposta:

```json theme={null}
{
  "task_id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "conversation_id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "status": "queued"
}
```

Dopo, puoi usare `action: retrieve` + `id` per interrogare il risultato della conversazione; puoi anche fornire `callback_url`, dopo il completamento del compito la piattaforma invierà `{ status, answer, usage, error }` tramite POST al tuo indirizzo di callback. `callback_url` deve utilizzare `http` / `https`, e non può essere direttamente `localhost` o un indirizzo IP privato.

I compiti in background di solito non possono essere confermati da nessuno. Se desideri che alcune Skill o MCP Server eseguano azioni di invio, pubblicazione, scrittura, ecc. in modalità senza supervisione, specifica esplicitamente l'elenco di autorizzazione nel corpo della richiesta:

```json theme={null}
{
  "model": "gpt-5.5",
  "async": true,
  "allowed_skills": ["acedatacloud/personal-wechat"],
  "allowed_mcp_servers": [],
  "question": "Il mio servizio ha segnalato un allerta, usa WeChat personale per notificare il gruppo WeChat 'AceDataCloud team'..."
}
```

I valori in `allowed_skills` sono gli slug delle Skill connesse; i valori in `allowed_mcp_servers` sono gli slug dei MCP Server connessi. Le Skill / MCP Server non incluse nell'autorizzazione preventiva possono comunque solo visualizzare, eseguire dry-run o rifiutare l'esecuzione delle operazioni di scrittura in modalità senza supervisione.

Se hai bisogno di un controllo più dettagliato, puoi anche utilizzare l'oggetto equivalente `unattended_policy`:

```json theme={null}
{
  "unattended_policy": {
    "allowed_skills": ["acedatacloud/personal-wechat"],
    "allowed_mcp_servers": [],
    "expires_at": 1790000000
  }
}
```

L'autorizzazione preventiva è semplicemente questi due elenchi: un elenco vuoto non autorizza alcuna capacità, senza bisogno di ulteriori campi di attivazione.

Nota: l'autorizzazione preventiva rappresenta solo "questa richiesta consente a queste capacità di saltare la conferma umana in modalità senza supervisione". La Skill specifica deve comunque supportare `--unattended-confirm` o un meccanismo di sicurezza corrispondente; altrimenti continuerà a eseguire dry-run e non eseguirà direttamente le operazioni di scrittura.

## Ripristino di una conversazione sospesa

Alcuni strumenti possono far sì che il modello "riformuli la domanda all'utente", in questo caso il modello emetterà un evento `ask_user_question`, la conversazione sarà congelata nello stato `awaiting_user_input`:

```json theme={null}
{
  "type": "ask_user_question",
  "tool_id": "toolu_01XYZW",
  "tool_name": "ask_user_question",
  "question": "Vuoi che il rapporto generato sia in cinese o in inglese?",
  "options": ["中文", "英文"],
  "id": "f2f4b3e8-..."
}
```

Nel frontend, questo evento viene visualizzato come una scheda per consentire all'utente di scegliere una risposta, quindi si invia una nuova richiesta con lo stesso `id`, riempiendo la risposta tramite `tool_results`:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: text/event-stream' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
    "tool_results": [
      {
        "tool_use_id": "toolu_01XYZW",
        "output": "中文"
      }
    ]
  }'
```

Nel corpo della richiesta, `tool_use_id` **deve** essere completamente identico a `tool_id` al momento della sospensione; altrimenti restituirà 400. Quando ci sono `tool_results` nella richiesta, `question` / `message` / `references` verranno ignorati.

Se l'utente decide di rinunciare a questa domanda, basta inviare una nuova `question` / `message` e la piattaforma segnerà automaticamente la chiamata dello strumento sospesa come "saltata dall'utente".

## Gestione delle conversazioni (CRUD)

v2 offre una gestione leggera delle conversazioni attraverso il campo `action` sullo stesso endpoint, senza necessità di aprire un'API separata.

### `action: retrieve` —— Recupera una conversazione

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "action": "retrieve",
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
  }'
```

Restituisce il documento completo della conversazione (inclusa la cronologia `messages`, `model`, `title`, `tools_used`, ecc.).

### `action: retrieve_batch` —— Elenca i riassunti delle conversazioni

```json theme={null}
{
  "action": "retrieve_batch",
  "model_group": "chatgpt",
  "limit": 20,
  "offset": 0
}
```

Restituisce `{ items: [...], total }`. **Il riassunto non include `messages`**, adatto per un elenco laterale; se l'utente apre una conversazione, utilizzare `action: retrieve` per recuperare i suoi messaggi completi.

Parametri di filtro opzionali: `user_id`, `application_id`, `model_group`, `model`.

### `action: update` —— Modifica il titolo o riscrivi la cronologia

```json theme={null}
{
  "action": "update",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "title": "Piano di viaggio a Hangzhou"
}
```

`messages` può essere inviato, ma il server eseguirà un rigoroso controllo dello schema (deve essere nella forma `ToolUseContent` compressa), altrimenti restituirà 400. In generale, si consiglia di utilizzarlo solo per modificare il `title`.

### `action: delete` —— Elimina una conversazione

```json theme={null}
{
  "action": "delete",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Restituisce `{ id, success: true }`. Dopo l'eliminazione non può essere ripristinato, si prega di confermare prima di chiamare.

## Migrazione fluida da v1

Se stai già utilizzando [`/aichat/conversations`](https://platform.acedata.cloud/documents/aichat-conversations), la migrazione a v2 richiede quasi nessuna modifica al codice:

1. Cambia l'URL da `https://api.acedata.cloud/aichat/conversations` a `https://api.acedata.cloud/aichat2/conversations`.
2. Se in precedenza utilizzavi nomi di modelli v1 (come `gpt-3.5`, `gpt-4-browsing`, ecc.), si consiglia di passare a modelli contemporanei (come `gpt-5.4`, `claude-opus-4-8`, `gemini-3.1-pro`, ecc.) durante il passaggio a v2.
3. I campi del flusso NDJSON rimangono retrocompatibili: ogni evento `text_delta` porta ancora `delta_answer` e `id`, quindi i client che analizzano `delta_answer` riga per riga non necessitano di modifiche.

Dopo la migrazione, puoi abilitare le nuove funzionalità di v2 (input multimodale `message`, SSE, chiamate agli strumenti, CRUD `action`) secondo necessità.

## Gestione degli errori

Le risposte di errore sono uniformi:

```json theme={null}
{
  "error": {
    "code": "chat_error",
    "message": "il LLM upstream ha restituito un errore"
  },
  "trace_id": "2cf86e86-22a4-46e1-ac2f-032c0f2a4e89"
}
```

Errori comuni:

* `400 bad_request`: mancano campi obbligatori, `tool_use_id` non corrisponde, schema `messages` non valido, ecc.
* `401 invalid_token`: intestazione `authorization` non corretta.
* `404 not_found`: durante `action: retrieve / update / delete`, la conversazione corrispondente all'`id` non esiste.
* `429 too_many_requests`: attivato il limite di velocità.
* `500 chat_error`: errore del LLM upstream o `completion_tokens=0` in questo round (trattato come non consumato, non verrà addebitato).

Nella risposta in streaming, gli errori vengono inviati come `{"type":"error","message":"..."}` e subito dopo il flusso terminerà.

## Conclusione

L'API AI Chat v2, mantenendo la retrocompatibilità con v1, ha aggiornato le conversazioni da "domande e risposte singole / multiple" a "conversazioni osservabili in stile agente": input multimodale, chiamate agli strumenti, pause / ripristini, eventi strutturati in streaming, CRUD integrato. Si consiglia di utilizzare direttamente v2 per le nuove integrazioni; le integrazioni esistenti di v1 possono essere migrate in fasi. Se hai domande, non esitare a contattare il nostro team di supporto tecnico.
