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

# Perform a List Users call

> List all users that have a certain relation with a particular object

This section will illustrate how to perform a [list users](https://docs.fga.dev/fga-concepts.md#what-is-a-list-users-request) request. The List Users call allows you to retrieve a list of [users](https://docs.fga.dev/fga-concepts.md#what-is-a-user) that have a specific [relationship](https://docs.fga.dev/fga-concepts.md#what-is-a-relationship) with a given [object](https://docs.fga.dev/fga-concepts.md#what-is-an-object).  This can be used in scenarios such as retrieving users who have access to a resource or managing members in a group.

## Before You Start

**Node.js**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [installed the SDK](https://docs.fga.dev/integration/install-sdk.md).
3. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md) and [updated the *relationship tuples*](https://docs.fga.dev/integration/update-tuples.md).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

**Go**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [installed the SDK](https://docs.fga.dev/integration/install-sdk.md).
3. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md) and [updated the *relationship tuples*](https://docs.fga.dev/integration/update-tuples.md).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

**.NET**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [installed the SDK](https://docs.fga.dev/integration/install-sdk.md).
3. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md) and [updated the *relationship tuples*](https://docs.fga.dev/integration/update-tuples.md).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

**Python**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [installed the SDK](https://docs.fga.dev/integration/install-sdk.md).
3. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md) and [updated the *relationship tuples*](https://docs.fga.dev/integration/update-tuples.md).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

**Java**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [installed the SDK](https://docs.fga.dev/integration/install-sdk.md).
3. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md) and [updated the *relationship tuples*](https://docs.fga.dev/integration/update-tuples.md).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

**CLI**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md).
3. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

**curl**

1. You have [obtained FGA API credentials](https://docs.fga.dev/integration/getting-your-api-keys.md) and set `FGA_API_URL`, `FGA_STORE_ID`, `FGA_API_TOKEN_ISSUER`, `FGA_API_AUDIENCE`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`.
2. You have [configured the *authorization model*](https://docs.fga.dev/modeling.md) and [updated the *relationship tuples*](https://docs.fga.dev/integration/update-tuples.md).
3. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

## Step by step

Consider the following model which includes a `user` that can have a `reader` relationship with a `document`:

FGA model · DSL

Assume that you want to list all users of type `user` that have a `reader` relationship with `document:planning`:

### 01. Configure the Auth0 FGA API client

Before calling the List Users API, you will need to configure the API client.

**Node.js**

```javascript theme={null}
const { CredentialsMethod, OpenFgaClient, ConsistencyPreference } = require('@openfga/sdk');

const fgaClient = new OpenFgaClient({
  apiUrl: process.env.FGA_API_URL, // https://api.us1.fga.dev, or your store's eu1/au1 region
  storeId: process.env.FGA_STORE_ID,
  authorizationModelId: process.env.FGA_MODEL_ID,
  credentials: {
    method: CredentialsMethod.ClientCredentials,
    config: {
      apiTokenIssuer: process.env.FGA_API_TOKEN_ISSUER, // auth.fga.dev
      apiAudience: process.env.FGA_API_AUDIENCE, // URL for your store's region
      clientId: process.env.FGA_CLIENT_ID,
      clientSecret: process.env.FGA_CLIENT_SECRET,
    },
  },
});
```

**Go**

```go theme={null}
package main

import (
    "os"
    . "github.com/openfga/go-sdk/client"
    "github.com/openfga/go-sdk/credentials"
)

// Configure FGA_API_URL and FGA_API_AUDIENCE for your store's us1/eu1/au1 region.
// Set FGA_STORE_ID, FGA_MODEL_ID, FGA_API_TOKEN_ISSUER, FGA_CLIENT_ID, and FGA_CLIENT_SECRET.
func main() {
    fgaClient, err := NewSdkClient(&ClientConfiguration{
        ApiUrl: os.Getenv("FGA_API_URL"),
        StoreId: os.Getenv("FGA_STORE_ID"),
        AuthorizationModelId: os.Getenv("FGA_MODEL_ID"),
        Credentials: &credentials.Credentials{
            Method: credentials.CredentialsMethodClientCredentials,
            Config: &credentials.Config{
                ClientCredentialsApiTokenIssuer: os.Getenv("FGA_API_TOKEN_ISSUER"),
                ClientCredentialsApiAudience: os.Getenv("FGA_API_AUDIENCE"),
                ClientCredentialsClientId: os.Getenv("FGA_CLIENT_ID"),
                ClientCredentialsClientSecret: os.Getenv("FGA_CLIENT_SECRET"),
            },
        },
    })
    if err != nil { panic(err) }
    _ = fgaClient // Use the client for the next request.
}
```

**.NET**

```csharp theme={null}
using System.Collections.Generic;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Client.Model;
using OpenFga.Sdk.Configuration;
using OpenFga.Sdk.Model;
using Environment = System.Environment;

// FGA_API_URL and FGA_API_AUDIENCE must match the store's us1/eu1/au1 region.
var fgaClient = new OpenFgaClient(new ClientConfiguration() {
  ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"),
  StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"),
  AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"),
  Credentials = new Credentials() {
    Method = CredentialsMethod.ClientCredentials,
    Config = new CredentialsConfig() {
      ApiTokenIssuer = Environment.GetEnvironmentVariable("FGA_API_TOKEN_ISSUER"),
      ApiAudience = Environment.GetEnvironmentVariable("FGA_API_AUDIENCE"),
      ClientId = Environment.GetEnvironmentVariable("FGA_CLIENT_ID"),
      ClientSecret = Environment.GetEnvironmentVariable("FGA_CLIENT_SECRET"),
    }
  }
});
```

**Python**

```python theme={null}
import os
from openfga_sdk.client import OpenFgaClient, ClientConfiguration
from openfga_sdk.client.models import ClientTuple
from openfga_sdk.models import RelationshipCondition, FgaObject, UserTypeFilter
from openfga_sdk.client.models.list_users_request import ClientListUsersRequest
from openfga_sdk.credentials import Credentials, CredentialConfiguration

# FGA_API_URL and FGA_API_AUDIENCE must match the store's us1/eu1/au1 region.
credentials = Credentials(
    method='client_credentials',
    configuration=CredentialConfiguration(
        api_issuer=os.environ.get('FGA_API_TOKEN_ISSUER'),
        api_audience=os.environ.get('FGA_API_AUDIENCE'),
        client_id=os.environ.get('FGA_CLIENT_ID'),
        client_secret=os.environ.get('FGA_CLIENT_SECRET'),
    ),
)
configuration = ClientConfiguration(
    api_url=os.environ.get('FGA_API_URL'),
    store_id=os.environ.get('FGA_STORE_ID'),
    authorization_model_id=os.environ.get('FGA_MODEL_ID'),
    credentials=credentials,
)
# Use: async with OpenFgaClient(configuration) as fga_client: ...
```

**Java**

```java theme={null}
import dev.openfga.sdk.api.client.OpenFgaClient;
import dev.openfga.sdk.api.configuration.ClientConfiguration;
import dev.openfga.sdk.api.configuration.ClientCredentials;
import dev.openfga.sdk.api.configuration.Credentials;
import dev.openfga.sdk.api.configuration.ClientCheckOptions;
import dev.openfga.sdk.api.configuration.ClientBatchCheckOptions;
import dev.openfga.sdk.api.configuration.ClientWriteOptions;
import dev.openfga.sdk.api.configuration.ClientListObjectsOptions;
import dev.openfga.sdk.api.configuration.ClientListUsersOptions;
import dev.openfga.sdk.api.client.model.*;
import dev.openfga.sdk.api.model.*;
import java.util.List;
import java.util.Map;

// FGA_API_URL and FGA_API_AUDIENCE must match the store's us1/eu1/au1 region.
public class SdkSetupExample {
    public static void main(String[] args) throws Exception {
        var config = new ClientConfiguration()
            .apiUrl(System.getenv("FGA_API_URL"))
            .storeId(System.getenv("FGA_STORE_ID"))
            .authorizationModelId(System.getenv("FGA_MODEL_ID"))
            .credentials(new Credentials(new ClientCredentials()
                .apiTokenIssuer(System.getenv("FGA_API_TOKEN_ISSUER"))
                .apiAudience(System.getenv("FGA_API_AUDIENCE"))
                .clientId(System.getenv("FGA_CLIENT_ID"))
                .clientSecret(System.getenv("FGA_CLIENT_SECRET"))));
        var fgaClient = new OpenFgaClient(config);
    }
}
```

**CLI**

```bash theme={null}
# Auth0 FGA managed API: choose your store's region (us1, eu1, or au1).
export FGA_API_URL=https://api.us1.fga.dev
export FGA_API_AUDIENCE=https://api.us1.fga.dev/
export FGA_API_TOKEN_ISSUER=auth.fga.dev
export FGA_STORE_ID=YOUR_STORE_ID
export FGA_MODEL_ID=YOUR_MODEL_ID
export FGA_CLIENT_ID=YOUR_CLIENT_ID
export FGA_CLIENT_SECRET=YOUR_CLIENT_SECRET
# Obtain these values from https://dashboard.fga.dev/ and keep credentials private.
```

**curl**

To obtain the [access token](https://auth0.com/docs/get-started/authentication-and-authorization-flow/call-your-api-using-the-client-credentials-flow):

```bash theme={null}
# Requires jq to safely encode credentials as JSON.
curl -sS -X POST 'https://auth.fga.dev/oauth/token' \
  -H 'content-type: application/json' \
  --data "$(jq -n \
    --arg client_id "$FGA_CLIENT_ID" \
    --arg client_secret "$FGA_CLIENT_SECRET" \
    --arg audience "$FGA_API_AUDIENCE" \
    '{client_id: $client_id, client_secret: $client_secret, audience: $audience, grant_type: "client_credentials"}')"
# Use the access_token in the response as FGA_BEARER_TOKEN for direct API calls.
```

### 02. Calling List Users API

To return all users of type `user` that have have the `reader` relationship with `document:planning`:

The result `user:anne` and `user:beth` are the `user` objects that have the `reader` relationship with `document:planning`.

> [!WARNING]
>
> **Warning**
>
> The performance characteristics of the List Users endpoint vary drastically depending on the model complexity, number of tuples, and the relations it needs to evaluate. Relations with 'and' or 'but not' are particularly expensive to evaluate.

## Usersets

In the above example, only specific subjects of the `user` type were returned. However, groups of users, known as [usersets](https://docs.fga.dev/modeling/concepts/usersets.md), can also be returned from the List Users API. This is done by specifying a `relation` field in the `user_filters` request object. Usersets will only expand to the underlying subjects if that `type` is specified as the user filter object.

Below is an example where usersets can be returned:

FGA model · DSL

With the tuples:

| user | relation | object |
| - | - | - |
| group:engineering#member | viewer | document:1 |
| group:product#member | viewer | document:1 |
| user:will | member | group:engineering |

Then calling the List Users API for `document:1` with relation `viewer` of type `group#member` will yield the below response. Note that the `user:will` is not returned, despite being a member of `group:engineering#member` because the `user_filters` does not target the `user` type.

## Type-bound public access

The List Users API supports tuples expressing public access via the wildcard syntax (e.g. `user:*`). Wildcard tuples that satisfy the query criteria will be returned with the `wildcard` root object property that will specify the type. A typed-bound public access result indicates that the object has a public relation but it doesn't necessarily indicate that all users of that type have that relation, it is possible that exclusions via the `but not` syntax exists. The API will not expand wildcard results further to any ID'd user object. Further, specific users that have been granted access will be returned in addition to any public access for that user's type.

> [!WARNING]
>
> A List Users response with a type-bound public access result (e.g. `user:*`) doesn't necessarily indicate that all users of that type have access, it is possible that exclusions exist. It is recommended to [perform a Check](https://docs.fga.dev/integration/perform-check.md) on specific users to ensure they have access to the target object.

Example response with type-bound public access:

```json theme={null}
{
  "users": [
    {
      "wildcard": {
        "type": "user"
      }
    },
    {
      "object": {
        "type": "user",
        "id": "anne"
      }
    }
  ]
}
```

## Related Sections

Take a look at the following section for more on how to perform list users in your system

[Auth0 FGA List Users API
Read the List Users API documentation and see how it works.](https://docs.fga.dev/api/service/relationship-queries/list-users.md)
