Automações
Três endpoints para enviar arquivos, acompanhar o processo e receber cada resultado. O fluxo é criado exclusivamente no painel.
Nesta página
Contrato da integração
Base: https://duckfile.com/api/v1/external. Chamadas entre servidores com HTTPS e Bearer. O cliente não define etapas nem escolhe um destino de armazenamento.
| Método | Caminho | Finalidade |
|---|---|---|
| POST | /automations/:id/runs | Enviar arquivos e executar |
| GET | /runs/:id | Acompanhar processamento |
| GET | /runs/:id/files/:fileId | Receber arquivo processado |
Enviar arquivos e executar

POST/automations/:id/runs
Envia um arquivo ou lote à automação criada e publicada no painel. O formulário multipart contém a versão e os arquivos; a API confirma os envios internamente e inicia as etapas publicadas.
| Campo | Tipo | Descrição |
|---|---|---|
| id | UUID na URL | Automação da conta autorizada para a chave. |
| version | campo de texto | Número da versão publicada, copiado no painel. |
| files | um ou mais arquivos | Repita o campo para um lote. JPG, PNG, WebP ou AVIF estático. |
import { readFile, writeFile } from 'node:fs/promises';import { randomUUID } from 'node:crypto';const requestId = randomUUID(); // Persista antes de enviar.const form = new FormData();form.set('version', process.env.DUCKFILE_AUTOMATION_VERSION);form.append('files', new Blob([await readFile('imagem.png')], { type: 'image/png' }), 'imagem.png');if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') throw new Error('Mantenha a validação TLS habilitada.');const base = new URL(process.env.DUCKFILE_API_URL);if (base.protocol !== 'https:' || base.username || base.password || base.search || base.hash) throw new Error('Use HTTPS.');const response = await fetch(base.href.replace(/\/$/, "") + "/automations/UUID_DA_AUTOMACAO/runs", { method: "POST", headers: { Authorization: "Bearer " + process.env.DUCKFILE_API_KEY, "Idempotency-Key": requestId }, body: form, signal: AbortSignal.timeout(150000), redirect: 'error',});if (!response.ok) throw new Error('API: HTTP ' + response.status);const { data } = await response.json();Resposta parcial ilustrativa 202
{ "data": { "id": "UUID_DA_EXECUCAO", "version": 1, "status": "QUEUED", "expiresAt": null, "files": [ { "id": "UUID_DO_ARQUIVO", "status": "QUEUED", "partial": false, "errorCode": null, "result": null } ] }}HTTP 202 confirma recebimento e início; não é o resultado final. Preserve a Idempotency-Key e os mesmos arquivos para recuperar um envio interrompido. Não envie grafo, etapas, opções ou destino de armazenamento.
Acompanhar processamento

GET/runs/:id
Informa o estado autoritativo e o resultado de cada item, incluindo falhas parciais. Os adaptadores acompanham automaticamente até o estado final.
| Campo | Tipo | Descrição |
|---|---|---|
| id | UUID na URL | ID recebido no envio. |
| files[].result | objeto ou null | Quando pronto, informa nome, MIME, bytes e caminho para receber o arquivo. |
import { readFile, writeFile } from 'node:fs/promises';if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') throw new Error('Mantenha a validação TLS habilitada.');const base = new URL(process.env.DUCKFILE_API_URL);if (base.protocol !== 'https:' || base.username || base.password || base.search || base.hash) throw new Error('Use HTTPS.');const response = await fetch(base.href.replace(/\/$/, "") + "/runs/UUID_DA_EXECUCAO", { method: "GET", headers: { Authorization: "Bearer " + process.env.DUCKFILE_API_KEY }, signal: AbortSignal.timeout(150000), redirect: 'error',});if (!response.ok) throw new Error('API: HTTP ' + response.status);const { data } = await response.json();Resposta parcial ilustrativa 200
{ "data": { "id": "UUID_DA_EXECUCAO", "version": 1, "status": "COMPLETED", "expiresAt": "DATA_ISO", "files": [ { "id": "UUID_DO_ARQUIVO", "status": "COMPLETED", "partial": false, "errorCode": null, "result": { "name": "imagem.webp", "mimeType": "image/webp", "bytes": "12345", "path": "/runs/UUID_DA_EXECUCAO/files/UUID_DO_ARQUIVO" } } ] }}Resultados novos ficam disponíveis por até 15 minutos após concluir. Trate files[] por item e preserve os arquivos recebidos no seu próprio sistema.
Receber arquivo processado

GET/runs/:id/files/:fileId
Entrega diretamente os bytes de um resultado individual, usando Bearer na própria API HTTPS. Para lotes, receba cada item com result. A integração não precisa conhecer o armazenamento interno.
| Campo | Tipo | Descrição |
|---|---|---|
| id | UUID na URL | ID da execução autorizada. |
| fileId | UUID na URL | ID do item com resultado pronto nessa execução. |
import { readFile, writeFile } from 'node:fs/promises';if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') throw new Error('Mantenha a validação TLS habilitada.');const base = new URL(process.env.DUCKFILE_API_URL);if (base.protocol !== 'https:' || base.username || base.password || base.search || base.hash) throw new Error('Use HTTPS.');const response = await fetch(base.href.replace(/\/$/, "") + "/runs/UUID_DA_EXECUCAO/files/UUID_DO_ARQUIVO", { method: "GET", headers: { Authorization: "Bearer " + process.env.DUCKFILE_API_KEY }, signal: AbortSignal.timeout(150000), redirect: 'error',});if (!response.ok) throw new Error('API: HTTP ' + response.status);await writeFile('resultado.bin', Buffer.from(await response.arrayBuffer()));A resposta é o arquivo binário, com Content-Type, Content-Length e Content-Disposition. Não há envelope JSON. Os adaptadores recebem e salvam os resultados automaticamente; a biblioteca da conta não recebe esses arquivos.