Skip to main content
POST
/
api
/
v1
/
runs
/
{id}
/
cancel
Cancel Run
curl --request POST \
  --url https://api.example.com/api/v1/runs/{id}/cancel
Cancel a test run that is currently pending, running, or grading.

Request

POST /api/v1/runs/{id}/cancel
Authorization: Bearer YOUR_API_KEY

Path Parameters

ParameterTypeRequiredDescription
idstringYesUUID of the run to cancel

Response

FieldTypeDescription
idstringRun UUID
statusstringNew status (canceled)
messagestringConfirmation message

Examples

curl -X POST "https://app.preclinical.dev/api/v1/runs/7c9e6679-7425-40de-944b-e07fc1f90ae7/cancel" \
  -H "Authorization: Bearer $API_KEY"

Success Response (200)

{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "status": "canceled",
  "message": "Test run cancellation initiated"
}

Error Response (400)

{
  "error": "Cannot cancel run with status 'completed'. Only pending, running, or grading runs can be canceled.",
  "code": "INVALID_STATE",
  "details": {
    "current_status": "completed"
  }
}

Errors

CodeDescription
RUN_NOT_FOUNDRun not found or doesn’t belong to your organization
INVALID_STATERun is already completed, failed, or canceled

Cancelable States

A run can only be canceled when in one of these states:
StatusCancelable
pendingYes
runningYes
gradingYes
completedNo
failedNo
canceledNo

Use Cases

Cancel on Timeout

async function runWithTimeout(agentId, timeoutMs = 300000) {
  // Start the run
  const startResponse = await fetch('https://app.preclinical.dev/api/v1/runs', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ agent_id: agentId }),
  });

  const run = await startResponse.json();
  const startTime = Date.now();

  // Poll for completion with timeout
  while (Date.now() - startTime < timeoutMs) {
    const statusResponse = await fetch(
      `https://app.preclinical.dev/api/v1/runs/${run.id}`,
      { headers: { 'Authorization': `Bearer ${API_KEY}` } }
    );

    const status = await statusResponse.json();

    if (['completed', 'failed', 'canceled'].includes(status.status)) {
      return status;
    }

    await new Promise(r => setTimeout(r, 5000));
  }

  // Timeout - cancel the run
  await fetch(`https://app.preclinical.dev/api/v1/runs/${run.id}/cancel`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
  });

  throw new Error(`Run ${run.id} timed out and was canceled`);
}

Cancel on User Interrupt

// Handle SIGINT (Ctrl+C) to cancel running tests
let currentRunId = null;

process.on('SIGINT', async () => {
  if (currentRunId) {
    console.log('\nCanceling test run...');
    await fetch(`https://app.preclinical.dev/api/v1/runs/${currentRunId}/cancel`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${API_KEY}` },
    });
    console.log('Run canceled');
  }
  process.exit(0);
});

// Start a run
const run = await startRun(agentId);
currentRunId = run.id;

// Wait for completion...