가이드
비동기 작업
긴 작업을 제출하고 상태를 폴링하며 종료 상태를 처리해 결과를 가져오세요.
일부 Felo 작업은 즉시 task_id를 반환하고 백그라운드에서 완료됩니다. 패턴은 어디서나 같습니다. 제출하고, 폴링하고, 결과를 가져옵니다.
두 가지 작업 계열
| 계열 | 제출 | 폴링 |
|---|---|---|
| Felo 워크플로 | POST /v2/ppts, POST /v2/landing_page, POST /v2/mindmap | GET /v2/tasks/{task_id}/status |
| 모델 생성 | POST /api/v1/videos/generations, POST /api/v1/images/generations | GET /api/v1/videos/generations/{task_id}, GET /api/v1/images/generations/{task_id} |
PPTX export는 별도의 비동기 작업입니다. POST /v2/ppts/{ppt_business_id}/export 후 GET /v2/ppts/{ppt_business_id}/export를 호출합니다.
SuperAgent는 폴링 API가 아닙니다. stream_key를 반환하고 SSE를 사용합니다. SuperAgent 참조를 확인하세요.
수명 주기
- 제출. 모델 또는 워크플로 파라미터를 보냅니다. 제출에 성공하면
task_id와 초기 상태가 반환됩니다. - 폴링. 일정 간격으로 task endpoint를 읽습니다. 간격과 최대 대기 시간을 코드에 두세요.
- 완료. 성공하면 결과 URL이나 출력 필드를 읽습니다. 실패하면 오류를 읽고 다시 제출할지 판단합니다.
상태 값
Felo 워크플로 작업은 대문자 값을 사용합니다.
| 상태 | 의미 |
|---|---|
RUNNING | 아직 처리 중 |
COMPLETED | 정상 완료 |
FAILED | 종료 상태의 실패. error_message를 읽으세요 |
PENDING | 이력 응답에서는 종료 상태. error_message를 읽으세요 |
EXPIRED | 종료 상태. 작업을 더 이상 사용할 수 없음 |
CANCELED | 종료 상태. 작업이 취소됨 |
모델 생성 작업은 소문자 값을 사용합니다: queued, running, succeeded, failed, interrupted. 실패한 작업에는 message와 type이 있는 error 객체가 포함될 수 있습니다.
백엔드가 발전하면서 알 수 없는 상태 값이 나타날 수 있습니다. 문서에 별도 설명이 없으면 알 수 없는 값을 종료 상태가 아닌 것으로 취급하세요.
폴링
- Felo 워크플로 작업: 2~5초마다.
- 비디오 생성: 5~10초마다.
- 이미지 생성: 2~5초로 시작하고 오래 걸리는 작업은 간격을 늘리세요.
- 종료 상태, 직접 정한 타임아웃, 또는 최대 시도 횟수에 도달하면 중지합니다.
- 여러 클라이언트가 동시에 폴링하면 jitter를 더하세요.
간단한 Node.js 루프:
async function pollStatus(taskId, { timeoutMs = 10 * 60 * 1000 } = {}) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const response = await fetch(`https://openapi.felo.ai/v2/tasks/${taskId}/status`, {
headers: { Authorization: `Bearer ${process.env.FELO_API_KEY}` },
});
if (!response.ok) throw new Error(`status ${response.status}`);
const payload = await response.json();
const status = payload.data?.status;
if (status === "COMPLETED") return payload.data;
if (["FAILED", "PENDING", "EXPIRED", "CANCELED"].includes(status)) {
throw new Error(payload.data?.error_message || status);
}
await new Promise((resolve) => setTimeout(resolve, 3000));
}
throw new Error("task timed out");
}결과 가져오기
| 작업 | 결과 |
|---|---|
| PPT | GET /v2/tasks/{task_id}/historical이 ppt_url, ppt_biz_id, 사용 가능한 경우 live_doc_url을 반환합니다 |
| Landing page | 이력 응답이 페이지 출력과 사용 가능한 경우 live_doc_url을 반환합니다 |
| 비디오 / 이미지 | 폴링 응답이 outputs를 반환합니다. 성공하면 각 항목은 익명으로 다운로드할 수 있는 서명된 미디어 URL입니다 |
| PPTX export | 폴링 응답은 status가 COMPLETED일 때만 download_url과 expires_at을 반환합니다 |
PPTX 서명 다운로드 URL은 발급 후 30분에 만료됩니다. GET endpoint를 다시 호출해 새 URL을 받으세요. 파일이 다시 생성되지는 않습니다.
실패 처리
- 재시도 전에 작업의 오류 필드를 읽으세요. 요청 자체가 원인인 실패는 반복됩니다.
- 타임아웃마다 무조건 다시 제출하지 마세요. 먼저 작업이 아직
RUNNING인지 확인하세요. 402는 크레딧 부족,429는 속도 제한입니다. 조건이 해소된 뒤에만 재시도하세요.- 비디오 및 이미지 생성의 callback 필드는 현재 무시됩니다. webhook을 기다리지 말고 task endpoint를 폴링하세요.