API 참조
ConvertFly REST API로 프로그램에서 파일을 변환, 최적화, 가공할 수 있어요. 작업과 태스크로 변환 파이프라인을 구성해 파일 가져오기, 처리, 결과 내보내기를 한 번의 요청으로 끝내세요.
https://convertfly.io/api/v1모든 엔드포인트는 이 기본 URL을 기준으로 해요. 요청과 응답은 JSON을 사용해요. 모든 타임스탬프는 UTC ISO 8601 형식이에요.
인증
모든 요청의 Authorization 헤더에 API 키를 포함해야 해요. 키는 cvfly_sk_로 시작하며 대시보드에서 만들 수 있어요.
Authorization: Bearer cvfly_sk_live_abc123def456...보안 팁: 클라이언트 측 코드에 API 키를 노출하지 마세요. 키는 환경 변수에 저장하고 API 호출은 서버에서 하세요.
키 권한 범위
API 키는 일부 작업으로 제한할 수 있어요. 권한 범위 목록 없이 만든 키에는 기본 권한 범위가 적용돼요.
| 권한 범위 | 접근 권한 |
|---|---|
| job:read | 작업 읽기(기본값) |
| job:write | 작업과 그 태스크 생성, 취소, 재시도, 삭제(기본값) |
| task:read | 태스크 읽기(기본값) |
| convert | 변환 실행(기본값) |
| api-key:read | API 키 목록 보기 |
| api-key:write | API 키 생성 및 폐기 |
| webhook:read | 웹훅 목록 보기 |
| webhook:write | 웹훅 생성 및 삭제 |
빠른 시작
세 단계로 PDF를 DOCX로 변환하세요. 작업을 만들고, 완료될 때까지 기다린 뒤, 결과를 다운로드하면 돼요.
변환 작업 만들기
curl -X POST https://convertfly.io/api/v1/jobs \
-H "Authorization: Bearer cvfly_sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"tasks": {
"import-file": {
"operation": "import/url",
"url": "https://example.com/report.pdf"
},
"convert": {
"operation": "convert",
"input": ["import-file"],
"output_format": "docx"
},
"export": {
"operation": "export/url",
"input": ["convert"]
}
}
}'const res = await fetch("https://convertfly.io/api/v1/jobs", {
method: "POST",
headers: {
"Authorization": "Bearer cvfly_sk_live_abc123...",
"Content-Type": "application/json",
},
body: JSON.stringify({
tasks: {
"import-file": {
operation: "import/url",
url: "https://example.com/report.pdf",
},
convert: {
operation: "convert",
input: ["import-file"],
output_format: "docx",
},
export: {
operation: "export/url",
input: ["convert"],
},
},
}),
});
const job = await res.json();
console.log(job.id); // "cmxr9k2p0..."
console.log(job.status); // "processing"import requests
resp = requests.post(
"https://convertfly.io/api/v1/jobs",
headers={"Authorization": "Bearer cvfly_sk_live_abc123..."},
json={
"tasks": {
"import-file": {
"operation": "import/url",
"url": "https://example.com/report.pdf",
},
"convert": {
"operation": "convert",
"input": ["import-file"],
"output_format": "docx",
},
"export": {
"operation": "export/url",
"input": ["convert"],
},
}
},
)
job = resp.json()
print(job["id"]) # "cmxr9k2p0..."
print(job["status"]) # "processing"완료 대기
작업 상태를 폴링하거나 웹훅으로 실시간 알림을 받으세요.
curl https://convertfly.io/api/v1/jobs/job_7kX9mP2qR \
-H "Authorization: Bearer cvfly_sk_live_abc123..."{
"id": "cmxr9k2p0",
"status": "finished",
"created_at": "2026-04-03T10:30:00Z",
"tasks": [
{
"name": "export",
"operation": "export/url",
"status": "finished",
"result": {
"files": [
{ "url": "https://files.convertfly.io/d/cmv.../result.docx?e=...&s=..." }
]
}
}
]
}결과 다운로드
내보내기 태스크 결과의 URL을 사용하세요. 다운로드 링크는 1시간 동안 유효하며, 파일은 업로드 후 24시간이 지나면 삭제돼요.
curl -o result.docx "https://files.convertfly.io/d/..."작업(Jobs)
작업(Job)은 변환 파이프라인을 이루는 하나 이상의 태스크(Task)를 담는 컨테이너예요. 작업 안의 태스크는 의존 순서대로 실행되며, 각 태스크는 input 필드로 이전 태스크의 출력을 참조할 수 있어요.
파이프라인 개념
일반적인 파이프라인은 import/url -> convert -> export/url 형태예요. 가져오기 -> 변환 -> 최적화 -> 워터마크 -> 내보내기처럼 여러 작업을 연결할 수도 있어요.
작업 상태
| 상태 | 설명 |
|---|---|
| waiting | 작업이 생성되어 처리 대기열에 있음 |
| processing | 하나 이상의 태스크가 실행 중 |
| finished | 모든 태스크가 성공적으로 완료됨 |
| error | 하나 이상의 태스크가 실패함 |
작업 만들기
/api/v1/jobstagstring작업을 정리하기 위한 선택적 라벨(예: batch-2026-04).
tasksobject필수태스크 이름과 태스크 정의의 맵이에요. 태스크 이름은 작업 안에서 고유해야 해요.
webhook_urlstring작업이 끝나면 job.finished 또는 job.failed 이벤트를 받을 URL이에요.
curl -X POST https://convertfly.io/api/v1/jobs \
-H "Authorization: Bearer cvfly_sk_..." \
-H "Content-Type: application/json" \
-d '{
"tag": "invoice-batch",
"tasks": {
"import-file": {
"operation": "import/url",
"url": "https://example.com/invoice.pdf"
},
"to-png": {
"operation": "convert",
"input": ["import-file"],
"output_format": "png",
"options": { "density": 300 }
},
"export": {
"operation": "export/url",
"input": ["to-png"]
}
}
}'{
"id": "cmxr9k2p0",
"tag": "invoice-batch",
"status": "processing",
"created_at": "2026-04-03T10:30:00Z",
"tasks": [
{ "name": "import-file", "operation": "import/url", "status": "finished" },
{ "name": "to-png", "operation": "convert", "status": "processing" },
{ "name": "export", "operation": "export/url", "status": "waiting" }
]
}예시: 여러 파일을 하나의 PDF로 병합
merge 작업은 두 개 이상의 입력(PDF 및/또는 이미지)을 하나의 PDF로 합쳐요. input 배열에 입력 태스크 이름을 순서대로 나열하세요.
curl -X POST https://convertfly.io/api/v1/jobs \
-H "Authorization: Bearer cvfly_sk_..." \
-H "Content-Type: application/json" \
-d '{
"tasks": {
"cover": {
"operation": "import/url",
"url": "https://example.com/cover.png"
},
"report": {
"operation": "import/url",
"url": "https://example.com/report.pdf"
},
"merge-all": {
"operation": "merge",
"input": ["cover", "report"]
},
"export": {
"operation": "export/url",
"input": ["merge-all"]
}
}
}'예시: 웹사이트 캡처
capture-website 작업은 입력 태스크가 필요 없어요. 공개 URL을 PDF, PNG 또는 JPG로 렌더링해요.
curl -X POST https://convertfly.io/api/v1/jobs \
-H "Authorization: Bearer cvfly_sk_..." \
-H "Content-Type: application/json" \
-d '{
"tasks": {
"capture": {
"operation": "capture-website",
"url": "https://example.com",
"output_format": "pdf",
"width": 1280
},
"export": {
"operation": "export/url",
"input": ["capture"]
}
}
}'작업 조회
/api/v1/jobs/:id작업 세부 정보와 모든 태스크의 상태를 가져와요.
curl https://convertfly.io/api/v1/jobs/job_7kX9mP2qR \
-H "Authorization: Bearer cvfly_sk_..."작업 목록
/api/v1/jobspageinteger페이지 번호(1부터 시작). 기본값: 1.
limitinteger페이지당 결과 수(1-100). 기본값: 20.
statusstring상태로 필터링: WAITING, PROCESSING, FINISHED, ERROR.
tagstring태그로 필터링.
curl "https://convertfly.io/api/v1/jobs?status=finished&per_page=5" \
-H "Authorization: Bearer cvfly_sk_..."{
"data": [ ... ],
"links": { "first": "?page=1&per_page=5", "last": "?page=9&per_page=5", "prev": null, "next": "?page=2&per_page=5" },
"meta": {
"page": 1,
"per_page": 5,
"total": 42
}
}작업 삭제
/api/v1/jobs/:id작업과 관련된 모든 파일을 함께 삭제해요. 실행 중인 태스크는 취소돼요. 삭제 후에는 되돌릴 수 없어요.
curl -X DELETE https://convertfly.io/api/v1/jobs/job_7kX9mP2qR \
-H "Authorization: Bearer cvfly_sk_..."완료 대기
/api/v1/jobs/:id/wait작업이 최종 상태(FINISHED 또는 ERROR)에 도달할 때까지 대기하는 롱 폴링 엔드포인트예요. 300초가 지나도 작업이 처리 중이면 202 Accepted로 시간 초과돼요.
curl "https://convertfly.io/api/v1/jobs/job_7kX9mP2qR/wait?timeout=120" \
-H "Authorization: Bearer cvfly_sk_..."태스크(Tasks)
태스크는 작업 안의 개별 단계예요. 각 태스크에는 이름(tasks 객체의 키), operation, 그리고 이전 태스크 이름을 참조하는 선택적 input 배열이 있어요.
태스크 필드
| 필드 | 유형 | 설명 |
|---|---|---|
| operation | string | 수행할 작업(작업 목록 참조) |
| input | string[] | 출력을 입력으로 사용할 태스크 이름 |
| output_format | string | 변환 작업의 대상 형식 |
| options | object | 작업별 설정(품질, 해상도 등) |
작업의 태스크 목록
/api/v1/jobs/:id/tasks{
"data": [
{
"name": "import-file",
"operation": "import/url",
"status": "finished",
"result": { "file_id": "file_Xk9m..." }
},
{
"name": "convert",
"operation": "convert",
"status": "finished",
"result": { "file_id": "file_Pm3n..." }
}
]
}태스크 조회
/api/v1/jobs/:job_id/tasks/:task_name태스크 취소
/api/v1/jobs/:job_id/tasks/:task_name/cancel실행 중이거나 대기 중인 태스크를 취소해요. 이 태스크에 의존하는 후속 태스크도 취소돼요.
실패한 태스크 재시도
/api/v1/jobs/:job_id/tasks/:task_name/retry상태가 ERROR인 태스크를 다시 시도해요. 과금 대상 태스크라면 크레딧이 다시 차감돼요.
파일 업로드
ConvertFly에 파일을 넣는 방법은 세 가지예요. 사용 사례에 가장 잘 맞는 방법을 선택하세요.
URL에서 가져오기
가장 간단한 방법이에요. ConvertFly가 공개적으로 접근 가능한 URL에서 파일을 다운로드해요.
{
"import-file": {
"operation": "import/url",
"url": "https://example.com/document.pdf",
"filename": "document.pdf",
"headers": {
"Authorization": "Bearer your-external-token"
}
}
}직접 업로드 (사전 서명 URL)
로컬 컴퓨터에 있는 파일용이에요. 두 단계로 진행돼요. 먼저 태스크를 만들어 사전 서명 업로드 URL을 받은 다음, 그 URL로 파일을 PUT하세요.
{
"upload-file": {
"operation": "import/upload",
"filename": "photo.jpg"
}
}# The task result will contain the presigned URL
curl -X PUT "https://files.convertfly.io/convertfly-files/..." \
-H "Content-Type: image/jpeg" \
--data-binary @photo.jpgBase64에서 가져오기
작은 파일(10 MB 미만)용이에요. 파일 내용을 요청에 직접 포함하세요.
{
"import-file": {
"operation": "import/base64",
"file": "JVBERi0xLjQKJcOkw7zD...",
"filename": "document.pdf"
}
}| 방법 | 최대 크기 | 적합한 경우 |
|---|---|---|
| import/url | 5 GB | 이미 온라인에 호스팅된 파일 |
| import/upload | 5 GB | 로컬 파일, 대용량 파일 |
| import/base64 | 10 MB | 작은 파일, 요청에 직접 포함 |
변환 옵션
각 작업은 고유한 옵션을 지원해요. 사용 가능한 모든 작업과 변환 형식 조합은 다음과 같아요.
사용 가능한 작업
| 작업 | 설명 | 크레딧 |
|---|---|---|
| import/upload | 사전 서명 URL로 파일 업로드 | 0 |
| import/url | URL에서 파일 가져오기 | 0 |
| import/base64 | base64 데이터에서 파일 가져오기 | 0 |
| convert | 형식 간 변환 | 1-4 |
| optimize | 파일 압축/최적화 | 1 |
| thumbnail | 썸네일 미리보기 생성 | 1 |
| merge | 여러 PDF 및/또는 이미지를 하나의 PDF로 병합 | 1 |
| watermark | 이미지, 동영상, PDF에 텍스트 또는 이미지 워터마크 추가 | 1 |
| split | PDF에서 페이지를 추출하거나 페이지마다 PDF 하나로 분할(ZIP) | 1 |
| rotate | PDF 페이지를 90, 180, 270도로 회전 | 1 |
| resize | 비율을 유지하며 너비, 높이 또는 비율로 이미지 크기 조절 | 1 |
| gif | 동영상 클립을 움직이는 GIF로 변환(시작 지점, 길이, fps, 너비) | 2 |
| ocr | PDF나 이미지의 텍스트 인식(14개 언어, OCR 페이지와 동일) | 3 |
| capture-website | 공개 웹사이트를 PDF, PNG 또는 JPG로 캡처 | 1 |
| metadata | 파일 메타데이터 추출 | 1 |
| export/url | 서명된 다운로드 URL 받기 | 0 |
| export/s3 | S3 버킷으로 바로 내보내기 | 0 |
지원되는 형식 조합
자주 쓰는 변환이에요. 형식은 파일에서 자동으로 감지되지만 input_format을 직접 지정할 수도 있어요.
| 범주 | 입력 형식 | 출력 형식 |
|---|---|---|
| 문서 | pdf, docx, doc, odt, rtf, txt, html | pdf, docx, odt, rtf, txt, html |
| 스프레드시트 | xlsx, xls, ods, csv | xlsx, ods, csv, pdf |
| 프레젠테이션 | pptx, ppt, odp | pptx, odp, pdf |
| 이미지 | jpg, png, gif, bmp, tiff, webp, svg, heic | jpg, png, gif, bmp, tiff, webp |
| 동영상 | mp4, avi, mov, mkv, webm | mp4, avi, mov, mkv, webm, gif |
| 오디오 | mp3, wav, ogg, flac, aac, m4a | mp3, wav, ogg, flac, aac |
품질 및 처리 옵션
변환 태스크의 options 객체에 전달하세요.
qualityinteger손실 압축 형식의 출력 품질(1-100). 기본값: 85.
densityinteger문서를 이미지로 변환할 때의 DPI. 기본값: 150.
widthinteger이 너비(픽셀)로 크기를 조정해요. height를 생략하면 가로세로 비율을 유지해요.
heightinteger이 높이(픽셀)로 크기를 조정해요. width를 생략하면 가로세로 비율을 유지해요.
pagesstring문서 작업의 페이지 범위. 예: 1-5, 1,3,5, all.
{
"convert-hq": {
"operation": "convert",
"input": ["import-file"],
"output_format": "png",
"options": {
"density": 300,
"quality": 95
}
}
}웹훅
웹훅 URL을 등록하면 작업이나 태스크의 상태가 바뀔 때 실시간 알림을 받을 수 있어요. 모든 페이로드는 HMAC-SHA256으로 서명되어 ConvertFly에서 보낸 것인지 확인할 수 있어요.
웹훅 만들기
/api/v1/webhooksurlstring필수웹훅 이벤트를 받을 HTTPS URL이에요.
eventsstring[]필수구독할 이벤트 유형이에요.
curl -X POST https://convertfly.io/api/v1/webhooks \
-H "Authorization: Bearer cvfly_sk_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/convertfly",
"events": ["job.finished", "job.failed"]
}'{
"data": {
"id": "wh_Abc123...",
"url": "https://your-app.com/webhooks/convertfly",
"events": ["job.finished", "job.failed"],
"signing_secret": "whsec_9f8e7d6c5b4a...",
"created_at": "2026-04-03T10:30:00Z"
}
}웹훅 목록
/api/v1/webhooks웹훅 삭제
/api/v1/webhooks/:id이벤트 유형
| 이벤트 | 발생 조건 |
|---|---|
| job.finished | 작업의 모든 태스크가 성공적으로 완료됨 |
| job.failed | 하나 이상의 태스크가 실패해 작업이 ERROR 상태임 |
| task.finished | 개별 태스크가 완료됨 |
| task.failed | 개별 태스크가 실패함 |
웹훅 페이로드
{
"event": "job.finished",
"timestamp": "2026-04-03T10:31:15Z",
"data": {
"id": "job_7kX9mP2qR",
"status": "finished",
"tasks": { ... }
}
}서명 확인
각 웹훅 요청에는 X-Webhook-Signature와 X-Webhook-Timestamp 두 헤더가 포함돼요. 이를 확인해 페이로드가 ConvertFly에서 보낸 것이며 변조되지 않았는지 확인하세요.
import crypto from "crypto";
function verifyWebhook(rawBody, signature, timestamp, secret) {
const signedContent = timestamp + "." + rawBody;
const expected = "v1=" + crypto
.createHmac("sha256", secret)
.update(signedContent)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}import hmac, hashlib
def verify_webhook(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool:
signed_content = f"{timestamp}.{raw_body.decode()}"
expected = "v1=" + hmac.new(
secret.encode(), signed_content.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)API 키
프로그램에서 API 키를 관리하세요. 대시보드에서도 키를 관리할 수 있어요.
API 키 만들기
/api/v1/api-keysnamestring필수키를 설명하는 이름이에요.
scopesstring[]부여할 권한이에요. 기본값: ["*"](전체 접근).
{
"data": {
"id": "key_Xk9m...",
"name": "production-server",
"key": "cvfly_sk_live_abc123def456...",
"scopes": ["*"],
"created_at": "2026-04-03T10:30:00Z"
}
}중요: 전체 API 키는 생성할 때 한 번만 표시돼요. 안전하게 보관하세요. 다시 가져올 수 없어요.
API 키 목록
/api/v1/api-keysAPI 키 폐기
/api/v1/api-keys/:id키를 즉시 무효화해요. 이 키를 사용하는 모든 요청은 401을 반환해요.
요청 한도
공정한 이용을 위해 API 요청에는 API 키별 요청 한도가 적용돼요. 한도를 넘으면 요청이 429 Too Many Requests를 반환해요.
기본 한도
각 API 키는 시간당 100건의 요청을 허용해요. 키 목록을 조회하면 키의 현재 한도와 기간이 rate_limit와 rate_limit_window(초)로 반환돼요. 더 높은 한도가 필요하면 문의하세요.
응답 헤더
API 키로 보낸 요청의 모든 응답에는 다음 헤더가 포함돼요:
X-RateLimit-Limit헤더현재 기간에 허용되는 최대 요청 수.
X-RateLimit-Remaining헤더현재 기간에 남은 요청 수.
X-RateLimit-Reset헤더기간이 초기화되는 Unix 타임스탬프.
Retry-After헤더다시 시도하기 전 기다려야 할 시간(초, 429 응답에만 포함).
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1743681600
Retry-After: 3600
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. 100 requests per 3600s allowed."
}오류
ConvertFly는 일반적인 HTTP 상태 코드를 사용해요. 모든 오류 응답은 기계가 읽을 수 있는 code와 사람이 읽을 수 있는 message를 포함한 일관된 형식을 따라요.
오류 응답 형식
{
"code": "INVALID_DATA",
"message": "Missing required field: output_format",
"details": {
"field": "output_format",
"reason": "required"
}
}오류 코드
| 코드 | HTTP | 설명 |
|---|---|---|
| INVALID_DATA | 400 | 잘못된 요청 본문 또는 매개변수 |
| UNAUTHENTICATED | 401 | API 키가 없거나 유효하지 않음 |
| FORBIDDEN | 403 | API 키에 이 작업에 필요한 권한 범위가 없음 |
| NOT_FOUND | 404 | 리소스가 존재하지 않거나 삭제됨 |
| CONFLICT | 409 | 리소스가 이미 존재하거나 작업이 현재 상태와 충돌함 |
| PAYLOAD_TOO_LARGE | 413 | 요청 본문이 허용되는 최대 크기를 초과함 |
| UNSUPPORTED_FORMAT | 422 | 요청한 변환을 지원하지 않음 |
| RATE_LIMIT_EXCEEDED | 429 | 요청 한도 초과, 요청 한도 참조 |
| INSUFFICIENT_CREDITS | 402 | 작업을 완료하기에 크레딧이 부족함 |
| SERVER_ERROR | 500 | 내부 서버 오류, 다시 시도하거나 지원팀에 문의하세요 |
| UNAVAILABLE | 503 | 서비스를 일시적으로 이용할 수 없음, 잠시 후 다시 시도하세요 |
오류 처리
const res = await fetch("https://convertfly.io/api/v1/jobs", {
method: "POST",
headers: {
"Authorization": "Bearer cvfly_sk_...",
"Content-Type": "application/json",
},
body: JSON.stringify({ tasks: { /* ... */ } }),
});
if (!res.ok) {
const error = await res.json();
console.error(`[${error.code}] ${error.message}`);
// "[INVALID_DATA] Missing required field: output_format"
return;
}
const { data: job } = await res.json();크레딧
각 작업에는 일정한 크레딧이 들어요. 가져오기와 내보내기 작업은 무료예요. 남은 잔액은 모든 API 응답의 X-Credits-Remaining 헤더에 포함돼요.
변환 유형별 크레딧 비용
| 작업 | 비용 | 예시 |
|---|---|---|
| 가져오기 / 내보내기 | 무료 | import/url, import/upload, export/url, export/s3 |
| 이미지 변환 | 1크레딧 | jpg를 png로, webp를 gif로, heic를 jpg로 |
| 오디오 변환 | 1크레딧 | mp3를 wav로, flac을 aac로 |
| 문서를 PDF로 | 1크레딧 | txt를 pdf로, html을 pdf로, md를 pdf로 |
| Office를 PDF로 | 2크레딧 | docx를 pdf로, pptx를 pdf로, xlsx를 pdf로 |
| 동영상 변환 | 2크레딧 | mp4를 webm으로, mov를 mp4로 |
| PDF를 Office로 | 4크레딧 | pdf를 docx로, pdf를 pptx로 |
| 최적화 | 1크레딧 | 이미지, PDF 압축 |
| 썸네일 | 1크레딧 | 미리보기 이미지 생성 |
| 병합 | 1크레딧 | 여러 PDF 합치기 |
| 워터마크 | 1크레딧 | 텍스트/이미지 오버레이 추가 |
| PDF 분할 | 1크레딧 | 1-3, 7페이지 추출 또는 페이지마다 파일 하나 |
| PDF 회전 | 1크레딧 | 모든 페이지 또는 선택한 페이지 돌리기 |
| 이미지 크기 조절 | 1크레딧 | 너비 1200 px, 50퍼센트 |
| GIF 만들기 | 2크레딧 | mp4 클립을 gif로, 동영상 변환 1회와 같은 가격 |
| 웹사이트 캡처 | 1크레딧 | URL을 PDF나 이미지로 렌더링 |
| OCR | 3크레딧 | 스캔한 PDF를 검색 가능하게 |
| 메타데이터 | 1크레딧 | 파일 정보 추출 |
잔액 확인
모든 API 응답에는 현재 잔액을 담은 X-Credits-Remaining 헤더가 포함돼요.
HTTP/1.1 201 Created
Content-Type: application/json
X-Credits-Remaining: 9847
X-Credits-Used: 2잔액이 부족해 작업을 완료할 수 없으면 API가 INSUFFICIENT_CREDITS 오류 코드와 함께 402를 반환해요. 결제 대시보드에서 크레딧을 충전하세요.
샌드박스
샌드박스 키를 사용하면 크레딧을 쓰지 않고 통합 기능을 처음부터 끝까지 구축하고 테스트할 수 있어요. "sandbox": true로 키를 만들면 cvfly_sk_ 대신 cf_test_로 시작해요. 세 가지 차이를 빼면 모든 것이 프로덕션과 똑같이 작동해요.
| 크레딧 | 차감되지 않아요. 잔액이 그대로 유지돼요. |
| 파일 크기 | 입력 파일은 최대 5 MB예요. |
| 출력 | 이미지, 동영상, PDF에는 "ConvertFly SANDBOX" 워터마크가 들어가요. |
curl -X POST https://convertfly.io/api/v1/api-keys \
-H "Authorization: Bearer YOUR_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Sandbox", "sandbox": true}'
# Response includes: "key": "cf_test_...", "is_sandbox": true