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

# Chevre REST API Endpoints — Users and Member Management

> List workspace members, send invitations, update member roles, and remove members using the Chevre REST API. All requests require a Bearer token.

Member and invitation endpoints let you query who has access to your workspaces and control team membership programmatically. Members are users who have accepted an invitation and joined the workspace. Invitations represent pending access grants that have not yet been accepted. All requests require your API key in the `Authorization` header as `Bearer <your_api_key>`.

***

## List workspace members

**`GET`** **`https://api.chevre.io/v1/workspaces/{workspace_id}/members`**

Returns an array of all active members in the specified workspace. Pending invitations that have not yet been accepted are not included — use the [List invitations](#list-invitations) endpoint for those.

### Path parameters

<ParamField path="workspace_id" type="string" required>
  The unique identifier of the workspace whose members you want to list (e.g. `ws_01HXYZ`).
</ParamField>

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members" \
    --header "Authorization: Bearer <your_api_key>" \
    --header "Accept: application/json"
  ```

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

  response = requests.get(
      "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members",
      headers={"Authorization": "Bearer <your_api_key>"},
  )
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members",
    {
      headers: {
        Authorization: "Bearer <your_api_key>",
        Accept: "application/json",
      },
    }
  );
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

### Example response

```json 200 theme={null}
{
  "data": [
    {
      "id": "mem_01PQR",
      "email": "alice@acme.com",
      "name": "Alice Johnson",
      "role": "admin",
      "status": "active",
      "joined_at": "2024-01-20T11:00:00Z"
    },
    {
      "id": "mem_02STU",
      "email": "bob@acme.com",
      "name": "Bob Smith",
      "role": "editor",
      "status": "active",
      "joined_at": "2024-03-05T08:30:00Z"
    }
  ]
}
```

### Response fields

<ResponseField name="data" type="array">
  An array of member objects for the workspace.

  <Expandable title="member object">
    <ResponseField name="id" type="string">
      The unique identifier for the workspace membership, prefixed with `mem_`.
    </ResponseField>

    <ResponseField name="email" type="string">
      The email address of the member.
    </ResponseField>

    <ResponseField name="name" type="string">
      The full display name of the member.
    </ResponseField>

    <ResponseField name="role" type="string">
      The member's role in the workspace. One of `"owner"`, `"admin"`, `"editor"`, or `"viewer"`.
    </ResponseField>

    <ResponseField name="status" type="string">
      The membership status. Active members have the value `"active"`.
    </ResponseField>

    <ResponseField name="joined_at" type="string">
      ISO 8601 timestamp of when the member accepted their invitation and joined the workspace.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Invite a user

**`POST`** **`https://api.chevre.io/v1/workspaces/{workspace_id}/invitations`**

Sends an email invitation to the specified address, granting the recipient access to the workspace with the given role when they accept. If the email address already belongs to an active member of the workspace, the request returns a `409 Conflict` error.

<Note>
  Invitations expire after **7 days**. If the recipient does not accept within that window, you will need to send a new invitation. You can monitor invitation status using the `status` field on the invitation object.
</Note>

### Path parameters

<ParamField path="workspace_id" type="string" required>
  The unique identifier of the workspace to invite the user into (e.g. `ws_01HXYZ`).
</ParamField>

### Request body

<ParamField body="email" type="string" required>
  The email address of the person you want to invite. Must be a valid email format.
</ParamField>

<ParamField body="role" type="string" required>
  The role to assign to the user when they accept the invitation. Accepted values:

  * `"owner"` — full administrative control, including billing and workspace deletion.
  * `"admin"` — can manage members, projects, and all workspace settings.
  * `"editor"` — can create and edit projects and automations, but cannot manage members.
  * `"viewer"` — read-only access to all shared projects in the workspace.
</ParamField>

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url "https://api.chevre.io/v1/workspaces/ws_01HXYZ/invitations" \
    --header "Authorization: Bearer <your_api_key>" \
    --header "Content-Type: application/json" \
    --data '{
      "email": "carol@acme.com",
      "role": "editor"
    }'
  ```

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

  response = requests.post(
      "https://api.chevre.io/v1/workspaces/ws_01HXYZ/invitations",
      json={"email": "carol@acme.com", "role": "editor"},
      headers={"Authorization": "Bearer <your_api_key>"},
  )
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.chevre.io/v1/workspaces/ws_01HXYZ/invitations",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer <your_api_key>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        email: "carol@acme.com",
        role: "editor",
      }),
    }
  );
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

### Example response

```json 201 theme={null}
{
  "data": {
    "id": "inv_01VWX",
    "email": "carol@acme.com",
    "role": "editor",
    "status": "pending",
    "expires_at": "2024-06-08T14:22:00Z",
    "created_at": "2024-06-01T14:22:00Z"
  }
}
```

### Response fields

<ResponseField name="data" type="object">
  The newly created invitation object.

  <Expandable title="invitation object">
    <ResponseField name="id" type="string">
      The unique identifier for the invitation, prefixed with `inv_`.
    </ResponseField>

    <ResponseField name="email" type="string">
      The email address the invitation was sent to.
    </ResponseField>

    <ResponseField name="role" type="string">
      The role the invitee will receive upon accepting.
    </ResponseField>

    <ResponseField name="status" type="string">
      The current status of the invitation. Starts as `"pending"`. Changes to `"accepted"` when the recipient joins, or `"expired"` after the expiry window passes.
    </ResponseField>

    <ResponseField name="expires_at" type="string">
      ISO 8601 timestamp of when the invitation will expire if not accepted.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp of when the invitation was created.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Update a member's role

**`PATCH`** **`https://api.chevre.io/v1/workspaces/{workspace_id}/members/{member_id}`**

