Documentation Index
Fetch the complete documentation index at: https://docs.doclo.ai/llms.txt
Use this file to discover all available pages before exploring further.
Get the status and results of a flow execution. Use this endpoint to poll for results after an async execution.
Endpoint
GET https://app.doclo.ai/api/v1/runs/{executionId}
Authentication
Requires an API key with executions:read scope.
Authorization: Bearer dc_live_your_api_key
Path Parameters
| Parameter | Type | Description |
|---|
executionId | string | Required. The execution identifier (e.g., exec_abc123) |
Query Parameters
| Parameter | Type | Description |
|---|
include | string | Additional data to include: artifacts, metrics (comma-separated) |
Response
Pending/Running (200 OK)
{
"id": "exec_abc123def456",
"flowId": "invoice-extractor",
"version": "1.2.0",
"status": "running",
"progress": {
"step": "extract",
"percentage": 65
},
"createdAt": "2024-02-20T15:30:00Z",
"metadata": {
"customerId": "cust_123"
}
}
Completed (200 OK)
{
"id": "exec_abc123def456",
"flowId": "invoice-extractor",
"version": "1.2.0",
"status": "completed",
"createdAt": "2024-02-20T15:30:00Z",
"completedAt": "2024-02-20T15:30:12Z",
"output": {
"invoiceNumber": "INV-2024-001",
"date": "2024-02-15",
"vendor": {
"name": "Acme Corporation",
"address": "123 Business St"
},
"total": 1627.50
},
"metrics": {
"durationMs": 12340,
"pageCount": 2,
"creditsUsed": 4
},
"metadata": {
"customerId": "cust_123"
}
}
Failed (200 OK)
{
"id": "exec_abc123def456",
"flowId": "invoice-extractor",
"version": "1.2.0",
"status": "failed",
"createdAt": "2024-02-20T15:30:00Z",
"completedAt": "2024-02-20T15:30:05Z",
"error": {
"code": "EXTRACTION_FAILED",
"message": "Unable to extract structured data from document",
"step": "extract"
},
"metadata": {
"customerId": "cust_123"
}
}
With Artifacts (200 OK)
When requesting ?include=artifacts:
{
"id": "exec_abc123def456",
"flowId": "invoice-extractor",
"status": "completed",
"output": { ... },
"artifacts": {
"parse": {
"pageCount": 2,
"wordCount": 450,
"documentIR": { ... }
},
"extract": {
"tokensUsed": 1250,
"model": "gpt-4.1"
}
}
}
Response Fields
| Field | Type | Description |
|---|
id | string | Execution identifier |
flowId | string | Flow that was executed |
version | string | Flow version used |
status | string | Current status (see below) |
progress | object | Progress info (while running) |
progress.step | string | Current step name |
progress.percentage | number | Estimated completion (0-100) |
createdAt | string | ISO 8601 start timestamp |
completedAt | string | ISO 8601 completion timestamp |
output | object | Extracted data (when completed) |
error | object | Error details (when failed) |
error.code | string | Error code |
error.message | string | Error description |
error.step | string | Step that failed |
metrics | object | Execution metrics |
artifacts | object | Step-level artifacts (if requested) |
metadata | object | Custom metadata from request |
Execution Status Values
| Status | Description |
|---|
pending | Queued, not yet started |
running | Currently processing |
completed | Successfully finished |
failed | Failed with error |
cancelled | Cancelled by user |
Examples
cURL
curl https://app.doclo.ai/api/v1/runs/exec_abc123def456 \
-H "Authorization: Bearer dc_live_your_api_key"
With Artifacts
curl "https://app.doclo.ai/api/v1/runs/exec_abc123def456?include=artifacts,metrics" \
-H "Authorization: Bearer dc_live_your_api_key"
TypeScript Polling
async function pollExecution(executionId: string): Promise<ExecutionResult> {
const maxAttempts = 60;
const pollInterval = 2000;
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const response = await fetch(
`https://app.doclo.ai/api/v1/runs/${executionId}`,
{
headers: {
'Authorization': `Bearer ${process.env.DOCLO_API_KEY}`
}
}
);
const result = await response.json();
switch (result.status) {
case 'completed':
return result;
case 'failed':
throw new Error(`Execution failed: ${result.error.message}`);
case 'cancelled':
throw new Error('Execution was cancelled');
case 'pending':
case 'running':
// Still processing, wait and retry
console.log(`Status: ${result.status}, Progress: ${result.progress?.percentage || 0}%`);
await new Promise(resolve => setTimeout(resolve, pollInterval));
break;
}
}
throw new Error('Polling timeout exceeded');
}
// Usage
const executionId = 'exec_abc123def456';
const result = await pollExecution(executionId);
console.log('Output:', result.output);
Check Status Only
const response = await fetch(
`https://app.doclo.ai/api/v1/runs/${executionId}`,
{
headers: {
'Authorization': `Bearer ${apiKey}`
}
}
);
const { status, progress } = await response.json();
if (status === 'running') {
console.log(`Processing: ${progress.step} (${progress.percentage}%)`);
}
Errors
| Status | Code | Description |
|---|
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | API key missing executions:read scope |
| 404 | EXECUTION_NOT_FOUND | Execution doesn’t exist |
| 429 | RATE_LIMITED | Rate limit exceeded |
Polling Best Practices
- Start with longer intervals: Begin with 2-3 second intervals
- Use exponential backoff: If still pending after 30s, increase interval
- Set a maximum timeout: Don’t poll forever (e.g., max 10 minutes)
- Consider webhooks: For production, webhooks are more efficient than polling
// Exponential backoff polling
async function pollWithBackoff(executionId: string) {
let interval = 2000;
const maxInterval = 10000;
const timeout = 600000; // 10 minutes
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const result = await getExecution(executionId);
if (result.status === 'completed' || result.status === 'failed') {
return result;
}
await new Promise(resolve => setTimeout(resolve, interval));
interval = Math.min(interval * 1.5, maxInterval);
}
throw new Error('Timeout');
}
Next Steps
Cancel Execution
Cancel a running execution
Webhooks
Use webhooks instead of polling