---
title: "Create an invite link"
description: "Create a single-use link that adds anyone who opens it to one app in this suite with exactly these roles, after signing in at the suite's address."
canonical: "https://grid82.com/docs/builder-api/invites/create"
updated: "2026-11-13"
---

# Create an invite link

`POST https://studio.grid82.app/v1/suites/{suiteId}/invites`

Create a single-use link that adds anyone who opens it to one app in this suite with exactly these roles, after signing in at the suite's address.

It works when the suite is invitation-only and can add a new person to the directory. It cannot set a password for an address already in the directory; that person needs their own link (`users.passwordLink`). Pass `maxUses` to allow multiple uses, or `null` for unlimited. The URL is returned once and never stored in clear; copy it now.

Requires the `members:write` scope. Operation `invites.create`. MCP tool `invites_create`. CLI: `grid82 invites create` (`npx grid82`).

## Path parameters

| Name      | Type   | Required | Description |
| --------- | ------ | -------- | ----------- |
| `suiteId` | string | yes      |             |

## Headers

| Name              | Type   | Required | Description                                                                                                                                                                                                                                                        |
| ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Idempotency-Key` | string | no       | Any unique string. Sending the same key with the same request again returns the first response (marked `Idempotency-Replayed: true`) instead of running it twice. Reusing it for a different request is refused with 409. Kept for 24 hours. Up to 255 characters. |

## Request body

| Field           | Type            | Required | Description                           |
| --------------- | --------------- | -------- | ------------------------------------- |
| `appId`         | string          | yes      | Up to 64 characters.                  |
| `roles`         | string\[]       | yes      |                                       |
| `label`         | string          | no       | Up to 60 characters.                  |
| `expiresInDays` | integer         | no       | Default `14`. At least 1. At most 90. |
| `maxUses`       | integer or null | no       |                                       |

**Authorizations**

- `Authorization` (bearer, in header, required)

## Response

**201**: Success

- `data` (`object`, required)
- `data.id` (`string`, required)
- `data.url` (`string`, required)
- `data.appId` (`string`, required)
- `data.roles` (`string[]`, required)
- `data.label` (`string,null`, required)
- `data.expiresAt` (`string`, required)
- `data.maxUses` (`number,null`, required)

```json
{
  "data": {
    "id": "<string>",
    "url": "<string>",
    "appId": "<string>",
    "roles": [
      "<string>"
    ],
    "label": null,
    "expiresAt": "<string>",
    "maxUses": null
  }
}
```

**4XX**: Refused

- `error` (`object`, required)
- `error.code` (`enum<string>`, required, one of: `not_found, forbidden, unauthenticated, validation_failed, conflict, rate_limited, payment_required, not_implemented, internal`)
- `error.message` (`string`, required)
- `error.details` (`Record<string, unknown>`)

```json
{
  "error": {
    "code": "not_found",
    "message": "<string>",
    "details": {}
  }
}
```

**Example request**

```bash
curl --request POST \
  --url 'https://studio.grid82.app/v1/suites/<suiteId>/invites' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "appId": "<string>",
  "roles": [
    "<string>"
  ]
}'
```
