Cancel a running or pending flow execution. Useful for aborting long-running jobs or stopping mistakenly triggered executions.
Endpoint
POST https://app.doclo.ai/api/v1/runs/{executionId}/cancel
Authentication
Requires an API key with executions:cancel scope.
Authorization: Bearer dc_live_your_api_key
Path Parameters
Parameter Type Description executionIdstring Required. The execution identifier to cancel
Request Body
No request body required. Send an empty POST request.
Response
Success (200 OK)
{
"id" : "exec_abc123def456" ,
"flowId" : "invoice-extractor" ,
"version" : "1.2.0" ,
"status" : "cancelled" ,
"createdAt" : "2024-02-20T15:30:00Z" ,
"cancelledAt" : "2024-02-20T15:30:45Z" ,
"metadata" : {
"customerId" : "cust_123"
}
}
Response Fields
Field Type Description idstring Execution identifier flowIdstring Flow that was being executed versionstring Flow version statusstring Always cancelled on success createdAtstring ISO 8601 start timestamp cancelledAtstring ISO 8601 cancellation timestamp metadataobject Custom metadata from original request
Examples
cURL
curl -X POST https://app.doclo.ai/api/v1/runs/exec_abc123def456/cancel \
-H "Authorization: Bearer dc_live_your_api_key"
TypeScript
async function cancelExecution ( executionId : string ) {
const response = await fetch (
`https://app.doclo.ai/api/v1/runs/ ${ executionId } /cancel` ,
{
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . DOCLO_API_KEY } `
}
}
);
if ( ! response . ok ) {
const { error } = await response . json ();
throw new Error ( `Cancel failed: ${ error . message } ` );
}
const result = await response . json ();
console . log ( `Execution ${ result . id } cancelled at ${ result . cancelledAt } ` );
return result ;
}
With Timeout Handling
async function processWithTimeout ( flowId : string , document : string , timeoutMs : number ) {
// Start execution
const startResponse = await fetch (
`https://app.doclo.ai/api/v1/flows/ ${ flowId } /run` ,
{
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
input: { document: { base64: document } }
})
}
);
const { id : executionId } = await startResponse . json ();
// Set up timeout
const timeoutPromise = new Promise (( _ , reject ) => {
setTimeout ( async () => {
// Cancel execution on timeout
await fetch (
`https://app.doclo.ai/api/v1/runs/ ${ executionId } /cancel` ,
{
method: 'POST' ,
headers: { 'Authorization' : `Bearer ${ apiKey } ` }
}
);
reject ( new Error ( 'Execution timed out and was cancelled' ));
}, timeoutMs );
});
// Poll for results
const pollPromise = pollExecution ( executionId );
return Promise . race ([ pollPromise , timeoutPromise ]);
}
Errors
Status Code Description 401 UNAUTHORIZEDMissing or invalid API key 403 FORBIDDENAPI key missing executions:cancel scope 404 EXECUTION_NOT_FOUNDExecution doesn’t exist 409 ALREADY_CANCELLEDExecution was already cancelled 409 NOT_CANCELLABLEExecution already completed or failed 429 RATE_LIMITEDRate limit exceeded
Error Examples
Already Cancelled:
{
"error" : {
"code" : "ALREADY_CANCELLED" ,
"message" : "Execution exec_abc123 was already cancelled"
}
}
Not Cancellable (completed):
{
"error" : {
"code" : "NOT_CANCELLABLE" ,
"message" : "Cannot cancel execution with status: completed"
}
}
Cancellation Behavior
Original Status Can Cancel Result pendingYes Immediately cancelled, no credits used runningYes Cancelled at next checkpoint, partial credits may apply completedNo Returns 409 error failedNo Returns 409 error cancelledNo Returns 409 error
Cancelling a running execution may not be immediate. The execution will be cancelled at the next processing checkpoint. Some credits may be charged for work already completed.
Use Cases
User-Initiated Cancellation
Allow users to cancel their own uploads:
// In your API route
app . post ( '/api/cancel-extraction/:executionId' , async ( req , res ) => {
const { executionId } = req . params ;
const userId = req . user . id ;
// Verify user owns this execution
const execution = await db . executions . findOne ({
executionId ,
userId
});
if ( ! execution ) {
return res . status ( 404 ). json ({ error: 'Execution not found' });
}
// Cancel via Doclo API
const response = await fetch (
`https://app.doclo.ai/api/v1/runs/ ${ executionId } /cancel` ,
{
method: 'POST' ,
headers: { 'Authorization' : `Bearer ${ process . env . DOCLO_API_KEY } ` }
}
);
if ( response . ok ) {
await db . executions . update ( executionId , { status: 'cancelled' });
return res . json ({ success: true });
}
const { error } = await response . json ();
return res . status ( response . status ). json ({ error: error . message });
});
Cleanup on Shutdown
Cancel pending executions during graceful shutdown:
const pendingExecutions = new Set < string >();
// Track started executions
async function startExecution ( flowId : string , input : any ) {
const result = await runFlow ( flowId , input );
pendingExecutions . add ( result . id );
return result ;
}
// Cleanup on shutdown
process . on ( 'SIGTERM' , async () => {
console . log ( 'Shutting down, cancelling pending executions...' );
await Promise . all (
Array . from ( pendingExecutions ). map ( async ( executionId ) => {
try {
await cancelExecution ( executionId );
console . log ( `Cancelled ${ executionId } ` );
} catch ( error ) {
// May already be completed, ignore errors
}
})
);
process . exit ( 0 );
});
Next Steps
Get Execution Check execution status
Run Flow Start a new execution