Updates the role of an existing workspace member. You must have `admin` or `owner` permissions in the workspace to update member roles. An owner cannot downgrade their own role — another owner must perform that action.

### Path parameters

<ParamField path="workspace_id" type="string" required>
  The unique identifier of the workspace (e.g. `ws_01HXYZ`).
</ParamField>

<ParamField path="member_id" type="string" required>
  The unique identifier of the member whose role you want to update (e.g. `mem_02STU`).
</ParamField>

### Request body

<ParamField body="role" type="string" required>
  The new role to assign to the member. Accepted values: `"owner"`, `"admin"`, `"editor"`, or `"viewer"`.
</ParamField>

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members/mem_02STU" \
    --header "Authorization: Bearer <your_api_key>" \
    --header "Content-Type: application/json" \
    --data '{
      "role": "admin"
    }'
  ```

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

  response = requests.patch(
      "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members/mem_02STU",
      json={"role": "admin"},
      headers={"Authorization": "Bearer <your_api_key>"},
  )
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members/mem_02STU",
    {
      method: "PATCH",
      headers: {
        Authorization: "Bearer <your_api_key>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ role: "admin" }),
    }
  );
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

### Example response

```json 200 theme={null}
{
  "data": {
    "id": "mem_02STU",
    "email": "bob@acme.com",
    "name": "Bob Smith",
    "role": "admin",
    "status": "active",
    "joined_at": "2024-03-05T08:30:00Z"
  }
}
```

### Response fields

<ResponseField name="data" type="object">
  The updated member object.

  <Expandable title="member object">
    <ResponseField name="id" type="string">
      The unique identifier for the workspace membership.
    </ResponseField>

    <ResponseField name="email" type="string">
      The email address of the member.
    </ResponseField>

    <ResponseField name="name" type="string">
      The full display name of the member.
    </ResponseField>

    <ResponseField name="role" type="string">
      The member's updated role in the workspace.
    </ResponseField>

    <ResponseField name="status" type="string">
      The membership status. Active members have the value `"active"`.
    </ResponseField>

    <ResponseField name="joined_at" type="string">
      ISO 8601 timestamp of when the member originally joined the workspace.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Remove a member

**`DELETE`** **`https://api.chevre.io/v1/workspaces/{workspace_id}/members/{member_id}`**

Removes a member from the workspace, immediately revoking their access to all projects and data within it. The removed member's account is not deleted — they simply lose access to this workspace.

<Warning>
  Removing a member immediately revokes their access. Any automations or tasks assigned to the removed member will remain but become unassigned. This action cannot be undone — you must send a new invitation if you want to restore their access.
</Warning>

### Path parameters

<ParamField path="workspace_id" type="string" required>
  The unique identifier of the workspace (e.g. `ws_01HXYZ`).
</ParamField>

<ParamField path="member_id" type="string" required>
  The unique identifier of the member to remove (e.g. `mem_02STU`).
</ParamField>

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request DELETE \
    --url "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members/mem_02STU" \
    --header "Authorization: Bearer <your_api_key>"
  ```

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

  response = requests.delete(
      "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members/mem_02STU",
      headers={"Authorization": "Bearer <your_api_key>"},
  )
  print(response.status_code)  # 204
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.chevre.io/v1/workspaces/ws_01HXYZ/members/mem_02STU",
    {
      method: "DELETE",
      headers: {
        Authorization: "Bearer <your_api_key>",
      },
    }
  );
  // Successful removal returns 204 No Content
  console.log(response.status); // 204
  ```
</CodeGroup>

### Example response

```json 204 theme={null}
// No content returned on successful removal
```

<Note>
  A successful removal returns HTTP `204 No Content` with an empty response body.
</Note>
