# Set a Genie access grant

> Gives a user or a group a role on a Genie (operator uses it, editor changes it, owner manages its access), changes it, or removes it (role null). Who may change access is decided per genie, as in the web app: an owner of the genie, or a workspace admin adding an owner. A genie always keeps one owner.

Source: https://docs.stacksync.com/api-reference/genies/access-grants/set_genie_access_grant

`POST https://api.stacksync.com/v1/workspaces/{workspace_id}/genies/{genie_id}/access-grants`

- Operation: `set_genie_access_grant`
- Resource: Genie access grants
- Access: writes data

## Authentication

- `Authorization: Bearer <key>`: A workspace API key (workspace_…, created by a workspace owner under Workspace settings > Stacksync API) acts with editor rights on that workspace only; a user API key (user_…, created under Profile > Stacksync API) acts as that user in every workspace they belong to. POST, PUT and PATCH requests must send Content-Type: application/json. Every authentication failure answers 403.
- `Content-Type: application/json` on every request with a body.

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | integer | Yes | The workspace. List the ones your key can reach with GET /v1/workspaces. |
| `genie_id` | string (uuid) | Yes | The Genie. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `region` | string (besg \| usnv) | Yes | Region of the genie: besg (Europe) or usnv (United States) |

## Request body

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `principal` | object (GenieAccessPrincipal) | Yes |  |
| `principal.type` | string (user \| group) | Yes |  |
| `principal.id` | string, 1 to 64 characters | Yes | The user id or the group id |
| `role` | string (operator \| editor \| owner) \| null | Yes | The role to give; null removes the principal |
| `validate_only` | boolean, default false | No | Run every check of the write and answer 204 without writing: a refused write answers the error the write would |

## Returns

### 200 OK

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `genie_id` | string | Yes |  |
| `principal` | object (GenieAccessPrincipal) | Yes |  |
| `principal.type` | string (user \| group) | Yes |  |
| `principal.id` | string, 1 to 64 characters | Yes | The user id or the group id |
| `role` | string (operator \| editor \| owner) \| null | Yes |  |

### 204 No Content

No body.

## Example request

```bash
curl -X POST "https://api.stacksync.com/v1/workspaces/{workspace_id}/genies/{genie_id}/access-grants?region=besg" \
  -H "Authorization: Bearer $STACKSYNC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "principal": {
    "type": "user",
    "id": "<id>"
  },
  "role": "operator"
}'
```

## Example response (200)

```json
{
  "genie_id": "<genie_id>",
  "principal": {
    "type": "user",
    "id": "<id>"
  },
  "role": "operator"
}
```

## Errors

| Status | Meaning | Body |
| --- | --- | --- |
| 400 | Bad Request | `{ "error": string, "msg": string, "field": string \| null }` |
| 403 | Forbidden | `{ "error": string, "msg": string, "field": string \| null }` |
| 404 | Not Found | `{ "error": string, "msg": string, "field": string \| null }` |
| 409 | Conflict | `{ "error": string, "msg": string, "field": string \| null }` |

## Related

- [API Reference overview](https://docs.stacksync.com/api-reference): base URLs, regions, pagination, idempotency and errors
- [Authentication](https://docs.stacksync.com/api-reference/authentication): API keys and the 403 answers
- OpenAPI document: https://docs.stacksync.com/openapi.json
- [List Genie access grants](https://docs.stacksync.com/api-reference/genies/access-grants/list_genie_access_grants)