Operations
Perform post-processing operations on completed document jobs for error analysis, generative tasks, and image selection.
Overview
Operations allow you to run additional analysis and processing on documents that have already been processed. Available operations include:
- Error Analysis: Identify potential issues in extraction results.
- Generative Tasks: Generate summaries, translations, or custom AI responses based on processed documents.
- Image Selection: Pick relevant figures from extracted images based on a prompt.
Available Operations
Error Analysis
Analyzes completed document processing jobs to identify:
- Potential extraction errors or inconsistencies.
- Missing or incomplete data fields.
- Confidence levels for extracted information.
- Suggestions for improving accuracy.
Generative Tasks
Generates custom AI responses based on processed document content:
- Document summaries and explanations.
- Content transformation (e.g., format conversion).
- Question answering based on document content.
- Custom analysis with user-defined prompts.
Image Selection
Selects the most relevant extracted figures based on a prompt. The parent job must have figure artifacts, which are created by running document processing or OCR with extract_figures=True (or describe_figures=True).
How Operations Work
- Document Processing: First, process a document normally.
- Operation Submission: Submit an operation request on the completed job.
- Analysis: AI analyzes the original processing results.
- Results: Get detailed analysis, generated content, or selected images.
API Endpoints
Submit Operation
POST /operation
Request Body:
{
"jobGuid": "uuid-of-completed-job",
"type": "error-analysis",
"parameters": {
"llmType": "HIGH",
"customParameters": {}
}
}
Submit Generative Task
POST /operation/{parentJobId}/generative-task
Request Body:
{
"prompt": "Summarize this document and explain its main purpose",
"model": "DEFAULT",
"temperature": 0.7,
"maxTokens": 500
}
SDK & CLI Examples
Error Analysis
- Python SDK
- Java SDK
- CLI
- cURL
from docudevs.docudevs_client import DocuDevsClient
import os
import asyncio
client = DocuDevsClient(token=os.getenv('API_KEY'))
async def analyze_errors(job_guid):
# Submit error analysis operation and wait for the result
analysis_result = await client.submit_and_wait_for_error_analysis(
job_guid=job_guid,
timeout=120
)
print(f"Analysis result: {analysis_result}")
# Usage
# asyncio.run(analyze_errors("your-job-guid"))
# Submit error analysis and wait for completion
docudevs operations error-analysis JOB_GUID --timeout 180
# Check status of operations on the job (optional)
docudevs operations status JOB_GUID
import ai.docudevs.client.DocuDevsClient;
import ai.docudevs.client.WaitOptions;
import com.fasterxml.jackson.databind.JsonNode;
DocuDevsClient client = DocuDevsClient.builder()
.apiKey(System.getenv("API_KEY"))
.build();
String parentJobGuid = "JOB_GUID";
client.submitOperation(parentJobGuid, "error-analysis");
JsonNode result = client.waitForOperation(
parentJobGuid, "error-analysis", WaitOptions.builder().build()
);
System.out.println(result.path("result"));
curl -X POST https://api.docudevs.ai/operation \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"jobGuid": "JOB_GUID", "type": "error-analysis"}'
# Poll for operation status
curl -X GET https://api.docudevs.ai/operation/JOB_GUID \
-H "Authorization: Bearer $API_KEY"
Generative Tasks
- Python SDK
- Java SDK
- CLI
- cURL
async def summarize_document(job_guid):
summary = await client.submit_and_wait_for_generative_task(
parent_job_id=job_guid,
prompt="Summarize the main findings",
model="DEFAULT"
)
# The result is a JSON string inside the response object
import json
result_data = json.loads(summary.result)
print(result_data['generated_text'])
# Create a generative task that waits for completion
docudevs operations generative-task PARENT_JOB_GUID \
--prompt "Summarize the main findings" \
--model DEFAULT --timeout 180
# Retrieve the operation result if needed later
docudevs operations result PARENT_JOB_GUID --type generative-task
import ai.docudevs.client.DocuDevsClient;
import ai.docudevs.client.WaitOptions;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
DocuDevsClient client = DocuDevsClient.builder()
.apiKey(System.getenv("API_KEY"))
.build();
ObjectMapper mapper = new ObjectMapper();
String parentJobGuid = "PARENT_JOB_GUID";
client.createGenerativeTask(parentJobGuid, "Summarize the main findings", "DEFAULT");
JsonNode result = client.waitForGenerativeTask(
parentJobGuid, WaitOptions.builder().build()
);
JsonNode payload = mapper.readTree(result.path("result").asText());
System.out.println(payload.path("generated_text").asText());
curl -X POST https://api.docudevs.ai/operation/PARENT_JOB_GUID/generative-task \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Summarize the main findings", "model": "DEFAULT"}'
# Fetch the generative task result
curl -X GET https://api.docudevs.ai/operation/PARENT_JOB_GUID/generative-task \
-H "Authorization: Bearer $API_KEY"
Image Selection
- Python SDK
- Java SDK
- CLI
- cURL
import json
job_guid = await client.submit_and_process_document(
document=document_bytes,
document_mime_type="application/pdf",
prompt="Extract key information",
extract_figures=True
)
await client.wait_until_ready(job_guid)
selection = await client.submit_and_wait_for_image_selection(
job_guid,
prompt="Return all diagrams from the document",
top_k=5,
match_mode="all",
use_vision=False
)
selection_payload = json.loads(selection.result)
first = selection_payload["selected"][0]
image_bytes = await client.get_figure_image(job_guid, first["id"])
docudevs operations submit JOB_GUID \
--type image-select \
--parameter prompt="Return all diagrams from the document" \
--parameter topK=5 \
--parameter matchMode=all \
--parameter useVision=false \
--wait
docudevs operations result JOB_GUID --type image-select
import ai.docudevs.client.DocuDevsClient;
import ai.docudevs.client.WaitOptions;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
DocuDevsClient client = DocuDevsClient.builder()
.apiKey(System.getenv("API_KEY"))
.build();
ObjectMapper mapper = new ObjectMapper();
String jobGuid = "JOB_GUID";
client.submitOperation(jobGuid, "image-select", null,
Map.of(
"prompt", "Return all diagrams from the document",
"topK", 5,
"matchMode", "all",
"useVision", false
)
);
JsonNode result = client.waitForOperation(
jobGuid, "image-select", WaitOptions.builder().build()
);
JsonNode payload = mapper.readTree(result.path("result").asText());
JsonNode first = payload.path("selected").get(0);
if (first != null) {
String imageId = first.path("id").asText();
byte[] imageBytes = client.getFigureImage(jobGuid, imageId);
Files.write(Path.of("selected_figure.png"), imageBytes);
}
System.out.println(payload.toPrettyString());
curl -X POST https://api.docudevs.ai/operation \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobGuid": "JOB_GUID",
"type": "image-select",
"parameters": {
"customParameters": {
"prompt": "Return all diagrams from the document",
"topK": 5,
"matchMode": "all",
"useVision": false
}
}
}'
Advanced Usage
Document Question Answering
You can use Generative Tasks to ask specific questions about a processed document.
questions = [
"What is the contract duration?",
"Who are the parties involved?",
"What are the key obligations?"
]
for question in questions:
answer = await client.submit_and_wait_for_generative_task(
parent_job_id=ocr_job_id,
prompt=f"Based on this document, answer the following question: {question}"
)
result_data = json.loads(answer.result)
print(f"Q: {question}")
print(f"A: {result_data['generated_text']}\n")
Advanced Parameters
- Python SDK
- Java SDK
- CLI
- cURL
# Submit operation with custom LLM and parameters
await client.submit_operation_with_parameters(
job_guid=job_guid,
operation_type="error-analysis",
llm_type="HIGH", # Use high-quality LLM for analysis
custom_parameters={
"focus_areas": ["numerical_accuracy", "date_formats"],
"confidence_threshold": 0.8,
"detailed_suggestions": True
}
)
# Submit error analysis with HIGH quality model
docudevs operations error-analysis <JOB_GUID> \
--llm-type HIGH \
--timeout 180
import ai.docudevs.client.DocuDevsClient;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
import java.util.Map;
DocuDevsClient client = DocuDevsClient.builder()
.apiKey(System.getenv("API_KEY"))
.build();
JsonNode response = client.submitOperation(
"JOB_GUID",
"error-analysis",
"HIGH",
Map.of(
"focus_areas", List.of("numerical_accuracy", "date_formats"),
"confidence_threshold", 0.8,
"detailed_suggestions", true
)
);
System.out.println("Operation job GUID: " + response.path("jobGuid").asText());
System.out.println("Status: " + response.path("status").asText());
curl -X POST https://api.docudevs.ai/operation \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobGuid": "<JOB_GUID>",
"type": "error-analysis",
"parameters": {
"llmType": "HIGH",
"customParameters": {
"focus_areas": ["numerical_accuracy", "date_formats"],
"confidence_threshold": 0.8
}
}
}'
Output Formats
Error Analysis Output
{
"analysis": {
"overall_confidence": 0.85,
"field_confidence": {
"invoice_number": 0.95,
"total_amount": 0.90
},
"potential_issues": [
{
"field": "line_items",
"issue": "Some quantities may be misread",
"confidence": 0.75,
"suggestion": "Review items with quantities > 100"
}
]
},
"recommendations": [
{
"type": "processing_improvement",
"description": "Consider using higher quality OCR settings"
}
]
}
Generative Task Output
{
"generated_text": "This document is a household contents insurance policy...",
"model_used": "DEFAULT",
"prompt": "Summarize this document...",
"processing_time_ms": 3245,
"token_usage": {
"prompt_tokens": 2847,
"completion_tokens": 94,
"total_tokens": 2941
}
}
Best Practices
- Quality Assurance: Run error analysis on critical documents or when confidence scores are low.
- Summarization: Use generative tasks to create quick summaries for document lists.
- Translation: Use generative tasks to translate document content while preserving context.
- Chain Operations: Process a document, then run error analysis, then summarize it—all via API.
- Map-Reduce Re-processing: Use
submit_and_wait_for_map_reduce(parent_job_id=...)to run map-reduce on a previously processed document without re-uploading or re-running OCR. See Map-Reduce Extraction for details.