API Documentation
JSON format API documentation or configuration file.
Preview
{
"info": {
"_postman_id": "document-extraction-api-v2",
"name": "Document Extraction API v2",
"description": "Complete Postman collection for testing the Document Extraction API. This API accepts ANY document type (PDF, JPEG, PNG) and uses AI to automatically identify and classify documents using a configurable document type registry. Currently supports extraction for Statement of Repair (SOR) and Insurance Certificate documents, with easy extensibility for new types.",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"variable": [
{
"key": "base_url",
"value": "https://api.extractable.xyz",
"type": "string",
"description": "Base URL for the API (production)"
},
{
"key": "api_key",
"value": "dk_live_your_api_key_here",
"type": "string",
"description": "Your API key for authentication"
},
{
"key": "job_id",
"value": "",
"type": "string",
"description": "Job ID from extraction request (auto-populated)"
}
],
"item": [
{
"name": "Document Extraction",
"item": [
{
"name": "Extract Document - SOR Example",
"event": [
{
"listen": "test",
"script": {
"exec": [
"// Parse response",
"const response = pm.response.json();",
"",
"// Test response structure",
"pm.test(\"Status code is 202\", function () {",
" pm.response.to.have.status(202);",
"});",
"",
"pm.test(\"Response has required fields\", function () {",
" pm.expect(response).to.have.property('jobId');",
" pm.expect(response).to.have.property('status');",
" pm.expect(response).to.have.property('pollingUrl');",
" pm.expect(response).to.have.property('resultUrl');",
"});",
"",
"pm.test(\"Initial status is pending\", function () {",
" pm.expect(response.status).to.equal('pending');",
"});",
"",
"// Save job ID for subsequent requests",
"if (response.jobId) {",
" pm.collectionVariables.set(\"job_id\", response.jobId);",
" console.log(\"Job ID saved: \" + response.jobId);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/statement-of-repair.pdf",
"description": "Upload a Statement of Repair PDF document"
},
{
"key": "webhookUrl",
"value": "https://your-webhook-endpoint.com/extraction-complete",
"type": "text",
"description": "Optional webhook URL for completion notification",
"disabled": true
},
{
"key": "metadata",
"value": "{\"clientId\": \"12345\", \"projectName\": \"Main St Renovation\"}",
"type": "text",
"description": "Optional metadata as JSON",
"disabled": true
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Submit a Statement of Repair document for extraction"
},
"response": [
{
"name": "Success - 202 Accepted",
"originalRequest": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/document.pdf"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
}
},
"status": "Accepted",
"code": 202,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"jobId\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"status\": \"pending\",\n \"pollingUrl\": \"https://draw.extractable.xyz/api/documents/extract/123e4567-e89b-12d3-a456-426614174000\",\n \"resultUrl\": \"https://draw.extractable.xyz/api/documents/extract/123e4567-e89b-12d3-a456-426614174000/result\",\n \"createdAt\": \"2024-01-01T00:00:00Z\"\n}"
}
]
},
{
"name": "Extract Document - Insurance Cert Example",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test(\"Status code is 202\", function () {",
" pm.response.to.have.status(202);",
"});",
"",
"if (response.jobId) {",
" pm.collectionVariables.set(\"job_id\", response.jobId);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/insurance-certificate.pdf",
"description": "Upload an Insurance Certificate (ACORD form)"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Submit an Insurance Certificate for extraction"
},
"response": []
},
{
"name": "Extract Document - JPEG Image",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test(\"Status code is 202\", function () {",
" pm.response.to.have.status(202);",
"});",
"",
"if (response.jobId) {",
" pm.collectionVariables.set(\"job_id\", response.jobId);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/document-photo.jpg",
"description": "Upload a JPEG photo of a document"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Submit a JPEG image for document extraction"
},
"response": []
},
{
"name": "Extract Document - Unknown Type (Invoice)",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test(\"Status code is 202\", function () {",
" pm.response.to.have.status(202);",
"});",
"",
"pm.test(\"Job accepted for processing\", function () {",
" pm.expect(response).to.have.property('jobId');",
"});",
"",
"if (response.jobId) {",
" pm.collectionVariables.set(\"job_id\", response.jobId);",
" console.log(\"Job ID for unknown document: \" + response.jobId);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/invoice.pdf",
"description": "Upload a document type not in the registry (e.g., Invoice)"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Test with a document type not currently registered for extraction"
},
"response": []
},
{
"name": "Extract Document - Building Permit",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test(\"Status code is 202\", function () {",
" pm.response.to.have.status(202);",
"});",
"",
"if (response.jobId) {",
" pm.collectionVariables.set(\"job_id\", response.jobId);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/building-permit.pdf",
"description": "Upload a building permit document"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Submit a building permit for identification"
},
"response": []
},
{
"name": "Get Extraction Status",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"Response has status field\", function () {",
" pm.expect(response).to.have.property('status');",
"});",
"",
"// Log current status",
"console.log(\"Current status: \" + response.status);",
"console.log(\"Progress: \" + (response.progress || 0) + \"%\");",
"",
"// Check document type if classified",
"if (response.documentType) {",
" console.log(\"Document type: \" + response.documentType);",
" if (response.documentType === 'unknown') {",
" console.log(\"Document could not be identified\");",
" }",
"}",
"",
"// Check classification confidence",
"if (response.classificationConfidence) {",
" console.log(\"Classification confidence: \" + (response.classificationConfidence * 100).toFixed(2) + \"%\");",
"}",
"",
"// Check alternative types",
"if (response.alternativeTypes && response.alternativeTypes.length > 0) {",
" console.log(\"Alternative type suggestions:\");",
" response.alternativeTypes.forEach(alt => {",
" console.log(\" - \" + alt.displayName + \" (\" + (alt.confidence * 100).toFixed(2) + \"%)\");",
" });",
"}",
"",
"// Check for errors",
"if (response.status === 'failed' && response.error) {",
" console.log(\"Error: \" + response.error);",
"}",
"",
"// If completed, check extracted data",
"if (response.status === 'completed') {",
" pm.test(\"Completed job has extracted data\", function () {",
" pm.expect(response).to.have.property('extractedData');",
" pm.expect(response).to.have.property('processingTime');",
" });",
" ",
" if (response.extractedData) {",
" console.log(\"Extraction successful!\");",
" console.log(\"Processing time: \" + response.processingTime + \" seconds\");",
" pm.collectionVariables.set(\"extracted_data\", JSON.stringify(response.extractedData));",
" } else {",
" console.log(\"Document type '\" + response.documentType + \"' identified but no extraction performed\");",
" }",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/extract/{{job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract",
"{{job_id}}"
]
},
"description": "Get the status of an extraction job. When status is 'completed', this endpoint also returns the full extraction results including extracted data. Status can be: pending, processing, completed, or failed."
},
"response": [
{
"name": "Status - Processing",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/extract/{{job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract",
"{{job_id}}"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"jobId\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"status\": \"processing\",\n \"fileName\": \"statement-of-repair.pdf\",\n \"fileType\": \"pdf\",\n \"documentType\": \"sor\",\n \"progress\": 45,\n \"createdAt\": \"2024-01-01T00:00:00Z\",\n \"updatedAt\": \"2024-01-01T00:00:30Z\"\n}"
},
{
"name": "Status - Completed",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/extract/{{job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract",
"{{job_id}}"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"jobId\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"status\": \"completed\",\n \"fileName\": \"statement-of-repair.pdf\",\n \"fileType\": \"pdf\",\n \"documentType\": \"sor\",\n \"progress\": 100,\n \"classificationConfidence\": 0.95,\n \"extractedData\": {\n \"documentMetadata\": {\n \"consultant\": \"ABC Consulting Inc.\",\n \"propertyAddress\": \"123 Main Street, City, State 12345\"\n }\n },\n \"processingTime\": 28.5,\n \"createdAt\": \"2024-01-01T00:00:00Z\",\n \"updatedAt\": \"2024-01-01T00:01:00Z\",\n \"completedAt\": \"2024-01-01T00:01:00Z\"\n}"
}
]
},
{
"name": "Get Supported Document Types",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"Response has types array\", function () {",
" pm.expect(response).to.have.property('types');",
" pm.expect(response.types).to.be.an('array');",
"});",
"",
"// Log available document types",
"if (response.types && response.types.length > 0) {",
" console.log(\"Available document types:\");",
" response.types.forEach(type => {",
" console.log(\"- \" + type.typeCode + \": \" + type.displayName);",
" console.log(\" Confidence threshold: \" + (type.confidenceThreshold * 100) + \"%\");",
" console.log(\" Extraction supported: \" + type.extractionSupported);",
" });",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/types",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"types"
]
},
"description": "Get a list of all document types registered in the system for automatic identification"
},
"response": []
}
]
},
{
"name": "Error Scenarios",
"item": [
{
"name": "Invalid File Type",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/document.txt",
"description": "Attempt to upload unsupported file type"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Test error handling for unsupported file types"
},
"response": []
},
{
"name": "Missing Authentication",
"request": {
"auth": {
"type": "noauth"
},
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/document.pdf"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
},
"description": "Test 401 unauthorized response"
},
"response": []
},
{
"name": "Invalid Job ID",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/extract/invalid-job-id",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract",
"invalid-job-id"
]
},
"description": "Test 404 response for non-existent job"
},
"response": []
}
]
},
{
"name": "System",
"item": [
{
"name": "Health Check",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"API is healthy\", function () {",
" const response = pm.response.json();",
" pm.expect(response.status).to.equal('ok');",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "noauth"
},
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/health",
"host": [
"{{base_url}}"
],
"path": [
"api",
"health"
]
},
"description": "Check if the API is operational (no authentication required)"
},
"response": []
}
]
},
{
"name": "Workflow Examples",
"item": [
{
"name": "Complete Extraction Flow",
"item": [
{
"name": "1. Submit Document",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/document.pdf"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
}
},
"response": []
},
{
"name": "2. Poll Status (repeat until completed, includes results when done)",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/extract/{{job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract",
"{{job_id}}"
]
}
},
"response": []
}
],
"description": "Example workflow showing the complete extraction process"
},
{
"name": "Unknown Document Workflow",
"item": [
{
"name": "1. Submit Unknown Document",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/path/to/random-document.pdf"
}
]
},
"url": {
"raw": "{{base_url}}/api/documents/extract",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract"
]
}
},
"response": []
},
{
"name": "2. Check Status (will show 'unknown' type with no extraction data)",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/documents/extract/{{job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"documents",
"extract",
"{{job_id}}"
]
}
},
"response": []
}
],
"description": "Example workflow for documents that don't match any registered type"
}
]
}
],
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"// Global pre-request script",
"console.log(\"Sending request to: \" + request.url);",
"console.log(\"Using API key: \" + pm.variables.get(\"api_key\").substring(0, 10) + \"...\");"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"// Global test script",
"console.log(\"Response time: \" + pm.response.responseTime + \"ms\");",
"console.log(\"Response size: \" + pm.response.responseSize + \" bytes\");"
]
}
}
]
}