Skip to main content
A run is a single execution of an agent with a specific prompt. You create a run, execute it, and then retrieve the results.
This page covers the run lifecycle APIs. If you want the simpler one-call execute flow that returns the final answer directly, see Execute.

Run lifecycle

  queued ──→ running ──→ completed
                    └──→ failed

    └──→ cancelled
StatusDescription
queuedCreated, waiting for exec
runningExecuting in a sandbox
completedFinished successfully
failedExecution error
cancelledCancelled by user

List runs

Endpoint
GET /agent/v1/run
Retrieve runs for your organization with optional filters and cursor-based pagination.
const { runs, hasMore, nextCursor } = await client.agent.v1.run.list({
  agentId: 'agent_abc123',
  status: 'completed',
  limit: 20,
})

// Fetch next page
if (hasMore) {
  const page2 = await client.agent.v1.run.list({ cursor: nextCursor })
}

Query parameters

ParameterTypeRequiredDescription
agentIdstringnoFilter by agent ID
statusstringnoFilter by status (queued, running, completed, failed, cancelled)
limitintegernoMax results per page (1-250, default 50)
cursorstringnoRun ID from a previous page’s nextCursor

Response

{
  "runs": [
    {
      "id": "run_abc123",
      "agentId": "agent_abc123",
      "status": "completed",
      "prompt": "Search vault vault_xyz for all references to...",
      "model": "anthropic/claude-sonnet-4.6",
      "createdAt": "2026-03-01T12:00:00Z",
      "startedAt": "2026-03-01T12:00:01Z",
      "completedAt": "2026-03-01T12:02:30Z"
    }
  ],
  "hasMore": true,
  "nextCursor": "run_abc122"
}
The prompt field is truncated to 200 characters in list responses. Use the details endpoint to get the full prompt.

Step 1: Create a run

Endpoint
POST /agent/v1/run
Creating a run queues it — it does not start execution. This lets you register watchers before the agent starts working.
const run = await client.agent.v1.run.create({
  agentId: 'agent_abc123',
  prompt:
    'Search vault vault_xyz for all references to force majeure clauses and compile a summary.',
})

console.log(run.id) // run_xxx
console.log(run.status) // "queued"

Run parameters

ParameterTypeRequiredDescription
agentIdstringyesAgent to run
promptstringyesTask for the agent
guidancestringnoAdditional context or constraints for this specific run
modelstringnoOverride the agent’s default model
objectIdsstring[]noScope this run to specific vault object IDs (runtime restriction)

Guidance vs. instructions

The agent’s instructions define its general behavior. The run’s guidance adds context for a specific execution:
// Agent instructions: "You analyze contracts for risk."
// Run guidance adds specifics for this particular run:
const run = await client.agent.v1.run.create({
  agentId: agent.id,
  prompt: 'Analyze the master services agreement in vault vault_abc',
  guidance:
    'Focus on indemnification and limitation of liability. The client is in healthcare, so flag any HIPAA-related concerns.',
})

Model override

Use a different model for a specific run without changing the agent:
const run = await client.agent.v1.run.create({
  agentId: agent.id,
  prompt: 'Quick summary of document vault_abc/obj_xyz',
  model: 'anthropic/claude-haiku-3.5', // faster, cheaper for simple tasks
})

Object ID scoping

Restrict a run to specific vault objects at runtime. This is useful when you want a general-purpose agent to only work with specific documents for a particular task:
const run = await client.agent.v1.run.create({
  agentId: agent.id,
  prompt: 'Summarize these depositions and identify contradictions.',
  objectIds: ['obj_depo_001', 'obj_depo_002', 'obj_depo_003'],
})
Object scoping is applied at runtime, not at agent creation. This means the same agent can work with different sets of documents on each run. The agent’s vaultIds restriction (set at creation) is still enforced — objectIds adds a further narrowing within allowed vaults.

Step 2: Execute the run

