> This documentation belongs to Invofox, an AI-powered document processing
> platform. The API extracts structured data (fields) from unstructured
> documents (invoices, contracts, forms, bank statements, and more).
> Key concepts: Account, Environment, Document Type, Field, File, Import,
> and Document. When answering, prefer the exact terminology defined in the
> Glossary and cite the relevant API Reference endpoint when applicable.

# List users for an account.

GET https://api.invofox.com/users

Lists the users that have a role in an account, or in one of its environments.

**Permissions:** with `environment`, the caller needs the `envDev` role or higher on that environment.

- **API keys:** `environment` is required. An API key always acts as `envDev` on the environment it belongs to, so it can only list that environment. Without `environment` it gets `403`.
- **Dashboard users:** without `environment`, the caller needs `accountAdmin` on the account; otherwise the API answers `403`.

**Pagination:** results are paginated. If you don't send `limit`, only the first 50 users are returned. Use `count` to know the total and page with `skip` and `limit`. There is no maximum `limit`.

Filters are plain query parameters (`?environment=...&limit=100`), not a JSON `filter` object.

Reference: https://developers.invofox.com/api-reference/main-reference/users/list-users-for-an-account

## Authentication

- `x-api-key` header (required) — API Key authentication via header

## Request

### Query parameters

- `account` (string, optional) — Account to list users for. Defaults to the caller's account.
- `environment` (string, optional) — Only list users with access to this environment: users with a role on the environment, plus account admins. Required when calling with an API key, and it must be the environment the key belongs to.
- `role` (enum, optional) — Only list users with this role. Any other value answers `400`.
  - Allowed values: `accountAdmin`, `envAdmin`, `envDev`, `envUser`
- `sort` (string, optional) — Field to sort users by. Prefix with `-` for descending order (e.g., `-creation` for newest first). Without it, the order is not guaranteed.
- `skip` (integer, optional, default: 0) — **`(List pagination element)`** number of users to skip from the start of the list.
- `limit` (integer, optional, default: 50) — **`(List pagination element)`** number of users to return, starting at `skip`. Defaults to 50. There is no maximum. `0` or a non-numeric value returns an empty `result`.

## Response

### 200

A list of users. `count` is the total number of matching users, not the number returned in `result`.

- `count` (integer, optional)
- `result` (list of UserListItem, optional)

## Errors

### 403 Forbidden Error

The caller lacks the required role: `accountAdmin` without `environment` (never available to an API key), or `envDev` or higher on the environment with it.

- `any`

## Types

### UserListItem

A user as returned by `GET /users`, with their role rows in the requested scope.

- `_id` (string, optional)
- `account` (string, optional) — Account the user was created in. To know which accounts and environments the user can access, read `roles`.
- `creator` (string, optional)
- `name` (string, optional)
- `email` (string, optional)
- `lang` (string, optional)
- `creation` (string, optional)
- `verifiedAt` (string, optional) — First time the user logged in. Users who never logged in are not listed.
- `lastAccessAt` (string, optional) — Last time the user logged in. Missing if unknown.
- `remote` (boolean, optional)
- `roles` (list of UserRole, optional) — The user's role rows within the requested account (and environment, when `environment` is sent). Roles on other environments are not included.

### UserRole

- `_id` (string, optional)
- `user` (string, optional)
- `scope` (enum, optional) — `account` roles apply to every environment of the account. `environment` roles apply only to `environment`.
  - Allowed values: `account`, `environment`
- `account` (string, optional)
- `environment` (string, optional) — Only present when `scope` is `environment`.
- `role` (enum, optional)
  - Allowed values: `accountAdmin`, `envAdmin`, `envDev`, `envUser`
- `createdAt` (string, optional)
- `createdBy` (string, optional) — User who granted the role. Missing on older rows.

## Examples

**Response**

```json
{
  "count": 1,
  "result": [
    {
      "_id": "28b05b800123456789000000",
      "account": "28b05b800123456789000000",
      "creator": "28b05b800123456789000000",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "lang": "en",
      "creation": "2024-01-15T09:30:00Z",
      "verifiedAt": "2024-01-15T09:30:00Z",
      "lastAccessAt": "2024-01-15T09:30:00Z",
      "remote": true,
      "roles": [
        {
          "_id": "28b05b800123456789000000",
          "user": "28b05b800123456789000000",
          "scope": "account",
          "account": "28b05b800123456789000000",
          "environment": "000000000000000000000001",
          "role": "accountAdmin",
          "createdAt": "2024-01-15T09:30:00Z",
          "createdBy": "28b05b800123456789000000"
        }
      ]
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "https://api.invofox.com/users"

querystring = {"account":"28b05b800123456789000000","environment":"000000000000000000000001","limit":"50"}

headers = {"x-api-key": "<apiKey>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript
const url = 'https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50';
const options = {method: 'GET', headers: {'x-api-key': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

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

func main() {

	url := "https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50"

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

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

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

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

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50")

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

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

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50")
  .header("x-api-key", "<apiKey>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50', [
  'headers' => [
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50");
var request = new RestRequest(Method.GET);
request.AddHeader("x-api-key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["x-api-key": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.invofox.com/users?account=28b05b800123456789000000&environment=000000000000000000000001&limit=50")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```