Skip to main content
GET
/
v1
/
workflows
/
runs
/
{run_id}
from retab import Retab

client = Retab()

run = client.workflows.runs.get("run_abc123xyz")

print(f"Lifecycle: {run.lifecycle.status}")
if run.lifecycle.status == "completed":
    if run.timing.started_at and run.timing.completed_at:
        duration_ms = int((run.timing.completed_at - run.timing.started_at).total_seconds() * 1000)
        print(f"Duration: {duration_ms}ms")
    for step_summary in client.workflows.steps.list(run.id):
        step = client.workflows.steps.get(step_summary.step_id)
        if step.handle_outputs:
            print(f"{step.block_id}: {step.handle_outputs}")
import { Retab } from "@retab/node";

const client = new Retab({ apiKey: process.env.RETAB_API_KEY });

const run = await client.workflows.runs.get("run_abc123xyz");

console.log(`Lifecycle: ${run.lifecycle.status}`);
if (run.lifecycle.status === "completed") {
  if (run.timing.startedAt && run.timing.completedAt) {
    const durationMs =
      new Date(run.timing.completedAt).getTime() -
      new Date(run.timing.startedAt).getTime();
    console.log(`Duration: ${durationMs}ms`);
  }
  const stepSummaries = await client.workflows.steps.list({ runId: run.id });
  for (const stepSummary of stepSummaries.data) {
    const step = await client.workflows.steps.get(stepSummary.stepId);
    if (Object.keys(step.handleOutputs).length > 0) {
      console.log(`${step.blockId}:`, step.handleOutputs);
    }
  }
}
package main

import (
	"context"
	"fmt"
	"log"

	retab "github.com/retab-dev/retab/clients/go"
)

func ptr[T any](v T) *T { return &v }

func main() {
	ctx := context.Background()

	client, err := retab.NewClient("")
	if err != nil {
		log.Fatal(err)
	}

	run, err := client.Workflows.Runs.Get(ctx, "run_abc123xyz")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Lifecycle: %v\n", run.Lifecycle.Status())
	if run.Lifecycle.Status() == "completed" {
		stepSummaries, err := client.Workflows.Steps.List(ctx, &retab.WorkflowStepsListParams{
			RunID: ptr(run.ID),
		})
		if err != nil {
			log.Fatal(err)
			}
			for _, summary := range stepSummaries.Data {
				step, err := client.Workflows.Steps.Get(ctx, summary.StepID, nil)
				if err != nil {
					log.Fatal(err)
				}
			if len(step.HandleOutputs) > 0 {
				fmt.Printf("%s: %v\n", step.BlockID, step.HandleOutputs)
			}
		}
	}
}
require 'retab'

client = Retab::Client.new(api_key: ENV['RETAB_API_KEY'])

run = client.workflows.runs.get(run_id: 'run_abc123xyz')

puts "Lifecycle: #{run.lifecycle.status}"
if run.lifecycle.status == 'completed'
  step_summaries = client.workflows.steps.list(run_id: run.id)
  step_summaries.data.each do |summary|
    step = client.workflows.steps.get(step_id: summary.step_id)
    puts "#{step.block_id}: #{step.handle_outputs}" if step.handle_outputs && !step.handle_outputs.empty?
  end
end
use retab::Retab;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Retab::new(std::env::var("RETAB_API_KEY")?);

    let run = client.workflows().runs().get("run_abc123xyz").await?;

    println!("Lifecycle: {:?}", run.lifecycle);
    println!(
        "Started: {:?}, Completed: {:?}",
        run.timing.started_at, run.timing.completed_at
    );
    Ok(())
}
<?php
require 'vendor/autoload.php';

use Retab\Client;

$client = new Client(apiKey: getenv('RETAB_API_KEY'));

$result = $client->workflows()->runs()->get(
    runId: 'run_abc123',
);
print_r($result);
using Retab;
using RetabClient = Retab.Retab;

var apiKey = Environment.GetEnvironmentVariable("RETAB_API_KEY")!;
var client = new RetabClient(apiKey);

var result = await client.Workflows.Runs.GetAsync("run_abc123");
Console.WriteLine(result);
import com.retab.RetabClient;

public final class Example {
  public static void main(String[] args) throws Exception {
    RetabClient client = new RetabClient(System.getenv("RETAB_API_KEY"));

    var result = client.workflows().runs().get("run_abc123");
    System.out.println(result);
  }
}
curl -X 'GET' \
  'https://api.retab.com/v1/workflows/runs/run_abc123xyz' \
  -H 'Authorization: Bearer <your-api-key>'
{
  "id": "run_abc123xyz",
  "workflow": {
    "workflow_id": "wf_abc123xyz",
    "version_id": "ver_abc123xyz"
  },
  "trigger": { "type": "api" },
  "lifecycle": { "status": "completed" },
  "timing": {
    "created_at": "2024-01-15T10:30:00Z",
    "started_at": "2024-01-15T10:30:00Z",
    "completed_at": "2024-01-15T10:30:15Z"
  },
  "inputs": {
    "documents": {
      "start_document-block-1": {
        "id": "file_123",
        "filename": "invoice.pdf",
        "mime_type": "application/pdf"
      }
    },
    "json_data": {}
  }
}
{
  "detail": "Workflow run not found"
}
Get a single workflow run by ID. Use this endpoint to check lifecycle.status for a running workflow or retrieve the results of a completed workflow. Run timing includes timestamps, not precomputed duration fields. Derive duration from timing.completed_at - timing.started_at when both timestamps are present. Run responses do not embed step records. Use List Steps for per-block status and started_at / completed_at, and use Get Step for typed handle inputs and outputs. For persisted step records such as review-trigger evaluations, function invocations, or API call traces, use List Artifacts.
from retab import Retab