Endpoint
POST /agent/v1/run/:id/exec
Execution starts a durable workflow that spins up a sandbox and runs the agent. The endpoint returns immediately — the work happens in the background.
const result = await client.agent.v1.run.exec(run.id)
console.log(result.status) // "running"
Response
{
  "id": "run_abc123",
  "status": "running",
  "workflowId": "wrun_xxx",
  "message": "Run started. Poll /run/:id/status or register a watcher."
}
Exec is a one-shot operation. Calling exec on a run that’s already been started returns 409 Conflict. Each run can only be executed once.

Step 3: Wait for completion

Two options: poll the status endpoint, or register a watcher before executing.

Option A: Poll

let status = await client.agent.v1.run.getStatus(run.id)

while (status.status === 'running') {
  await new Promise((r) => setTimeout(r, 2000))
  status = await client.agent.v1.run.getStatus(run.id)
}

if (status.status === 'completed') {
  const details = await client.agent.v1.run.getDetails(run.id)
  console.log(details.result.output)
}

Option B: Watch (webhook callback)

Register a callback URL before executing. You’ll receive a POST when the run completes:
// 1. Create run
const run = await client.agent.v1.run.create({
  agentId: agent.id,
  prompt: 'Analyze the contract...',
})

// 2. Register watcher BEFORE exec
await client.agent.v1.run.watch(run.id, {
  callbackUrl: 'https://your-app.com/webhooks/agent-complete',
})

// 3. Execute
await client.agent.v1.run.exec(run.id)
// Your webhook receives the result when done
See Monitoring & Analysis for details on webhook payloads and polling patterns.

Step 4: Stream run events

Endpoint
GET /agent/v1/run/:id/events
The run events endpoint streams SSE for run execution with server-side replay buffering. It includes synthetic terminal events emitted by Case.dev:
  • run.completed
  • run.failed
  • run.cancelled
Use this endpoint to drive live progress UI and to recover from disconnects.

Replay after reconnect

You can replay from a sequence number using either:
  • Query param: lastEventId
  • Header: Last-Event-ID
# Stream live (and replay from the beginning)
curl -N "https://api.case.dev/agent/v1/run/$RUN_ID/events?lastEventId=0" \
  -H "Authorization: Bearer $CASEDEV_API_KEY"
Example SSE events
id: 12
event: message.part.updated
data: {"type":"message.part.updated",...}

id: 18
event: run.completed
data: {"type":"run.completed","runId":"run_...","status":"completed",...}
If the run is already terminal when you connect, the endpoint returns buffered events and then sends a close event.

Cancel a run

Endpoint
POST /agent/v1/run/:id/cancel
Cancel a queued or running run. Cancelling a completed run returns the current status without error.
const result = await client.agent.v1.run.cancel(run.id)
console.log(result.status) // "cancelled"

Complete example

Create an agent, run a complex multi-step task, and get the results:
import Casedev from '@case.dev/sdk'

const client = new Casedev({ apiKey: process.env.CASEDEV_API_KEY })

// Create a research agent
const agent = await client.agents.create({
  name: 'Legal Researcher',
  instructions: `You are a legal research assistant. When given a topic:
1. Search vaults for relevant documents
2. Use legal search to find related case law and statutes
3. Compile a research memo in markdown
4. Upload the memo to the vault
5. Return the vault object ID and download URL`,
})

// Run it
const run = await client.agent.v1.run.create({
  agentId: agent.id,
  prompt:
    'Research employment discrimination laws relevant to the documents in vault vault_abc. Upload a report.',
})

await client.agent.v1.run.exec(run.id)

// Wait for completion
let status = await client.agent.v1.run.getStatus(run.id)
while (status.status === 'running') {
  console.log(`Running... ${Math.round(status.durationMs / 1000)}s`)
  await new Promise((r) => setTimeout(r, 5000))
  status = await client.agent.v1.run.getStatus(run.id)
}

// Get results
const details = await client.agent.v1.run.getDetails(run.id)
console.log(details.result.output)

Typical run times

Task complexityExampleDuration
Simple”Say hello”10-20s
Medium”List services and describe them”20-45s
Complex”Search vault, research laws, compile report, upload”2-6 min
Most of the run time is the AI thinking and making API calls — sandbox startup is under 10 seconds.

Next: Monitor and analyze

Learn how to get detailed results, audit trails, and set up webhooks →