# Set a user's Will Return / Out of Roam

`POST /user.status.set`

## Description

Record an absence on a workspace member — the same Will Return Today /
Out of Roam field the desktop client writes, already readable via
[`user.info?expand=status`](/docs/api/user-info) and
[`user.status.update`](/docs/webhooks/user-status-update).

This is **not** [external activity](/docs/guides/user-activity). Use
`user.status.set` for HR absences (sick leave, vacation, parental leave,
public holidays). Use `user.activity.set` for a short-lived on-map glow
/ emoji (phone call, browser meeting).

`willReturn` is last-writer-wins with the desktop client. Setting it
does **not** check the user out, does **not** enable Do Not Disturb, and
does **not** accept a `status` enum (`checkedIn` / `checkedOut` stay
read-only).

`outOfRoam` defaults to `true` (persistent Out of Roam, up to 2 years).
Pass `outOfRoam: false` for same-day Will Return Today (`returnTime`
must be less than 10 hours from now).

Identify the user with `userId`: a bare UUID, tagged `U-…` ID, or
ASCII email (same convention as `group.create` members). Third-party
systems that only have an email do not need a UUID lookup first.

See [Will Return / Out of Roam](/docs/guides/user-status) for the two
modes, persistence across check-in, and an HRIS example.

**Access:** Organization and Personal. Organization tokens may target
any active member in the workspace. Personal tokens (OAuth or PAT) may
target only the token owner.

**Required scope:** `user:write.status`. Personal Access Tokens skip
this check; personal-mode OAuth installs must still request the scope.
Reading the field back via `user.info` still needs `user:read.status`.

---

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

## Authentication

```
Authorization: Bearer YOUR_API_KEY
```

## Request Body

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `userId` | string | Yes | Target user. Bare UUID, tagged `U-…` ID, or ASCII email (same convention as `group.create` members). Personal tokens may only pass their own user. Does not require `user:read.email` — email is an iden |
| `willReturn` | object | Yes | Absence to write. Required. Replaces any existing Will Return / Out of Roam on this user.  |
| `status` | string | No | Rejected. Check-in status is read-only; absences go in `willReturn`. Sending this field returns `400` `invalid_arguments`.  |

**willReturn**:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `returnTime` | string | Yes | When the user is expected back (RFC3339). Must be in the future and at most 2 years from now. Will Return Today (`outOfRoam: false`) additionally requires less than 10 hours from now.  |
| `reason` | string | No | Optional absence message (for example "On vacation"). At most 128 Unicode code points.  |
| `outOfRoam` | boolean | No | `true` (default) is multi-day Out of Roam and persists across check-ins. `false` is same-day Will Return Today.  |

## Responses

### 200 - Absence saved. `willReturn` echoes the written value (including
defaulted `outOfRoam`). `status` is the user's current check-in
(`checkedIn` / `checkedOut`) and is unchanged by this call. `userId`
is the canonical UUID.


| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `userId` | string | Yes | Bare UUID of the target user. |
| `status` | "checkedIn" | "checkedOut" | No | Current check-in. Unchanged by this call. Omitted if the presence lookup fails.  |
| `willReturn` | WillReturn | Yes |  |

**WillReturn**:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `returnTime` | string | Yes | When the user is expected to return (RFC 3339). |
| `reason` | string | No | Optional absence message (for example "On Vacation" or "Out to lunch"). At most 128 Unicode code points.  |
| `outOfRoam` | boolean | No | When true, multi-day Out of Roam that persists across check-ins. When false or omitted on a **read**, same-day Will Return Today.  `user.status.set` defaults omitted `outOfRoam` to **true**. Will Retu |


#### Example Response

```json
{
  "userId": "0cc74785-e31e-4403-aa5e-0cc7c1897e66",
  "status": "checkedOut",
  "willReturn": {
    "returnTime": "2026-09-22T09:00:00Z",
    "reason": "On vacation",
    "outOfRoam": true
  }
}
```

### 400 - Bad request. Common causes:
- Missing `userId` or `willReturn` (`missing_parameter`)
- Missing `willReturn.returnTime` (`missing_parameter`)
- `status` sent (`invalid_arguments`)
- `userId` is not a UUID, tagged ID, or ASCII email
- `willReturn.returnTime` in the past, more than 2 years out, or
  ≥ 10 hours out with `outOfRoam: false` (`invalid_parameter`)
- `willReturn.reason` longer than 128 code points (`invalid_parameter`)


### 401 - Presented invalid authentication credentials.

### 403 - Forbidden. Common causes:
- Missing `user:write.status` (OAuth / API key)
- Personal token targeting a user other than the owner (`access_denied`)


### 404 - User not found, archived, or not in this workspace (`user_not_found`).


### 405 - An unsupported method was requested.

### 500 - An internal error occurred.

---

*Machine-readable API documentation.*
*Full documentation: https://developer.ro.am/docs/api/user-status-set*
