# Get the Mac

> The Mac that sends for you: whether it is online, its setup checks, how many texts are waiting and today’s counts against the limits.

`GET /v1/device`

The Mac that sends for you: whether it is online, its setup checks, how many texts are waiting and today’s counts against the limits.

Needs a key with the `account:read` scope. [Keys and scopes](https://usebluebot.com/docs/concepts/api-keys)

## Example

```bash
curl "https://usebluebot.com/api/v1/device" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY"
```

```ts
import BlueBot from '@usebluebot/sdk';

const client = new BlueBot({ apiKey: process.env.BLUEBOT_API_KEY });

const device = await client.device.get();
console.log(device);
```

```python
import os
from bluebot import BlueBot

client = BlueBot(api_key=os.environ["BLUEBOT_API_KEY"])

device = client.device.get()
print(device)
```

## Response

`200`: The Mac.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string or null | Yes | Null until a Mac is connected. Starts with `dev_` |
| `object` | "device" | Yes |   |
| `status` | string | Yes | `online` (checked in within 2 minutes), `offline` or `never_connected`. One of `online`, `offline`, `never_connected` |
| `name` | string or null | Yes |   |
| `number` | string or null | Yes | The phone number Messages on the Mac sends from, when it can tell. |
| `app_version` | string or null | Yes |   |
| `macos_version` | string or null | Yes |   |
| `last_seen_at` | timestamp or null | Yes | The Mac’s last check-in. |
| `last_sync_at` | timestamp or null | Yes | The last time the Mac finished posting the texts it read from Messages. |
| `offline_since` | timestamp or null | Yes | When the Mac went quiet, while it is offline. |
| `paired_at` | timestamp or null | Yes | When this Mac was connected. |
| `checks` | object | Yes | The Mac’s setup checks: Messages signed in, Full Disk Access, Text Message Forwarding, staying awake, FileVault. |
| `checks.messages` | object | Yes |   |
| `checks.messages.state` | string | Yes | `ok`, `needs_you` (something on the Mac needs fixing) or `unknown`. One of `ok`, `needs_you`, `unknown` |
| `checks.messages.detail` | string or null | Yes | What the Mac saw, in words. |
| `checks.full_disk_access` | object | Yes |   |
| `checks.full_disk_access.state` | string | Yes | `ok`, `needs_you` (something on the Mac needs fixing) or `unknown`. One of `ok`, `needs_you`, `unknown` |
| `checks.full_disk_access.detail` | string or null | Yes | What the Mac saw, in words. |
| `checks.forwarding` | object | Yes |   |
| `checks.forwarding.state` | string | Yes | `ok`, `needs_you` (something on the Mac needs fixing) or `unknown`. One of `ok`, `needs_you`, `unknown` |
| `checks.forwarding.detail` | string or null | Yes | What the Mac saw, in words. |
| `checks.awake` | object | Yes |   |
| `checks.awake.state` | string | Yes | `ok`, `needs_you` (something on the Mac needs fixing) or `unknown`. One of `ok`, `needs_you`, `unknown` |
| `checks.awake.detail` | string or null | Yes | What the Mac saw, in words. |
| `checks.filevault` | object | Yes |   |
| `checks.filevault.state` | string | Yes | `ok`, `needs_you` (something on the Mac needs fixing) or `unknown`. One of `ok`, `needs_you`, `unknown` |
| `checks.filevault.detail` | string or null | Yes | What the Mac saw, in words. |
| `checks_ok` | boolean or null | Yes | True when no check needs you. |
| `transcription` | boolean | Yes | Whether voice memos are transcribed on this Mac. |
| `held_count` | integer | Yes | Queued texts that are waiting on a hold. |
| `queued_count` | integer | Yes | Every queued text. |
| `unconfirmed_count` | integer | Yes | Texts the Mac couldn’t confirm, waiting for you to settle them. |
| `paused_until` | timestamp or null | Yes | While you have sending paused, until when. |
| `today` | object | Yes | Today’s counts against the limits. |
| `today.sent` | integer | Yes | Texts the Mac took today, in your time zone. |
| `today.new_people` | integer | Yes | People texted for the first time today. |
| `today.new_people_limit` | integer | Yes | Your new-people-per-day setting. |
| `today.daily_limit` | integer | Yes | BlueBot’s ceiling on texts a day. |
| `today.resets_at` | timestamp | Yes | The next local midnight, when the counts start again. |

The answer, `200`:

```json
{
  "id": "dev_1Hq2LxW9cVbN3mKpRtYs0a",
  "object": "device",
  "status": "online",
  "name": "Dana’s MacBook Air",
  "number": "+15555550100",
  "app_version": "1.0.0",
  "macos_version": "15.1",
  "last_seen_at": "2026-11-13T19:41:00.000Z",
  "last_sync_at": "2026-11-13T19:41:00.000Z",
  "offline_since": null,
  "paired_at": "2026-11-01T15:00:00.000Z",
  "checks": {
    "messages": {
      "state": "ok",
      "detail": null
    },
    "full_disk_access": {
      "state": "ok",
      "detail": null
    },
    "forwarding": {
      "state": "ok",
      "detail": null
    },
    "awake": {
      "state": "ok",
      "detail": null
    },
    "filevault": {
      "state": "ok",
      "detail": null
    }
  },
  "checks_ok": true,
  "transcription": false,
  "held_count": 0,
  "queued_count": 0,
  "unconfirmed_count": 0,
  "paused_until": null,
  "today": {
    "sent": 14,
    "new_people": 3,
    "new_people_limit": 50,
    "daily_limit": 1000,
    "resets_at": "2026-11-14T05:00:00.000Z"
  }
}
```

## Errors

Every refusal has the same envelope and a page of its own. These are the ones this operation can give.

| Code                                                    | Status | What it means                                                                                                                               |
| ------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| [`unauthorized`](https://usebluebot.com/docs/errors/unauthorized)             | 401    | The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API.                           |
| [`insufficient_scope`](https://usebluebot.com/docs/errors/insufficient_scope) | 403    | The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope.                                              |
| [`rate_limited`](https://usebluebot.com/docs/errors/rate_limited)             | 429    | Too many requests. A key may make 120 requests a minute. The `RateLimit` header says how many are left, and `Retry-After` how long to wait. |
| [`internal`](https://usebluebot.com/docs/errors/internal)                     | 500    | Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe.               |

## Try it
