Skip to main content
GET
/
threads
/
{thread_id}
/
runs
/
{run_id}
/
steps
/
{step_id}
cURL
curl https://api.portkey.ai/v1/threads/thread_abc123/runs/run_abc123/steps/step_abc123 \
  -H "x-portkey-api-key: $PORTKEY_API_KEY" \
  -H "x-portkey-virtual-key: $PORTKEY_PROVIDER_VIRTUAL_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v2"
from portkey_ai import Portkey

client = Portkey(
  api_key = "PORTKEY_API_KEY",
  virtual_key = "PROVIDER_VIRTUAL_KEY"
)

run_step = client.beta.threads.runs.steps.retrieve(
    thread_id="thread_abc123",
    run_id="run_abc123",
    step_id="step_abc123"
)

print(run_step)
import Portkey from 'portkey-ai';

const client = new Portkey({
  apiKey: 'PORTKEY_API_KEY',
  virtualKey: 'PROVIDER_VIRTUAL_KEY'
});

async function main() {
  const runStep = await client.beta.threads.runs.steps.retrieve(
    "thread_abc123",
    "run_abc123",
    "step_abc123"
  );
  console.log(runStep);
}

main();
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.portkey.ai/v1/threads/{thread_id}/runs/{run_id}/steps/{step_id}",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "x-portkey-api-key: <api-key>",
    "x-portkey-virtual-key: <api-key>"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.portkey.ai/v1/threads/{thread_id}/runs/{run_id}/steps/{step_id}"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("x-portkey-api-key", "<api-key>")
	req.Header.Add("x-portkey-virtual-key", "<api-key>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://api.portkey.ai/v1/threads/{thread_id}/runs/{run_id}/steps/{step_id}")
  .header("x-portkey-api-key", "<api-key>")
  .header("x-portkey-virtual-key", "<api-key>")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://api.portkey.ai/v1/threads/{thread_id}/runs/{run_id}/steps/{step_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["x-portkey-api-key"] = '<api-key>'
request["x-portkey-virtual-key"] = '<api-key>'

response = http.request(request)
puts response.read_body
{
  "id": "<string>",
  "object": "thread.run.step",
  "created_at": 123,
  "assistant_id": "<string>",
  "thread_id": "<string>",
  "run_id": "<string>",
  "step_details": {
    "type": "message_creation",
    "message_creation": {
      "message_id": "<string>"
    }
  },
  "last_error": {
    "message": "<string>"
  },
  "expired_at": 123,
  "cancelled_at": 123,
  "failed_at": 123,
  "completed_at": 123,
  "metadata": {},
  "usage": {
    "completion_tokens": 123,
    "prompt_tokens": 123,
    "total_tokens": 123
  }
}

Authorizations

x-portkey-api-key
string
header
required
x-portkey-virtual-key
string
header
required

Path Parameters

thread_id
string
required

The ID of the thread to which the run and run step belongs.

run_id
string
required

The ID of the run to which the run step belongs.

step_id
string
required

The ID of the run step to retrieve.

Response

200 - application/json

OK

Represents a step in execution of a run.

id
string
required

The identifier of the run step, which can be referenced in API endpoints.

object
enum<string>
required

The object type, which is always thread.run.step.

Available options:
thread.run.step
created_at
integer
required

The Unix timestamp (in seconds) for when the run step was created.

assistant_id
string
required

The ID of the assistant associated with the run step.

thread_id
string
required

The ID of the thread that was run.

run_id
string
required

The ID of the run that this run step is a part of.

type
enum<string>
required

The type of run step, which can be either message_creation or tool_calls.

Available options:
message_creation,
tool_calls
status
enum<string>
required

The status of the run step, which can be either in_progress, cancelled, failed, completed, or expired.

Available options:
in_progress,
cancelled,
failed,
completed,
expired
step_details
Message creation · object
required

Details of the message creation by the run step.

last_error
object | null
required

The last error associated with this run step. Will be null if there are no errors.

expired_at
integer | null
required

The Unix timestamp (in seconds) for when the run step expired. A step is considered expired if the parent run is expired.

cancelled_at
integer | null
required

The Unix timestamp (in seconds) for when the run step was cancelled.

failed_at
integer | null
required

The Unix timestamp (in seconds) for when the run step failed.

completed_at
integer | null
required

The Unix timestamp (in seconds) for when the run step completed.

metadata
object | null
required

Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long.

usage
object | null
required

Usage statistics related to the run step. This value will be null while the run step's status is in_progress.

Last modified on April 2, 2026