client = Retab()

run = client.workflows.runs.get("run_abc123xyz")

print(f"Lifecycle: {run.lifecycle.status}")
if run.lifecycle.status == "completed":
    if run.timing.started_at and run.timing.completed_at:
        duration_ms = int((run.timing.completed_at - run.timing.started_at).total_seconds() * 1000)
        print(f"Duration: {duration_ms}ms")
    for step_summary in client.workflows.steps.list(run.id):
        step = client.workflows.steps.get(step_summary.step_id)
        if step.handle_outputs:
            print(f"{step.block_id}: {step.handle_outputs}")
import { Retab } from "@retab/node";

const client = new Retab({ apiKey: process.env.RETAB_API_KEY });

const run = await client.workflows.runs.get("run_abc123xyz");

console.log(`Lifecycle: ${run.lifecycle.status}`);
if (run.lifecycle.status === "completed") {
  if (run.timing.startedAt && run.timing.completedAt) {
    const durationMs =
      new Date(run.timing.completedAt).getTime() -
      new Date(run.timing.startedAt).getTime();
    console.log(`Duration: ${durationMs}ms`);
  }
  const stepSummaries = await client.workflows.steps.list({ runId: run.id });
  for (const stepSummary of stepSummaries.data) {
    const step = await client.workflows.steps.get(stepSummary.stepId);
    if (Object.keys(step.handleOutputs).length > 0) {
      console.log(`${step.blockId}:`, step.handleOutputs);
    }
  }
}
package main

import (
	"context"
	"fmt"
	"log"

	retab "github.com/retab-dev/retab/clients/go"
)

func ptr[T any](v T) *T { return &v }

func main() {
	ctx := context.Background()

	client, err := retab.NewClient("")
	if err != nil {
		log.Fatal(err)
	}

	run, err := client.Workflows.Runs.Get(ctx, "run_abc123xyz")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Lifecycle: %v\n", run.Lifecycle.Status())
	if run.Lifecycle.Status() == "completed" {
		stepSummaries, err := client.Workflows.Steps.List(ctx, &retab.WorkflowStepsListParams{
			RunID: ptr(run.ID),
		})
		if err != nil {
			log.Fatal(err)
			}
			for _, summary := range stepSummaries.Data {
				step, err := client.Workflows.Steps.Get(ctx, summary.StepID, nil)
				if err != nil {
					log.Fatal(err)
				}
			if len(step.HandleOutputs) > 0 {
				fmt.Printf("%s: %v\n", step.BlockID, step.HandleOutputs)
			}
		}
	}
}
require 'retab'

client = Retab::Client.new(api_key: ENV['RETAB_API_KEY'])

run = client.workflows.runs.get(run_id: 'run_abc123xyz')

puts "Lifecycle: #{run.lifecycle.status}"
if run.lifecycle.status == 'completed'
  step_summaries = client.workflows.steps.list(run_id: run.id)
  step_summaries.data.each do |summary|
    step = client.workflows.steps.get(step_id: summary.step_id)
    puts "#{step.block_id}: #{step.handle_outputs}" if step.handle_outputs && !step.handle_outputs.empty?
  end
end
use retab::Retab;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Retab::new(std::env::var("RETAB_API_KEY")?);

    let run = client.workflows().runs().get("run_abc123xyz").await?;

    println!("Lifecycle: {:?}", run.lifecycle);
    println!(
        "Started: {:?}, Completed: {:?}",
        run.timing.started_at, run.timing.completed_at
    );
    Ok(())
}
<?php
require 'vendor/autoload.php';

use Retab\Client;

$client = new Client(apiKey: getenv('RETAB_API_KEY'));

$result = $client->workflows()->runs()->get(
    runId: 'run_abc123',
);
print_r($result);
using Retab;
using RetabClient = Retab.Retab;

var apiKey = Environment.GetEnvironmentVariable("RETAB_API_KEY")!;
var client = new RetabClient(apiKey);

var result = await client.Workflows.Runs.GetAsync("run_abc123");
Console.WriteLine(result);
import com.retab.RetabClient;

public final class Example {
  public static void main(String[] args) throws Exception {
    RetabClient client = new RetabClient(System.getenv("RETAB_API_KEY"));

    var result = client.workflows().runs().get("run_abc123");
    System.out.println(result);
  }
}
curl -X 'GET' \
  'https://api.retab.com/v1/workflows/runs/run_abc123xyz' \
  -H 'Authorization: Bearer <your-api-key>'
{
  "id": "run_abc123xyz",
  "workflow": {
    "workflow_id": "wf_abc123xyz",
    "version_id": "ver_abc123xyz"
  },
  "trigger": { "type": "api" },
  "lifecycle": { "status": "completed" },
  "timing": {
    "created_at": "2024-01-15T10:30:00Z",
    "started_at": "2024-01-15T10:30:00Z",
    "completed_at": "2024-01-15T10:30:15Z"
  },
  "inputs": {
    "documents": {
      "start_document-block-1": {
        "id": "file_123",
        "filename": "invoice.pdf",
        "mime_type": "application/pdf"
      }
    },
    "json_data": {}
  }
}
{
  "detail": "Workflow run not found"
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

run_id
string
required

Response

Successful Response

A single execution of a workflow.

id
string
required

Unique ID for this run

workflow_id
string
required

ID of the workflow that was run

workflow_version_id
string
required

Content-addressed workflow version used for this run.

trigger
TriggerInfo · object
required

What started this run

lifecycle
PendingRun · object
required

The run has been created but execution has not started.

timing
RunTiming · object
required

All timing information

inputs
RunInputs · object

Input payloads supplied at run creation time

metadata
Metadata · object | null

User-defined metadata associated with this workflow run.