Skip to main content

Retrieve Approved Results

Enterprise Feature

This feature is available in Unstract Cloud Edition and Unstract On-Premise Edition.

After documents are approved in the HITL workflow (either manually by supervisors or automatically through Auto Approval), you can retrieve the approved results through the API if your workflow is configured to send results to a queue.

Overview

When your HITL workflow is configured with "After approval, send result to: Queue", approved documents are stored in the approved queue and can be retrieved programmatically using the Approved Results API.

Queue-Based Retrieval

This API uses a queue-based dequeue operation. Each API call:

  • Retrieves ONE item from the approved queue
  • Removes that item from the queue
  • Returns the single item's data

This is not a read-only list query - items are dequeued and consumed with each request.

Use Cases

  • Building custom downstream processing workflows
  • Integrating approved results with external systems
  • Creating custom dashboards and reporting
  • Archiving approved documents

Approved Results API

API Endpoint

GET /mr/api/{org_name}/approved/result/{class_id}/

Example Request

curl --location 'https://us-central.unstract.com/mr/api/<org_name>/approved/result/<class_id>/' \
--header 'Authorization: Bearer <api_key>'

Optional Query Parameters

ParameterTypeDescription
hitl_queue_namestringOptional queue name suffix for API deployments

Example with optional parameter:

curl --location 'https://us-central.unstract.com/mr/api/<org_name>/approved/result/<class_id>/?hitl_queue_name=custom-queue' \
--header 'Authorization: Bearer <api_key>'

Getting Required Parameters

Organization Name

The organization name is used in the API path to identify your organization.

How to find it:

  1. Navigate to your workflow or ETL pipeline
  2. Check the API endpoint URL
  3. The organization name is part of the URL path (e.g., your company name or org identifier)

You can also find it in:

  • ETL execution API endpoint
  • Human Quality Review settings
  • Workflow configuration page

API Key

Create an API key specifically for Human Review API access:

  1. Navigate to Human Quality Review
  2. Click Create API Key
  3. Copy and securely store your API key
  4. Use this key in the Authorization: Bearer <api_key> header

Create API Key API Key Created

Security Best Practice
  • Store API keys securely (use environment variables or secrets management)
  • Never commit API keys to version control
  • Rotate API keys periodically
  • Revoke unused or compromised keys immediately

Class ID (Workflow ID)

Get the class ID from the Download and Sync Manager:

  1. Click on Profile IconDownload and Sync Manager
  2. Find your workflow in the list
  3. Copy the class ID (workflow ID)

Access Sync Manager Get Class ID

The class ID is a UUID that uniquely identifies your workflow/document class.

Response Format

The API returns a single approved document's data in JSON format.

Example Response

{
"data": {
"file": "invoice_2025_001.pdf",
"status": "approved",
"result": {
"invoice_number": "INV-2025-001",
"invoice_date": "2025-10-27",
"vendor_name": "Acme Corp",
"total_amount": "1500.00",
"line_items": [
{
"description": "Software License",
"quantity": 1,
"unit_price": "1500.00",
"total": "1500.00"
}
]
},
"workflow_id": "workflow-uuid",
"file_execution_id": "execution-uuid"
}
}

Response Fields

FieldTypeDescription
filestringOriginal filename of the processed document
statusstringStatus of the document (typically "approved")
resultobjectThe extracted and approved field values
workflow_idstringUUID of the workflow/document class
file_execution_idstringUnique identifier for this execution
tip

The result object contains the actual extracted data fields as defined in your Prompt Studio project. The structure will match your prompt configuration.

Integration Examples

Python Example

import requests
import os
import time

# Configuration
BASE_URL = "https://us-central.unstract.com"
ORG_NAME = "your-org-name"
CLASS_ID = "your-workflow-class-id"
API_KEY = os.environ.get("UNSTRACT_API_KEY")

def dequeue_approved_result():
"""Dequeue one approved result from HITL queue"""
url = f"{BASE_URL}/mr/api/{ORG_NAME}/approved/result/{CLASS_ID}/"
headers = {
"Authorization": f"Bearer {API_KEY}"
}

response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()

return response.json()

# Process approved results continuously
def process_approved_results():
"""Continuously process approved results from the queue"""
while True:
try:
result = dequeue_approved_result()
data = result.get("data", {})

# Process the result
print(f"Processing file: {data.get('file')}")
print(f"Status: {data.get('status')}")
print(f"Extracted data: {data.get('result')}")

# Add your processing logic here
# ...

except requests.exceptions.HTTPError as e:
if e.response.status_code == 404:
print("No more results in queue, waiting...")
time.sleep(30) # Wait before checking again
else:
print(f"Error: {e}")
time.sleep(5)

except Exception as e:
print(f"Unexpected error: {e}")
time.sleep(5)

# Start processing
process_approved_results()

Node.js Example

const axios = require('axios');

