---
title: List feature flags
description: "Reference for the GET /v1/projects/{project_id}/flags API endpoint."
product: general
lang: en
last_updated: 2026-09-15
token_estimate: 2817
---
# List feature flags

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

## List feature flags

**GET** `/v1/projects/{project_id}/flags`

Full URL: `https://developer-api.amplitude.com/v1/projects/{project_id}/flags`

**Servers:**
- Production (US): `https://developer-api.amplitude.com/v1/projects/{project_id}/flags`
- Production (EU): `https://developer-api.eu.amplitude.com/v1/projects/{project_id}/flags`

List feature flags

## Authorizations

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| Authorization | string | Yes | — | http |

## Path parameters

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| project_id (path) | string | Yes | 12345 | Amplitude project identifier, backed by the canonical app ID. Constraints: pattern: ^[0-9]+$ |

## Query parameters

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| cursor (query) | string | No | — | Opaque cursor from `pagination.next_cursor` on the previous response. Numeric offsets are capped by the underlying search index (10,000 results per query). Well-formed pagination stops before that window; requests whose cursor would exceed it return 400 `pagination_not_supported`. Constraints: nullable |
| limit (query) | integer | No | 50 | Number of items to return. Defaults to 50, max 200. Constraints: min: 1, max: 200 |

## Response (application/json)

**200** — Successful response.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| data | object[] | Yes | — | — |
| data.id | string | Yes | — | — |
| data.project_id | string | Yes | — | Constraints: pattern: ^[0-9]+$ |
| data.key | string | Yes | — | — |
| data.name | string | Yes | — | — |
| data.description | string | No | — | Constraints: nullable |
| data.deployments | string[] | No | — | Deployment IDs associated with this flag. Managed via the create/update deployment fields, not set directly on this field. |
| data.enabled | boolean | Yes | — | — |
| data.evaluation_mode | string | Yes | — | Allowed values: local, remote |
| data.variants | object[] | Yes | — | — |
| data.variants.key | string | Yes | — | Stable variant key. The value `off` is reserved. Constraints: pattern: ^[A-Za-z0-9_-]+$ |
| data.variants.name | string | No | — | Constraints: nullable |
| data.variants.description | string | No | — | Constraints: nullable |
| data.variants.payload | unknown | No | — | Optional JSON payload returned by evaluation. |
| data.bucketing_key | string | Yes | — | Bucketing key used for assignment. Never null in responses; defaults to `amplitude_id` when not explicitly set. |
| data.bucketing_salt | string | No | — | Constraints: nullable |
| data.bucketing_unit | string | No | — | Constraints: nullable |
| data.rollout_percentage | integer | Yes | — | Constraints: min: 0, max: 100 |
| data.rollout_weights | object | Yes | — | Variant-keyed rollout weights. Values may be normalized to sum to 100 (percentages) or expressed as unnormalized relative weights (for example `{ "control": 1, "treatment": 1 }` for an even split). Weights are non-negative and may be fractional. |
| data.target_segments | object[] | Yes | — | — |
| data.target_segments.name | string | No | — | Constraints: nullable |
| data.target_segments.conditions | object[] | Yes | — | — |
| data.target_segments.conditions.group_type | string | No | — | Constraints: nullable |
| data.target_segments.conditions.prop | string | Yes | — | Property name or cohort identifier being targeted. Constraints: min length: 1 |
| data.target_segments.conditions.prop_type | string | No | — | Namespace of the targeted property, for example `user`, `event`, or `group`. Omitted for conditions that target a cohort rather than a property. Constraints: nullable |
| data.target_segments.conditions.op | string | Yes | — | Targeting operator applied to the property values. Allowed values: is, is not, contains, does not contain, less, less or equal, greater, greater or equal, set is, set is not, set contains, set does not contain, glob match, glob does not match |
| data.target_segments.conditions.type | string | Yes | — | Condition type, for example `property` or `cohort`. |
| data.target_segments.conditions.values | string[] | Yes | — | At least one value to match against. Conditions with no values are rejected. |
| data.target_segments.percentage | integer | No | — | Segment rollout percentage. Constraints: nullable, min: 0, max: 100 |
| data.target_segments.rollout_weights | object | No | — | Variant-keyed rollout weights. Values may be normalized to sum to 100 (percentages) or expressed as unnormalized relative weights (for example `{ "control": 1, "treatment": 1 }` for an even split). Weights are non-negative and may be fractional. |
| data.target_segments.bucketing_key | string | No | — | Constraints: nullable |
| data.testers | object[] | No | — | — |
| data.testers.variant_key | string | Yes | — | — |
| data.testers.values | string[] | Yes | — | User IDs, device IDs, or cohort identifiers included in this variant. At most 2000 entries per variant (the limit is 10 when the entries are cohort identifiers). |
| data.owners | string[] | No | — | — |
| data.tags | string[] | Yes | — | — |
| data.created_by | string | No | — | Constraints: nullable |
| data.last_modified_by | string | No | — | Constraints: nullable |
| data.created_at | string | No | — | Constraints: format: date-time, nullable |
| data.updated_at | string | No | — | Constraints: format: date-time, nullable |
| data.parent_dependencies | object | No | — | — |
| data.parent_dependencies.operator | string | Yes | — | Allowed values: all, any |
| data.parent_dependencies.flags | object[] | Yes | — | — |
| data.parent_dependencies.flags.flag_id | string | Yes | — | — |
| data.parent_dependencies.flags.allowed_variants | string[] | No | — | — |
| data.links | object[] | No | — | — |
| data.links.url | string | Yes | — | Constraints: format: uri |
| data.links.title | string | Yes | — | — |
| data.version | integer | Yes | — | Server-managed config version used for optimistic concurrency. |
| data.archived | boolean | Yes | — | Whether the resource is archived. Set via the archive (DELETE) operation. |
| data.url | string | No | — | Constraints: format: uri, nullable |
| data.object | string | Yes | — | Resource-type discriminator. Always `feature_flag`. |
| pagination | object | Yes | — | — |
| pagination.next_cursor | string | Yes | — | Cursor for the next page, or `null` on the last page. Chart list responses may stop before all project charts are enumerated because the search backend caps each query at 10,000 sorted hits. Constraints: nullable |
| pagination.has_more | boolean | Yes | — | — |

