# Grant a Guest Badge

`POST /guest.badge.create`

## Description

Grant a Guest Badge so an email that is **not** a workspace member can
visit a host in Roam.

This is **not** an [On-Air event guest](/docs/onair-api/on-air-api). It is
also **not** implied by [`group.add`](/docs/api/group-add): adding an email
to a group does not mint a badge or send the invite. Typical onboarding is
`guest.badge.create` then `group.add`.

Repeating create for the same host and email returns the existing badge
(`visitPermission` is **not** updated) and does not re-send the invite.

**Access:** Organization and Personal.
Organization tokens require `hostUserId`. Personal tokens default to the
token owner; naming a different host returns `403` `access_mode_not_supported`.

**Required scope:** `guest:write`. Personal Access Tokens use the
`pat:guests:write` group.

See [Guest Badges](/docs/guides/guest-badges).

---

**OpenAPI Spec:** [chat-v1.json](https://developer.ro.am/chat-v1.json)

## Authentication

```
Authorization: Bearer YOUR_API_KEY
```

## Request Body

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `email` | string | Yes | Guest email. ASCII only. Must not be a workspace member. |
| `hostUserId` | string | No | Host member. UUID or member email — the same convention as [`group.create`](/docs/api/group-create) `members[].userId`. Required for organization tokens. Optional for personal tokens (defaults to the  |
| `visitPermission` | boolean | No | Whether the guest may visit the host on the map. Defaults to `true`. Ignored on an idempotent retry of an existing grant.  |

## Responses

### 200 - Badge created, or the existing grant returned.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `email` | string | Yes | The guest's email address (lowercase). |
| `userId` | string | No | The guest's chat address ID, when one has been provisioned. Omitted if the address is not yet available.  |
| `hostUserId` | string | Yes | The host member's user ID (always a UUID, even if you passed an email). |
| `visitPermission` | boolean | Yes | Whether the guest may visit the host on the map. |
| `acknowledged` | boolean | Yes | Whether the guest has acknowledged the badge. |


#### Example Response

```json
{
  "email": "alex@client.example",
  "userId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "hostUserId": "3f1c0b2a-8d4e-4c91-9a7b-2e6f1d8c0a11",
  "visitPermission": true,
  "acknowledged": false
}
```

### 400 - Error response. `ok` is always false; branch on the machine-readable `error` code. See the Responses and Errors guide.

### 401 - Error response. `ok` is always false; branch on the machine-readable `error` code. See the Responses and Errors guide.

### 403 - `missing_scope`, `access_mode_not_supported` (personal token named
another host), or `guest_badge_forbidden` (this host is not allowed to
grant Guest Badges).


### 404 - Host not found (`user_not_found`).

### 405 - Error response. `ok` is always false; branch on the machine-readable `error` code. See the Responses and Errors guide.

### 500 - Error response. `ok` is always false; branch on the machine-readable `error` code. See the Responses and Errors guide.

---

*Machine-readable API documentation.*
*Full documentation: https://developer.ro.am/docs/api/guest-badge-create*
