Come collegare più modelli di AI a n8n con una sola API?
Collegare modelli di AI un provider alla volta può funzionare per un prototipo, ma diventa fragile con l’aumentare dell’uso. Ogni provider porta credenziali, endpoint, formati di richiesta, limiti di frequenza, fatturazione e strutture di risposta separati. In n8n, questo spesso crea nodi HTTP duplicati e rami specifici per provider, quindi aggiungere un modello o cambiare un percorso di fallback significa modificare diverse parti del workflow.
n8n e CometAPI risolvono livelli diversi di questo problema. n8n controlla quando eseguire un job, convalida gli input, instrada attività sincrone e asincrone, ritenta i fallimenti e memorizza i risultati. CometAPI centralizza l’accesso ai modelli dietro un’unica chiave API e un unico base URL. Insieme, mantengono i cambiamenti di provider fuori dallo strato di orchestrazione: puoi cambiare l’ID del modello preservando la stessa logica di coda, polling, storage e monitoraggio.
Questa combinazione è particolarmente utile per job misti di immagini e video provenienti da fogli di calcolo o strumenti interni. Il workflow resta visivo e verificabile in n8n, mentre credenziali, disponibilità dei modelli e costi di utilizzo diventano più facili da gestire tramite un unico strato API.
Il modo più semplice per integrare più provider di AI in un’unica app è separare l’orchestrazione dall’accesso ai modelli. Lascia che n8n gestisca trigger, diramazioni, ritentativi e storage, mentre CometAPI fornisce a ogni ramo un’unica chiave API e un unico base URL. L’ID del modello diventa un campo in ogni job anziché un account provider separato, un SDK e una configurazione di fatturazione.
In questa guida creerai una pipeline low-code funzionante che legge job di immagini e video da Google Sheets, li invia a modelli OpenAI e ByteDance tramite CometAPI, salva gli ID dei task video asincroni, esegue polling fino al completamento e upserta il risultato finale in una Data Table di n8n.
Cosa realizzerai
Il workflow finale segue questo percorso:
Google Sheets Trigger → Normalize Job → Switch per tipo di media → richiesta immagine o video a CometAPI → Attesa e polling dei task video → Carica o referenzia l’output → upsert nella Data Table.
Usa queste colonne nel foglio sorgente:
job_id | media_type | model | prompt | size | seconds | status
Una riga tipica per le immagini usa image, gpt-image-2 e 1024x1024. Una riga per i video usa video, seedance-2-5, 1280x720 e una durata da 4 a 30 secondi.
Prima di iniziare
Ti servono un’istanza n8n, un Google Sheet, una chiave API CometAPI e una Data Table di n8n chiamata ai_jobs. Crea queste colonne nella Data Table: job_id, media_type, model, status, task_id, result_url, error e updated_at.
Per n8n self-hosted, aggiungi i seguenti valori all’ambiente usato dal processo n8n:
COMETAPI_BASE_URL=https://api.cometapi.com/v1COMETAPI_KEY=your_cometapi_key
Riavvia n8n dopo aver modificato l’ambiente. In n8n Cloud, o quando non vuoi esporre variabili d’ambiente nelle espressioni dei nodi, crea una credenziale di tipo HTTP Header Auth chiamata CometAPI Bearer. Imposta il nome dell’header su Authorization e il valore su Bearer your_cometapi_key. Gli esempi sotto usano questa credenziale e il base URL compatibile con OpenAI fisso https://api.cometapi.com/v1.
Usa gli ID modello attuali
| Job | Provider e modello | Richiesta | Risultato |
|---|---|---|---|
| Immagine | OpenAI · gpt-image-2 | POST /v1/images/generations | Immagine base64 sincrona |
| Video | ByteDance · seedance-2-5 | POST /v1/videos | Task asincrono, poi polling |
Sia gli ID sia le capacità erano disponibili nella live CometAPI model directory API l’11 agosto 2026. Il modello di immagini supporta la generazione testo→immagine. Seedance 2.5 supporta la generazione testo→video e immagine→video, clip da 4 a 30 secondi e le dimensioni documentate 480p e 720p.
Prezzi al 11 agosto 2026: la pagina del modello GPT Image 2 indica $4 per milione di token in input e $24 per milione di token in output. La pagina del modello Seedance 2.5 indica $0,103 al secondo a 480p e $0,231 al secondo a 720p. I prezzi possono cambiare, quindi usa la directory modelli live o la pagina del modello come fonte di verità a runtime.
La differenza architetturale importante è che la generazione di immagini può essere gestita come operazione request-response, mentre la generazione di video va trattata come un job con stato. Salvare l’ID del task video prima del polling impedisce che un riavvio dell’esecuzione di n8n faccia perdere il job.
Crea il workflow in n8n
1. Attiva nuovi job da Google Sheets
Aggiungi un nodo Google Sheets Trigger e scegli Row added or updated. Puntalo al worksheet che contiene la tua coda di job. Aggiungi subito dopo il trigger un nodo IF e prosegui solo quando status è vuoto oppure uguale a queued. Questo evita che le righe completate vengano inviate di nuovo quando il foglio cambia.
2. Normalizza e valida ogni riga
Aggiungi un nodo Code chiamato Normalize Job. Questo nodo applica valori predefiniti sicuri, limita il workflow a ID modello approvati e produce gli stessi campi per entrambi i rami.
const row = $json;const allowedModels = { image: new Set(['gpt-image-2']), video: new Set(['seedance-2-5']),};const mediaType = String(row.media_type || '').trim().toLowerCase();if (!allowedModels[mediaType]) { throw new Error(`media_type must be image or video; received: ${row.media_type}`);}const defaultModel = mediaType === 'image' ? 'gpt-image-2' : 'seedance-2-5';const model = String(row.model || defaultModel).trim();if (!allowedModels[mediaType].has(model)) { throw new Error(`Model ${model} is not allowed for ${mediaType} jobs`);}const prompt = String(row.prompt || '').trim();if (!prompt) throw new Error('prompt is required');const seconds = mediaType === 'video' ? Number(row.seconds || 4) : null;if (mediaType === 'video' && (!Number.isInteger(seconds) || seconds < 4 || seconds > 30)) { throw new Error('Seedance 2.5 seconds must be an integer from 4 to 30');}return [{ json: { job_id: String(row.job_id || $execution.id), media_type: mediaType, model, prompt, size: String(row.size || (mediaType === 'image' ? '1024x1024' : '1280x720')), seconds, status: 'processing', updated_at: new Date().toISOString(), },}];
Aggiungi un nodo Switch dopo Normalize Job. Instrada image al ramo immagini e video al ramo video.
3. Genera immagini tramite un unico endpoint
Aggiungi un nodo HTTP Request chiamato Create Image con queste impostazioni:
- Metodo:
POST - URL:
https://api.cometapi.com/v1/images/generations - Autenticazione: la credenziale Header Auth
CometAPI Bearer - Tipo contenuto corpo: JSON
{ "model": "={{ $('Normalize Job').item.json.model }}", "prompt": "={{ $('Normalize Job').item.json.prompt }}", "size": "={{ $('Normalize Job').item.json.size }}"}
GPT Image 2 restituisce dati immagine base64. Aggiungi un nodo Code chiamato Prepare Image File per trasformare tali dati in un item binario di n8n:
const job = $('Normalize Job').item.json;const b64 = $json.data?.[0]?.b64_json;if (!b64) throw new Error('CometAPI returned no image data');return [{ json: { ...job, status: 'completed', task_id: '', result_url: '', error: '', updated_at: new Date().toISOString(), }, binary: { media: { data: b64, mimeType: 'image/png', fileName: `${job.job_id}.png`, }, },}];
Collega questo nodo al tuo nodo di object storage preferito, come S3 o Google Drive. Archivia l’URL del file restituito in result_url, quindi esegui l’upsert della riga in ai_jobs. Tieni i payload base64 voluminosi fuori dalla Data Table.
4. Crea un task video asincrono
Aggiungi un nodo HTTP Request chiamato Create Video:
- Metodo:
POST - URL:
https://api.cometapi.com/v1/videos - Autenticazione:
CometAPI Bearer - Tipo contenuto corpo: Form-Data
Aggiungi quattro campi form: model, prompt, seconds e size. Mappa i loro valori da Normalize Job.
Poi aggiungi un nodo Code chiamato Save Video Task:
const job = $('Normalize Job').item.json;const taskId = $json.id || $json.task_id;if (!taskId) throw new Error('Video task ID missing from create response');return [{ json: { ...job, task_id: taskId, status: $json.status || 'queued', result_url: '', error: '', updated_at: new Date().toISOString(), },}];
Esegui l’upsert di questo item in ai_jobs prima del polling. Salvare subito l’ID del task significa che un riavvio o timeout non fa perdere il job.
5. Attendi, esegui polling e archivia l’URL del video
Aggiungi un nodo Wait impostato a 15 secondi. Poi aggiungi un nodo HTTP Request chiamato Get Video:
- Metodo:
GET - URL:
=https://api.cometapi.com/v1/videos/{{ $json.task_id }} - Autenticazione:
CometAPI Bearer
Dopo la richiesta, usa un nodo Switch su status:
queuedoin_progress: ritorna al nodo Wait.completed: continua aFinalize Video.failedoerror: scrivi l’errore inai_jobse interrompi.
Aggiungi questo nodo Code per il ramo completato:
const prior = $('Save Video Task').item.json;const resultUrl = $json.video_url || $json.url || $json.data?.video_url;if (!resultUrl) throw new Error('Completed video response has no video URL');return [{ json: { ...prior, status: 'completed', result_url: resultUrl, error: '', updated_at: new Date().toISOString(), },}];
Esegui l’upsert dell’item finale in ai_jobs per job_id. Gli URL dei video CometAPI possono essere firmati e temporanei, quindi i workflow di produzione dovrebbero scaricare e ri-ospitare il file prima di salvare l’URL permanente. Se la tua app può ricevere richieste in ingresso, sostituisci il polling con un webhook dove il modello selezionato supporta i callback.
Mappa completa dei nodi
Il workflow completo può essere assemblato con i seguenti nodi:
- Google Sheets Trigger — Row added or updated
- IF — Elabora solo righe nuove o in coda
- Code — Normalize Job
- Switch — Immagine o video
- Ramo immagini: HTTP Request → Prepare Image File → Object Storage → Data Table Upsert
- Ramo video: HTTP Request → Save Video Task → Data Table Upsert → Wait → HTTP Request → Status Switch
- Video completato: Finalize Video → Object Storage o URL permanente → Data Table Upsert
- Video fallito: Set Error → Data Table Upsert
Per un ramo di fallimento, usa questa espressione in un nodo Edit Fields:
{ "job_id": "={{ $('Save Video Task').item.json.job_id }}", "status": "failed", "task_id": "={{ $('Save Video Task').item.json.task_id }}", "result_url": "", "error": "={{ $json.error?.message || $json.message || 'Video generation failed' }}", "updated_at": "={{ $now.toISO() }}"}
Testa il workflow
Aggiungi queste due righe al foglio sorgente:
img-001 | image | gpt-image-2 | A cinematic product photo of a glass robot on a dark desk | 1024x1024 | | queuedvid-001 | video | seedance-2-5 | A paper airplane flies through a sunlit studio, smooth tracking shot | 1280x720 | 4 | queued
La richiesta immagine dovrebbe restituire una struttura simile a:
{ "created": 1786400000, "data": [ { "b64_json": "iVBORw0KGgoAAA..." } ]}
La richiesta di creazione video dovrebbe restituire una struttura di task simile a:
{ "id": "video_task_abc123", "object": "video", "status": "queued", "progress": 0}
Dopo il polling, una risposta completata dovrebbe contenere lo stesso ID task, status: completed e un video_url. I campi opzionali esatti possono variare per modello, motivo per cui il codice di normalizzazione legge lo stato del task e l’URL del risultato stabili invece di copiare l’intera risposta del provider nel tuo database.
Errori comuni e soluzioni
| Errore | Soluzione |
|---|---|
| 401 Unauthorized | Verifica che il valore dell’Header Auth inizi con Bearer e che la chiave sia attiva. |
| 404 model or task not found | Controlla la directory modelli live e conferma che l’ID del task salvato sia usato in GET /v1/videos/{id}. |
| 400 invalid size or seconds | Usa una dimensione supportata e mantieni la durata di Seedance 2.5 tra 4 e 30 secondi. |
| 429 rate limited | Riduci la concorrenza di n8n e ritenta con backoff esponenziale e jitter. |
| Il polling non termina mai | Conserva il conteggio dei tentativi e interrompi dopo un timeout definito; tratta failed ed error come terminali. |
| Il payload immagine è troppo grande | Converti il base64 in binario, caricalo e salva solo l’URL permanente. |
Checklist per la produzione
Proteggi le credenziali. Conserva la chiave API nelle credenziali di n8n o in variabili d’ambiente lato server. Non inserirla nel foglio di calcolo né restituirla a un browser.
Rendi ogni job idempotente. Usa job_id come chiave di upsert nella Data Table. Prima di creare un nuovo task, salta le righe già contrassegnate come processing o completed.
Controlla polling e concorrenza. Esegui polling dei job video ogni 10–20 secondi, limita il numero di tentativi e limita le esecuzioni simultanee. Esegui backoff su risposte 429, 500 e 503 invece di creare task duplicati.
Convalida la policy dei modelli prima di ogni richiesta. Mantieni una allowlist per tipo di media. Aggiorna disponibilità e prezzi dei modelli dalla directory live su base programmata, ma distribuisci i cambiamenti ai modelli tramite revisione invece di consentire agli utenti del foglio di inviare ID arbitrari.
Tieni traccia del costo per job. Archivia modello, risoluzione, durata e campi di utilizzo con ogni risultato. Un job Seedance 2.5 da quattro secondi a 720p costa circa $0,924 al tasso indicato l’11 agosto 2026; gli stessi quattro secondi a 480p circa $0,412. Applica limiti massimi di durata e risoluzione prima di inviare la richiesta.
Ri-ospita i contenuti generati. Tratta gli URL firmati del provider come link di consegna, non come storage permanente. Scarica i media completati, caricali in un bucket sotto il tuo controllo e salva l’URL durevole più il checksum.
Mantieni una traccia di audit. Archivia il modello richiesto, i parametri sanificati, l’ID del task, le transizioni di stato, il conteggio dei ritentativi, il tempo di risposta e la posizione finale dell’asset. Non loggare chiavi API o prompt privati completi.
Perché questo pattern è scalabile
Il workflow resta semplice perché ogni nuovo provider o modello è una decisione di instradamento, non una nuova integrazione di account. Il foglio di calcolo rimane la coda dei job, n8n rimane lo strato di orchestrazione e CometAPI rimane l’unico strato di accesso. Aggiungi un modello estendendo la allowlist e la configurazione dei rami; trigger, persistenza dei task, polling, storage e logica di monitoraggio restano invariati.
Questa è la risposta pratica all’integrazione multi-provider di AI: un endpoint e una chiave controllati, instradamento esplicito dei modelli, percorsi sincroni e asincroni separati e una registrazione durevole per ogni job.
FAQ
n8n può chiamare più provider di AI tramite un’unica API?
Sì. Con uno strato API unificato come CometAPI, n8n può inviare richieste a diversi modelli supportati mantenendo centralizzati la credenziale del provider e l’integrazione HTTP.
Posso usare CometAPI con il nodo HTTP Request di n8n?
Sì. Il nodo HTTP Request può inviare richieste all’endpoint di CometAPI con l’autenticazione richiesta e i parametri specifici del modello.
n8n può cambiare automaticamente modello di AI quando uno fallisce?
Sì. Usa un ramo IF/Switch dopo la richiesta API e instrada i fallimenti ripetibili o specifici del modello verso un modello di fallback. Il fallback dovrebbe supportare la stessa modalità e le capacità richieste.
