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

# Users

## Worked users samples

The endpoint list below documents every operation's parameters; this
overlay walks the authenticated user's presence the way an inbound-routing
integration actually uses it: **set presence → refine DND behaviour → set
the recurring DND schedule → handle an invalid-status 422**. Success
envelopes are `{ data, meta }`, error envelopes `{ error, meta }` — see
[How to read a worked sample](/guides/using-orbit-samples). Both routes
require the caller's own authenticated user — there is no admin override
on `PATCH /users/me/*`, and the change invalidates the inbound-routing
DND cache immediately.

Every response carries `meta.request_id`. Quote the request id when you
report a presence flip that did not fire the realtime event — support
pairs the request id with the `user.presence.changed` publish.

### 1. Set your presence

`PATCH /api/v1/users/me/presence` sets the authenticated user's presence.
`status` is required and one of `available`, `busy`, `away`, `dnd`;
optional refinements: `dnd_until` (ISO 8601, only honoured with
`status=dnd` and must be in the future), `status_message` (up to 200
chars, persists across status changes until cleared), and `activity`
(`in_a_call` or `in_a_meeting`, only meaningful with `status=busy`). The
call is idempotent, publishes a `user.presence.changed` realtime event
on the tenant channel, and invalidates the inbound-routing DND cache
immediately.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://api.orbit.devotel.io/api/v1/users/me/presence" \
    -H "X-API-Key: dv_test_sk_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "status": "busy",
    "activity": "in_a_call",
    "status_message": "On a call until 3pm",
    "dnd_until": "2026-08-26T15:00:00.000Z"
  }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/users/me/presence",
    {
      method: "PATCH",
      headers: {
        "X-API-Key": process.env.ORBIT_API_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        status: "busy",
        activity: "in_a_call",
        status_message: "On a call until 3pm",
        dnd_until: "2026-08-26T15:00:00.000Z",
      }),
    },
  );
  console.log(await res.json());
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "presence": {
      "status": "busy",
      "activity": "in_a_call",
      "status_message": "On a call until 3pm",
      "dnd_until": "2026-08-26T15:00:00.000Z"
    }
  },
  "meta": {
    "request_id": "req_usr_presence",
    "timestamp": "2026-08-26T12:00:00.000Z"
  }
}
```

### 2. Set the recurring DND schedule

`PATCH /api/v1/users/me/presence/schedule` sets the recurring weekly
do-not-disturb / business-hours envelope. Fields: `enabled` (boolean —
send `{"enabled": false}` to turn the schedule off), `timezone` (IANA
name, e.g. `"Europe/Paris"`), `daysOfWeek` (0–6, Sunday is 0),
`startMinute` (0–1439, minutes since 00:00 local), and `endMinute`
(0–1440; 1440 is the end-of-day sentinel). A 60-second worker tick
auto-flips presence between `available` (inside the window) and `dnd`
(outside it); an active manual time-bounded DND always wins over the
schedule. Days are deduplicated and sorted before persistence, so
re-sending the same envelope is idempotent.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH \
    "https://api.orbit.devotel.io/api/v1/users/me/presence/schedule" \
    -H "X-API-Key: dv_test_sk_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "enabled": true,
    "timezone": "Europe/Paris",
    "daysOfWeek": [1, 2, 3, 4, 5],
    "startMinute": 1080,
    "endMinute": 480
  }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/users/me/presence/schedule",
    {
      method: "PATCH",
      headers: {
        "X-API-Key": process.env.ORBIT_API_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        enabled: true,
        timezone: "Europe/Paris",
        daysOfWeek: [1, 2, 3, 4, 5],
        startMinute: 1080,
        endMinute: 480,
      }),
    },
  );
  console.log(await res.json());
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "schedule": {
      "enabled": true,
      "timezone": "Europe/Paris",
      "daysOfWeek": [1, 2, 3, 4, 5],
      "startMinute": 1080,
      "endMinute": 480
    }
  },
  "meta": {
    "request_id": "req_usr_schedule",
    "timestamp": "2026-08-26T12:01:00.000Z"
  }
}
```

### 3. Errors

Errors follow the `{ error, meta }` envelope. The failure every client
hits:

**422 — invalid status or schedule.** A `status` not in the enum, a
`dnd_until` that is in the past, or `endMinute` below `startMinute`:

```json 422 theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "`status` must be one of: available, busy, away, dnd.",
    "status": 422
  },
  "meta": {
    "request_id": "req_usr_err",
    "timestamp": "2026-08-26T12:02:00.000Z"
  }
}
```