const BASE_URL = "https://us-central.unstract.com";
const ORG_NAME = "your-org-name";
const CLASS_ID = "your-workflow-class-id";
const API_KEY = process.env.UNSTRACT_API_KEY;

async function dequeueApprovedResult() {
const url = `${BASE_URL}/mr/api/${ORG_NAME}/approved/result/${CLASS_ID}/`;

const response = await axios.get(url, {
headers: {
'Authorization': `Bearer ${API_KEY}`
},
timeout: 30000
});

return response.data;
}

// Process approved results continuously
async function processApprovedResults() {
while (true) {
try {
const result = await dequeueApprovedResult();
const data = result.data || {};

// Process the result
console.log(`Processing file: ${data.file}`);
console.log(`Status: ${data.status}`);
console.log(`Extracted data:`, data.result);

// Add your processing logic here
// ...

} catch (error) {
if (error.response && error.response.status === 404) {
console.log('No more results in queue, waiting...');
await new Promise(resolve => setTimeout(resolve, 30000));
} else {
console.error('Error:', error.message);
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
}
}

// Start processing
processApprovedResults();

cURL Script Example

#!/bin/bash

BASE_URL="https://us-central.unstract.com"
ORG_NAME="your-org-name"
CLASS_ID="your-workflow-class-id"
API_KEY="your-api-key"

# Dequeue and process one approved result
curl --fail --location "${BASE_URL}/mr/api/${ORG_NAME}/approved/result/${CLASS_ID}/" \
--header "Authorization: Bearer ${API_KEY}" \
--output result.json

# Check if request was successful
if [ $? -eq 0 ]; then
echo "Successfully retrieved approved result"
cat result.json | jq '.'
else
echo "Failed to retrieve result or queue is empty"
fi

Batch Processing Script

import requests
import os
import json

BASE_URL = "https://us-central.unstract.com"
ORG_NAME = "your-org-name"
CLASS_ID = "your-workflow-class-id"
API_KEY = os.environ.get("UNSTRACT_API_KEY")

def process_batch(batch_size=10):
"""Process a batch of approved results"""
url = f"{BASE_URL}/mr/api/{ORG_NAME}/approved/result/{CLASS_ID}/"
headers = {"Authorization": f"Bearer {API_KEY}"}

results = []

for i in range(batch_size):
try:
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
results.append(response.json())
print(f"Retrieved result {i+1}/{batch_size}")

except requests.exceptions.HTTPError as e:
if e.response.status_code == 404:
print(f"Queue empty after {i} results")
break
else:
print(f"Error on result {i+1}: {e}")
break

return results

# Process a batch
batch = process_batch(batch_size=10)
print(f"Processed {len(batch)} approved results")

# Save to file
with open('approved_batch.json', 'w') as f:
json.dump(batch, f, indent=2)

Error Handling

Common Error Responses

401 Unauthorized

{
"detail": "Authentication credentials were not provided."
}

Solution: Check that your API key is valid and included in the Authorization header.

403 Forbidden

{
"detail": "You do not have permission to access this resource."
}

Solution: Ensure your API key has the necessary permissions for Human Review access.

404 Not Found

This typically means the queue is empty (no more approved results to retrieve).

Solutions:

  1. Wait for more documents to be approved
  2. Check that documents are being approved and sent to the queue
  3. Verify the class_id is correct

500 Internal Server Error

{
"detail": "An error occurred while retrieving approved results."
}

Solution: Contact support if this persists. Check system status and logs.

Troubleshooting

No Results Returned (404 Error)

Possible Causes:

  • Queue is currently empty (most common)
  • No documents have been approved yet
  • Workflow is configured to send results to Destination DB instead of Queue
  • Class ID is incorrect

Solutions:

  1. Wait for documents to be approved
  2. Check the workflow destination configuration (should be "Queue")
  3. Verify documents are going through the approval process
  4. Confirm the class ID matches your workflow

Empty or Missing Data in Response

Possible Causes:

  • Extraction failed during processing
  • Document had no extractable content
  • Prompts were not configured correctly in Prompt Studio

Solutions:

  1. Check the original document in Human Quality Review
  2. Review extraction logs for errors
  3. Verify Prompt Studio configuration
  4. Test the prompt with sample documents

Repeated Retrieval of Same Item

If you're seeing the same item repeatedly:

Possible Causes:

  • Item is being re-enqueued due to processing failures
  • Multiple consumers are reading from the same queue

Solutions:

  1. Ensure your processing logic completes successfully
  2. Check for competing consumers
  3. Review your queue configuration

API Timeout Errors

Possible Causes:

  • Network connectivity issues
  • Server under heavy load
  • Queue operation taking too long

Solutions:

  1. Increase timeout values in your HTTP client
  2. Implement retry logic with exponential backoff
  3. Check network connectivity
  4. Contact support if issue persists