빠른 시작
이 문서는 키 발급, 문서 업로드, 처리 시작, 결과 수신까지의 전체 과정을 송장을 예시로 설명합니다. 아직 curl을 설치하지 않았거나 키에 대한 환경 변수를 설정하지 않았다면 먼저 환경 설정을 참조하세요.
1단계 — API 키 발급
API 키는 계정의 프로필 설정 페이지의 API Key 항목에서 확인할 수 있습니다. v1 API는 유료 요금제가 필요합니다. 무료 요금제 키는 인증 검사를 통과하지만, 이후 모든 호출에서 plan_required 오류가 반환됩니다. 새로 생성되는 키는 itt_live_<16진수 64자> 형식입니다. 스크립트에 하드코딩되지 않도록 환경 변수로 내보내세요:
export API_KEY="itt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"2단계 — 문서 업로드
POST /api/v1/documents는 file 또는 서버가 대신 가져오는 url 중 하나를 받습니다. 둘 중 하나만 전달하세요. batch_name은 선택 사항입니다. 생략하면 API가 자동 생성하며, 함께 처리하려는 모든 문서는 동일한 batch_name을 공유해야 합니다. 이 예제는 자체 사이트에 호스팅된 실제 샘플 송장에 대해 url을 사용하므로, 로컬 파일 없이도 그대로 실행 가능합니다:
curl -X POST https://imagetotable.ai/api/v1/documents \
-H "Authorization: Bearer $API_KEY" \
-F "url=https://imagetotable.ai/static/samples/invoice.webp"import os
import requests
response = requests.post(
"https://imagetotable.ai/api/v1/documents",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
data={"url": "https://imagetotable.ai/static/samples/invoice.webp"},
)
print(response.json())const formData = new FormData();
formData.append("url", "https://imagetotable.ai/static/samples/invoice.webp");
const response = await fetch("https://imagetotable.ai/api/v1/documents", {
method: "POST",
headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
body: formData,
});
console.log(await response.json());로컬 파일을 사용하시나요? url 대신 멀티파트 file 필드를 사용하세요. batch_name, template_id, password를 포함한 전체 매개변수 목록은 문서 업로드 참조를 확인하세요.
응답은 새 문서의 ID와 해당 문서가 속한 배치를 반환합니다. batch_name을 저장해 두세요. 다음 두 단계에서 필요합니다:
{
"document_id": "3f9c9e2a-1b7d-4e2b-9a3e-2f5b6c7d8e9f",
"batch_name": "260716-4K9P",
"remaining_batch_capacity": 199
}이미지 대신 여러 페이지로 구성된 PDF를 업로드해도 동일하게 작동합니다. 단, document_id가 배열로 반환된다는 점이 다릅니다. 각 페이지가 독립적으로 처리되므로 페이지당 하나의 문서가 생성됩니다.
3단계 — 처리 시작
POST /api/v1/batches/{batch_name}/process가 추출을 시작합니다. 저장된 템플릿을 template_id로 지정하거나, 여기처럼 fields로 원하는 필드를 인라인으로 선언하여 일회성 실행을 할 수 있습니다:
curl -X POST https://imagetotable.ai/api/v1/batches/260716-4K9P/process \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": [
{"name": "invoice_number"},
{"name": "invoice_date"},
{"name": "vendor_name"},
{"name": "total_amount"}
]
}'import os
import requests
response = requests.post(
"https://imagetotable.ai/api/v1/batches/260716-4K9P/process",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"fields": [
{"name": "invoice_number"},
{"name": "invoice_date"},
{"name": "vendor_name"},
{"name": "total_amount"},
]
},
)
print(response.json())const response = await fetch("https://imagetotable.ai/api/v1/batches/260716-4K9P/process", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
fields: [
{ name: "invoice_number" },
{ name: "invoice_date" },
{ name: "vendor_name" },
{ name: "total_amount" },
],
}),
});
console.log(await response.json());이 호출은 즉시 크레딧을 차감하고 문서를 백그라운드 처리를 위해 대기열에 추가합니다:
{
"batch_name": "260716-4K9P",
"queued": 1,
"quality": "fast",
"webhook_registered": false
}fields와 template_id를 모두 생략하면 API가 자체적으로 적절한 열 이름을 추론합니다. quality도 선택 사항입니다. 생략하면 계정의 기본 속도/품질 설정이 사용됩니다(계정 설정 및 API 동작 참조). 여기서 webhook_registered: false는 이 특정 호출에 webhook_url이 포함되지 않았다는 의미일 뿐, 이 배치에 등록된 웹훅이 없다는 뜻은 아닙니다. PUT .../webhook을 통해 별도로 등록하는 경우 배치 참조를 확인하세요.
4단계 — 결과 폴링 및 확인
처리는 비동기 방식입니다. GET /api/v1/batches/{batch_name}을 폴링하여 all_done이 true가 될 때까지 기다리거나, 폴링 대신 웹훅을 등록하세요. 전체 생애주기는 비동기 작업 모델 가이드에서 확인할 수 있습니다.
완료되면 변환된 결과를 가져옵니다:
curl https://imagetotable.ai/api/v1/batches/260716-4K9P/results \
-H "Authorization: Bearer $API_KEY"import os
import requests
response = requests.get(
"https://imagetotable.ai/api/v1/batches/260716-4K9P/results",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.json())const response = await fetch("https://imagetotable.ai/api/v1/batches/260716-4K9P/results", {
headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());응답 JSON은 언어별 탭이 없습니다. 요청을 보낸 클라이언트에 따라 구조가 변경되지 않습니다:
{
"batch_name": "260716-4K9P",
"status": "succeeded",
"created_at": "2026-07-16T09:12:03Z",
"started_at": "2026-07-16T09:12:05Z",
"completed_at": "2026-07-16T09:12:14Z",
"documents": [
{
"document_id": "3f9c9e2a-1b7d-4e2b-9a3e-2f5b6c7d8e9f",
"filename": "invoice.jpg",
"status": "succeeded",
"created_at": "2026-07-16T09:12:03Z",
"started_at": "2026-07-16T09:12:05Z",
"completed_at": "2026-07-16T09:12:14Z",
"line_items": [
{
"invoice_number": "INV-1042",
"invoice_date": "2026-06-30",
"vendor_name": "Acme Supply Co.",
"total_amount": "1,284.50"
}
]
}
]
}completed_at은 문서가 succeeded, failed, canceled와 같은 최종 상태에 도달하면 설정됩니다. queued 또는 processing 상태인 동안에는 null로 유지되며, 배치 수준에서는 일부 문서가 먼저 완료되더라도 배치 내 모든 문서가 완료될 때까지 null로 유지됩니다.
다음 단계
여기서부터: 비동기 작업 모델에서 전체 상태 수명 주기를 확인하고, 웹훅으로 폴링 대신 알림을 받거나, API 참조에서 모든 엔드포인트의 전체 매개변수 목록을 확인하세요.