```json
{
  "data": [
    {
      "id": "string",
      "project_id": "string",
      "key": "string",
      "name": "string",
      "description": "string",
      "deployments": [
        "string"
      ],
      "enabled": true,
      "evaluation_mode": "local",
      "variants": [
        {
          "key": "string",
          "name": "string",
          "description": "string",
          "payload": null
        }
      ],
      "bucketing_key": "string",
      "bucketing_salt": "string",
      "bucketing_unit": "string",
      "rollout_percentage": 0,
      "rollout_weights": {},
      "target_segments": [
        {
          "name": "string",
          "conditions": [
            {
              "group_type": "string",
              "prop": "string",
              "prop_type": "string",
              "op": "is",
              "type": "string",
              "values": [
                "string"
              ]
            }
          ],
          "percentage": 0,
          "rollout_weights": {},
          "bucketing_key": "string"
        }
      ],
      "testers": [
        {
          "variant_key": "string",
          "values": [
            "string"
          ]
        }
      ],
      "owners": [
        "string"
      ],
      "tags": [
        "string"
      ],
      "created_by": "string",
      "last_modified_by": "string",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z",
      "parent_dependencies": {
        "operator": "all",
        "flags": [
          {
            "flag_id": "string",
            "allowed_variants": [
              "string"
            ]
          }
        ]
      },
      "links": [
        {
          "url": "https://example.com",
          "title": "string"
        }
      ],
      "version": 0,
      "archived": true,
      "url": "https://example.com",
      "object": "feature_flag"
    }
  ],
  "pagination": {
    "next_cursor": "string",
    "has_more": true
  }
}
```

**400**

**401**

**403**

**429**

**500**

## Code samples

### cURL

```bash
curl -X GET "https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50" \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_API_KEY"
```

### Python

```python
import requests

response = requests.get(
    "https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50",
    headers={
        "Content-Type": "application/json",
        "Authorization": "YOUR_API_KEY"
    }
)
data = response.json()
```

### JavaScript

```javascript
const response = await fetch("https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50", {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "YOUR_API_KEY"
  }
});
const data = await response.json();
```

### PHP

```php
<?php
$ch = curl_init("https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json",
    "Authorization: YOUR_API_KEY"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
```

### Go

```go
package main

import (
  "bytes"
  "net/http"
)

func main() {
req, _ := http.NewRequest("GET", "https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50", nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "YOUR_API_KEY")
  client := &http.Client{}
  resp, _ := client.Do(req)
  defer resp.Body.Close()
}
```

### Java

```java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50"))
      .method("GET", HttpRequest.BodyPublishers.noBody())
.header("Content-Type", "application/json")
      .header("Authorization", "YOUR_API_KEY")
      .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
```

### Ruby

```ruby
require "net/http"
require "json"

uri = URI("https://developer-api.amplitude.com/v1/projects/12345/flags?limit=50")
request = Net::HTTP::Get.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "YOUR_API_KEY"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end
```

