JavaScript, Python e n8n
As receitas usam a API REST e seu próprio segredo. Salve um UUID em INFINITY_FLOW_REQUEST_KEY antes de executar; use o mesmo UUID e payload para retomar depois de uma resposta perdida. Os exemplos fazem trabalho real quando usados com credenciais de produção.
JavaScript no servidor
Seção intitulada “JavaScript no servidor”Node com fetch nativo. Não execute este código no navegador:
const base = 'https://infinityflow.stream/api/v1';const key = process.env.INFINITY_FLOW_API_KEY;const requestKey = process.env.INFINITY_FLOW_REQUEST_KEY;if (!key || !requestKey) throw new Error('Configure a chave e um UUID persistido.');
const headers = { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' };const payload = { prompt: 'Uma floresta ao amanhecer', mediaKind: 'video', aspect: '16:9' };const response = await fetch(`${base}/generations`, { method: 'POST', headers: { ...headers, 'Idempotency-Key': requestKey }, body: JSON.stringify(payload), signal: AbortSignal.timeout(30000),});const result = await response.json();if (!response.ok) throw new Error(JSON.stringify(result));const id = result.generation.id; // Persista este ID na sua tarefa.console.log({ id, state: result.generation.state });
// Repetir GET é seguro. Não repetir POST com outra chave.for (let attempt = 0; attempt < 120; attempt++) { await new Promise(resolve => setTimeout(resolve, 5000)); const statusResponse = await fetch(`${base}/generations/${id}`, { headers }); const status = await statusResponse.json(); if (!statusResponse.ok) throw new Error(JSON.stringify(status)); if (status.generation.state === 'succeeded') { const ticketResponse = await fetch(`${base}/generations/${id}/outputs/0/download-ticket`, { headers }); if (!ticketResponse.ok) throw new Error('Não foi possível obter o download.'); const { url } = await ticketResponse.json(); // Seu download seguinte usa url SEM headers de autenticação do Infinity Flow. const media = await fetch(url); if (!media.ok) throw new Error('Link expirou ou download falhou.'); // Grave media.body em seu armazenamento privado. Não registre url nos logs. break; } if (['failed', 'cancelled', 'attention_required'].includes(status.generation.state)) { console.log({ id, state: status.generation.state }); break; }}Se o loop terminar sem conclusão, mantenha o ID e consulte depois. Um timeout local não cancela nem recria o pedido. Em uma aplicação real, implemente backoff e persistência da tarefa.
Python sem dependências externas
Seção intitulada “Python sem dependências externas”import json, os, urllib.request
base = 'https://infinityflow.stream/api/v1'key = os.environ['INFINITY_FLOW_API_KEY']request_key = os.environ['INFINITY_FLOW_REQUEST_KEY'] # UUID salvo antes de executarpayload = {'prompt': 'Uma floresta ao amanhecer', 'mediaKind': 'video', 'aspect': '16:9'}request = urllib.request.Request( base + '/generations', data=json.dumps(payload).encode(), headers={'Authorization': 'Bearer ' + key, 'Content-Type': 'application/json', 'Idempotency-Key': request_key}, method='POST',)with urllib.request.urlopen(request, timeout=30) as response: generation = json.load(response)['generation']print({'id': generation['id'], 'state': generation['state']})# Salve generation['id']; consulte GET /generations/{id} para acompanhar.# Em timeout, conserve request_key/payload. Não gere outro UUID automaticamente.- Na origem da tarefa, persista
requestKeyUUID e o payload. Não use um UUID recalculado a cada retry ou o ID de execução como substituto do UUID. - Crie uma credencial Header Auth para
Authorization: Bearer ...no n8n; não escreva o segredo em campos exportáveis do workflow. - No HTTP Request, use
POST https://infinityflow.stream/api/v1/generations, JSON eIdempotency-Key: {{$json.requestKey}}. Mapeieprompt,mediaKindeaspectdos dados persistidos. - Grave
generation.idna tarefa antes do próximo passo. - Use Wait e
GET /generations/{id}para polling.succeededsegue para download;attention_required,failedecancelledseguem para acompanhamento, sem novo POST automático. - Obtenha
download-ticketautenticado. Baixe a URL em outro HTTP Request sem credencial Header Auth, salvando o arquivo binário antes de expirar.
Se habilitar retry do nó de criação, confirme que ele conserva o mesmo header de idempotência e o mesmo body. Nunca conecte o ramo de erro a um nó que cria outra chave para o mesmo pedido.