GET
/
classify
/
{job_id}
curl -X GET "https://prod.visionapi.unsiloed.ai/classify/47c536aa-9fab-48ca-b27c-2fd74d30490a" \
  -H "api-key: your-api-key" \
  -H "Content-Type: application/json"
{
  "job_id": "47c536aa-9fab-48ca-b27c-2fd74d30490a",
  "status": "processing",
  "progress": "Processing page 1 of 2",
  "error": null,
  "result": null
}

Overview

The Get Classification Job Status endpoint allows you to check the current status of classification jobs and retrieve the final results once processing is complete. Classification jobs process documents asynchronously, uploading files to cloud storage and analyzing them in the background.
Classification jobs are stored in Supabase and updated in real-time. Status checks are lightweight and can be polled frequently to monitor progress.

Request

job_id
string
required
The unique identifier of the classification job to check
api-key
string
required
API key for authentication
Content-Type
string
Set to “application/json”

Response

job_id
string
Unique identifier for the classification job
status
string
Current job status: “processing”, “completed”, or “failed”
progress
string
Human-readable progress message describing current processing stage
error
string
Error message (if job failed, otherwise null)
result
object
Classification results (only present when status is “completed”)

Request Examples

curl -X GET "https://prod.visionapi.unsiloed.ai/classify/47c536aa-9fab-48ca-b27c-2fd74d30490a" \
  -H "api-key: your-api-key" \
  -H "Content-Type: application/json"

Response Examples

{
  "job_id": "47c536aa-9fab-48ca-b27c-2fd74d30490a",
  "status": "processing",
  "progress": "Processing page 1 of 2",
  "error": null,
  "result": null
}

Job Status Values

Polling Strategy

For long-running classification jobs, implement polling with exponential backoff:
import time
import asyncio

async def poll_classification_status(job_id, max_wait_time=300):
    """Poll classification job status with exponential backoff"""
    
    base_delay = 1  # Start with 1 second
    max_delay = 30  # Maximum delay between polls
    current_delay = base_delay
    total_wait_time = 0
    
    while total_wait_time < max_wait_time:
        try:
            response = requests.get(
                f"https://prod.visionapi.unsiloed.ai/classify/{job_id}",
                headers={"api-key": "your-api-key", "Content-Type": "application/json"}
            )
            
            if response.status_code == 200:
                result = response.json()
                
                if result['status'] == 'completed':
                    return result['result']
                elif result['status'] == 'failed':
                    raise Exception(f"Classification failed: {result.get('error', 'Unknown error')}")
                else:
                    print(f"Status: {result['status']}, Progress: {result.get('progress', 'N/A')}")
            
            # Wait before next poll
            await asyncio.sleep(current_delay)
            total_wait_time += current_delay
            
            # Exponential backoff
            current_delay = min(current_delay * 2, max_delay)
            
        except Exception as e:
            print(f"Error polling status: {e}")
            await asyncio.sleep(current_delay)
            total_wait_time += current_delay
    
    raise Exception("Classification job timed out")

Progress Messages

During processing, the progress field will show informative messages:
  • “Starting classification…” - Job has been queued and is beginning
  • “Processing page X of Y” - Currently analyzing specific pages
  • “Classification completed” - Job finished successfully
  • “Classification failed” - Job encountered an error

Error Handling

Common Error Scenarios

  1. File Processing Errors: PDF corruption, password protection, or unreadable content
  2. Invalid Conditions: Empty conditions list or malformed JSON
  3. Storage Errors: File upload failures to Supabase storage
  4. Vision API Errors: OpenAI API failures or timeouts
  5. Job Not Found: Invalid job ID or job has been deleted

Error Response Examples

File Processing Error
{
  "job_id": "47c536aa-9fab-48ca-b27c-2fd74d30490a",
  "status": "failed",
  "progress": "Classification failed",
  "error": "Failed to process PDF: File appears to be corrupted",
  "result": null
}
Invalid Conditions Error
{
  "job_id": "47c536aa-9fab-48ca-b27c-2fd74d30490a",
  "status": "failed",
  "progress": "Classification failed",
  "error": "Invalid conditions format. Must be a valid JSON string.",
  "result": null
}
Storage Error
{
  "job_id": "47c536aa-9fab-48ca-b27c-2fd74d30490a",
  "status": "failed",
  "progress": "Classification failed",
  "error": "Failed to upload file to storage. Please try again.",
  "result": null
}

Best Practices

Polling Frequency: Use exponential backoff when polling job status to avoid overwhelming the API. Start with 1-second intervals and increase gradually.
Timeout Handling: Set reasonable timeouts for classification jobs. Most jobs complete within 30-60 seconds, but complex multi-page documents may take longer.
Error Recovery: Implement retry logic for transient errors and provide fallback handling for permanent failures.
Result Caching: Once a job is completed, cache the results to avoid unnecessary API calls for the same job ID.
Rate Limits: Status checking endpoints have rate limits. Implement proper backoff strategies to avoid hitting limits.
Job Retention: Classification jobs and their results may be automatically cleaned up after a certain period. Check with your service provider for retention policies.

Integration Examples

Simple Status Check

def check_classification_status(job_id):
    """Simple function to check classification job status"""
    
    response = requests.get(
        f"https://prod.visionapi.unsiloed.ai/classify/{job_id}",
        headers={"api-key": "your-api-key", "Content-Type": "application/json"}
    )
    
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"Failed to get job status: {response.status_code}")

Batch Status Monitoring

async def monitor_classification_jobs(job_ids):
    """Monitor multiple classification jobs concurrently"""
    
    async def check_single_job(session, job_id):
        async with session.get(
            f"https://prod.visionapi.unsiloed.ai/classify/{job_id}",
            headers={"api-key": "your-api-key", "Content-Type": "application/json"}
        ) as response:
            return await response.json()
    
    async with aiohttp.ClientSession() as session:
        tasks = [check_single_job(session, job_id) for job_id in job_ids]
        results = await asyncio.gather(*tasks)
        return results

# Usage
job_ids = ["job1", "job2", "job3"]
results = asyncio.run(monitor_classification_jobs(job_ids))

Webhook Integration

from flask import Flask, request

app = Flask(__name__)

@app.route('/classification-webhook', methods=['POST'])
def classification_webhook():
    """Webhook endpoint for classification job completion"""
    
    data = request.json
    
    if data['status'] == 'completed':
        # Process completed classification
        result = data['result']
        classification = result['classification']
        confidence = result['confidence']
        
        # Route document based on classification
        route_document(classification, confidence)
        
        return {"status": "processed"}, 200
    elif data['status'] == 'failed':
        # Handle failed classification
        error = data['error']
        log_error(error)
        
        return {"status": "error_logged"}, 200
    
    return {"status": "ignored"}, 200