> ## Documentation Index
> Fetch the complete documentation index at: https://docs.userjourneys.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Releases

> List and retrieve releases — access merged pull request metadata and the linked chat for each release.

A release represents a merged pull request in your project. Each release includes basic GitHub metadata and a `chat_id` pointing to the chat where the release analysis happened.

***

## `GET /v1/releases`

List releases for your project.

Returns releases in descending `merged_at` order, newest first.

### Request

<ParamField header="Authorization" type="string" required>
  Bearer token. See [Authentication](/api/authentication).
</ParamField>

<ParamField query="status" type="string">
  Filter by status: `"active"` or `"dismissed"`.
</ParamField>

<ParamField query="limit" type="integer">
  Number of releases to return. Default `20`, max `100`.
</ParamField>

<ParamField query="starting_after" type="string">
  Cursor for pagination. Pass the `id` of the last release from the previous page.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://app.userjourneys.ai/api/v1/releases \
    -H "Authorization: Bearer uj_live_your_key_here"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://app.userjourneys.ai/api/v1/releases",
    {
      headers: {
        Authorization: "Bearer uj_live_your_key_here",
      },
    }
  );
  const { data, has_more } = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://app.userjourneys.ai/api/v1/releases",
      headers={"Authorization": "Bearer uj_live_your_key_here"},
  )
  data = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "object": "list",
    "data": [
      {
        "id": "6a9f3b0d-6a8c-4cde-9e47-9d53f78a3d56",
        "object": "release",
        "status": "active",
        "chat_id": "7af6cf75-20ec-49f4-b113-929c01dfbe45",
        "github_pr_number": 482,
        "github_pr_title": "Ship release summary emails",
        "github_pr_url": "https://github.com/acme/product/pull/482",
        "github_pr_author": "alex",
        "merged_at": "2026-04-10T15:22:13.000Z",
        "last_analysis_at": "2026-04-10T15:25:44.000Z",
        "created_at": "2026-04-10T15:22:20.000Z"
      }
    ],
    "has_more": false
  }
  ```
</ResponseExample>

<Tip>
  Use `status=active` if you only want releases that are still active in the release workflow.
</Tip>

***

## `GET /v1/releases/:id`

Retrieve a single release with full pull request metadata.

### Request

<ParamField header="Authorization" type="string" required>
  Bearer token. See [Authentication](/api/authentication).
</ParamField>

<ParamField path="id" type="string" required>
  Release ID (UUID).
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://app.userjourneys.ai/api/v1/releases/6a9f3b0d-6a8c-4cde-9e47-9d53f78a3d56 \
    -H "Authorization: Bearer uj_live_your_key_here"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://app.userjourneys.ai/api/v1/releases/6a9f3b0d-6a8c-4cde-9e47-9d53f78a3d56",
    {
      headers: {
        Authorization: "Bearer uj_live_your_key_here",
      },
    }
  );
  const release = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://app.userjourneys.ai/api/v1/releases/6a9f3b0d-6a8c-4cde-9e47-9d53f78a3d56",
      headers={"Authorization": "Bearer uj_live_your_key_here"},
  )
  release = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "6a9f3b0d-6a8c-4cde-9e47-9d53f78a3d56",
    "object": "release",
    "status": "active",
    "chat_id": "7af6cf75-20ec-49f4-b113-929c01dfbe45",
    "github_pr_number": 482,
    "github_pr_title": "Ship release summary emails",
    "github_pr_description": "Adds release summary emails and related delivery metrics.",
    "github_pr_url": "https://github.com/acme/product/pull/482",
    "github_pr_author": "alex",
    "merged_at": "2026-04-10T15:22:13.000Z",
    "last_analysis_at": "2026-04-10T15:25:44.000Z",
    "created_at": "2026-04-10T15:22:20.000Z"
  }
  ```
</ResponseExample>

Returns `404` if the release doesn't exist or doesn't belong to your project.

***

## Release object

<ResponseField name="id" type="string">
  Release ID (UUID).
</ResponseField>

<ResponseField name="object" type="string">
  `"release"`
</ResponseField>

<ResponseField name="status" type="string">
  `"active"` or `"dismissed"`.
</ResponseField>

<ResponseField name="chat_id" type="string">
  ID of the linked [chat](/api/chats).
</ResponseField>

<ResponseField name="github_pr_number" type="integer">
  GitHub pull request number.
</ResponseField>

<ResponseField name="github_pr_title" type="string">
  GitHub pull request title.
</ResponseField>

<ResponseField name="github_pr_description" type="string | null">
  GitHub pull request description. Only returned by `GET /v1/releases/:id`.
</ResponseField>

<ResponseField name="github_pr_url" type="string">
  GitHub pull request URL.
</ResponseField>

<ResponseField name="github_pr_author" type="string">
  GitHub username or author handle for the pull request.
</ResponseField>

<ResponseField name="merged_at" type="string">
  ISO 8601 timestamp for when the pull request was merged.
</ResponseField>

<ResponseField name="last_analysis_at" type="string | null">
  ISO 8601 timestamp for the last release analysis run, or `null` if analysis has not run yet.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp for when the release record was created.
</ResponseField>
