{"openapi":"3.1.0","info":{"title":"StructDatafy API","description":"Document extraction, PDF filling, and Excel filling API","version":"1.0.0"},"paths":{"/v1/health":{"get":{"tags":["Health"],"summary":"Health Check","operationId":"health_check_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/keys":{"get":{"tags":["API Keys"],"summary":"List Api Keys","description":"List all API keys.","operationId":"list_api_keys_v1_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/APIKeyResponse"},"type":"array","title":"Response List Api Keys V1 Keys Get"}}}}}},"post":{"tags":["API Keys"],"summary":"Create Api Key","description":"Create a new API key. The full key is shown only once.","operationId":"create_api_key_v1_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/keys/{key_id}":{"delete":{"tags":["API Keys"],"summary":"Revoke Api Key","description":"Revoke an API key.","operationId":"revoke_api_key_v1_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/extract":{"post":{"tags":["Extract"],"summary":"Extract Document","description":"Extract structured data from document(s).\n\nReturns a clean `fields` dict with extracted key-value data, plus any `tables` found.\nAdd `detail=true` for the full AI output (entities, summary, primary/secondary entities).\nAdd `chunk_size` to get overlapping text chunks from the raw OCR.\n\n- Single file <=5 pages: synchronous (200)\n- Multiple files or >5 pages: async job (202), poll via /v1/jobs/{id}","operationId":"extract_document_v1_extract_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_extract_document_v1_extract_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/models":{"get":{"tags":["Extract"],"summary":"List Models","description":"List all available models.","operationId":"list_models_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/formats":{"get":{"tags":["Extract"],"summary":"List Formats","description":"List all supported file formats grouped by category.","operationId":"list_formats_v1_formats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/fill/pdf":{"post":{"tags":["Fill PDF"],"summary":"Fill Pdf","description":"Fill a PDF form using source documents, natural language instructions, or explicit mappings.\n\nThree ways to fill:\n1. **Source documents** — upload source doc(s), AI extracts and maps data to form fields\n2. **Instructions** — describe what to fill in plain language\n3. **Explicit mappings** — provide JSON {field_name: value} pairs\n\nAt least one of source_files, instructions, or field_mappings must be provided.","operationId":"fill_pdf_v1_fill_pdf_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_fill_pdf_v1_fill_pdf_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fill/excel":{"post":{"tags":["Fill Excel"],"summary":"Fill Excel","description":"Fill an Excel template using source documents, natural language instructions, or both.\n\nTwo ways to fill:\n1. **Source documents** — upload source doc(s), AI extracts and maps data\n2. **Instructions** — describe what to fill in plain language\n\nBoth can be combined. At least one must be provided.","operationId":"fill_excel_v1_fill_excel_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_fill_excel_v1_fill_excel_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs/{job_id}":{"get":{"tags":["Jobs"],"summary":"Get Job","description":"Get the status and result of a processing job.","operationId":"get_job_v1_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs":{"get":{"tags":["Jobs"],"summary":"List Jobs","description":"List jobs for the current API key.","operationId":"list_jobs_v1_jobs_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by type","title":"Type"},"description":"Filter by type"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs/{job_id}/download":{"get":{"tags":["Jobs"],"summary":"Download Job Result","description":"Download the filled file for a completed fill job.","operationId":"download_job_result_v1_jobs__job_id__download_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage":{"get":{"tags":["Usage"],"summary":"Get Usage","description":"Get usage statistics for the current API key.","operationId":"get_usage_v1_usage_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"current_month, last_month, or YYYY-MM","default":"current_month","title":"Period"},"description":"current_month, last_month, or YYYY-MM"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Root Health","operationId":"root_health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"APIKeyCreate":{"properties":{"name":{"type":"string","title":"Name","description":"Friendly name for the key"},"owner_email":{"type":"string","title":"Owner Email","description":"Email of the key owner"},"rate_limit_per_minute":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Rate Limit Per Minute","default":60},"monthly_request_limit":{"type":"integer","minimum":1.0,"title":"Monthly Request Limit","default":10000}},"type":"object","required":["name","owner_email"],"title":"APIKeyCreate"},"APIKeyCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"owner_email":{"type":"string","title":"Owner Email"},"is_active":{"type":"boolean","title":"Is Active"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"monthly_request_limit":{"type":"integer","title":"Monthly Request Limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"key":{"type":"string","title":"Key"}},"type":"object","required":["id","key_prefix","name","owner_email","is_active","rate_limit_per_minute","monthly_request_limit","created_at","last_used_at","key"],"title":"APIKeyCreated","description":"Returned only on creation — includes the full key (shown once)."},"APIKeyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"owner_email":{"type":"string","title":"Owner Email"},"is_active":{"type":"boolean","title":"Is Active"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"monthly_request_limit":{"type":"integer","title":"Monthly Request Limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","key_prefix","name","owner_email","is_active","rate_limit_per_minute","monthly_request_limit","created_at","last_used_at"],"title":"APIKeyResponse"},"Body_extract_document_v1_extract_post":{"properties":{"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files","description":"Document file(s) to extract"},"model":{"type":"string","title":"Model","description":"OCR model: qomplement-OCR-v1 (standard) or qomplement-OCR-XL-v1 (high precision)","default":"qomplement-OCR-v1"},"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema","description":"JSON schema of target fields"},"output_format":{"type":"string","title":"Output Format","description":"Output format: json, csv, xml","default":"json"},"detail":{"type":"boolean","title":"Detail","description":"Include full AI extraction detail (entities, summary, primary/secondary entities)","default":false},"chunk_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chunk Size","description":"Split OCR text into chunks of this many characters"},"chunk_overlap":{"type":"integer","title":"Chunk Overlap","description":"Number of overlapping characters between chunks","default":0},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url","description":"Webhook URL for async results"}},"type":"object","required":["files"],"title":"Body_extract_document_v1_extract_post"},"Body_fill_excel_v1_fill_excel_post":{"properties":{"target_excel":{"type":"string","format":"binary","title":"Target Excel","description":"Target Excel template to fill"},"source_files":{"anyOf":[{"items":{"type":"string","format":"binary"},"type":"array"},{"type":"null"}],"title":"Source Files","description":"Source document(s) to extract data from"},"model":{"type":"string","title":"Model","description":"OCR model: qomplement-OCR-v1 or qomplement-OCR-XL-v1","default":"qomplement-OCR-v1"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions","description":"Natural language instructions for filling"},"fill_mode":{"type":"string","title":"Fill Mode","description":"Fill mode: smart, complete, or replace","default":"smart"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"}},"type":"object","required":["target_excel"],"title":"Body_fill_excel_v1_fill_excel_post"},"Body_fill_pdf_v1_fill_pdf_post":{"properties":{"target_pdf":{"type":"string","format":"binary","title":"Target Pdf","description":"Target PDF form to fill"},"source_files":{"anyOf":[{"items":{"type":"string","format":"binary"},"type":"array"},{"type":"null"}],"title":"Source Files","description":"Source document(s) to extract data from"},"model":{"type":"string","title":"Model","description":"OCR model: qomplement-OCR-v1 or qomplement-OCR-XL-v1","default":"qomplement-OCR-v1"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions","description":"Natural language instructions for filling (e.g. \"Fill client name as 'Acme Corp'\")"},"field_mappings":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Mappings","description":"JSON explicit mappings {field: value}"},"flatten":{"type":"boolean","title":"Flatten","description":"Flatten form after filling","default":false},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"}},"type":"object","required":["target_pdf"],"title":"Body_fill_pdf_v1_fill_pdf_post"},"DailyUsage":{"properties":{"date":{"type":"string","title":"Date"},"requests":{"type":"integer","title":"Requests"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["date","requests","pages"],"title":"DailyUsage"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JobListResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/JobResponse"},"type":"array","title":"Jobs"},"total":{"type":"integer","title":"Total"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["jobs","total","has_more"],"title":"JobListResponse"},"JobProgress":{"properties":{"current":{"type":"integer","title":"Current"},"total":{"type":"integer","title":"Total"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["current","total"],"title":"JobProgress"},"JobResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"type":{"type":"string","title":"Type"},"status":{"type":"string","title":"Status"},"progress":{"anyOf":[{"$ref":"#/components/schemas/JobProgress"},{"type":"null"}]},"result":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Result"},"error":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Error"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"processing_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Processing Time Ms"}},"type":"object","required":["id","type","status","created_at"],"title":"JobResponse"},"UsageResponse":{"properties":{"period":{"type":"string","title":"Period"},"requests":{"type":"integer","title":"Requests"},"pages_processed":{"type":"integer","title":"Pages Processed"},"ocr_tokens":{"type":"integer","title":"Ocr Tokens"},"structuring_tokens":{"type":"integer","title":"Structuring Tokens"},"pdfs_filled":{"type":"integer","title":"Pdfs Filled"},"excels_filled":{"type":"integer","title":"Excels Filled"},"daily_breakdown":{"items":{"$ref":"#/components/schemas/DailyUsage"},"type":"array","title":"Daily Breakdown"}},"type":"object","required":["period","requests","pages_processed","ocr_tokens","structuring_tokens","pdfs_filled","excels_filled","daily_breakdown"],"title":"UsageResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}