# CLI scripts and errors

Source: https://blocklive.io/docs/developers/cli/scripts

Use the CLI from scripts: JSON output, errors, exit codes and rate limits.

## JSON output

Add `--json` to any command for one line of JSON on standard output instead
of text:

| Command       | JSON                                                     |
| ------------- | -------------------------------------------------------- |
| `events list` | `{ "events": [...], "more": false }`                     |
| `event show`  | The event, with `ticketTypes`, `orders` and `checkedIn`. |
| `guests list` | `{ "event": {...}, "guests": [...], "more": false }`     |
| `whoami`      | The sign-in: `person`, `scopes`, `actions`, `endsAt`.    |
| `logout`      | `{ "signedOut": true, "endedOnBlocklive": true }`        |
| `--version`   | `{ "version": "0.1.0" }`                                 |

`more` is `true` when there were more rows than one page; add `--all` to get
them all.

> **Note:** Run `blocklive login` without `--json`. With it, the code to type
> isn't printed.

### An event

```json
{
    "id": "6f1c…",
    "title": "Summer Opening",
    "slug": "summer-opening",
    "status": "active",
    "startsAt": 1794682800000,
    "endsAt": 1794711600000,
    "timeZone": "Europe/London",
    "location": "Riverside Hall",
    "team": { "id": "2b9d…", "name": "Night Market", "slug": "night-market" },
    "path": "/manage/night-market/event/summer-opening/overview",
    "role": "manager",
    "ticketTypes": [
        {
            "id": "a41e…",
            "title": "General admission",
            "price": 25,
            "supply": 400,
            "sold": 200
        }
    ],
    "orders": { "confirmed": 205, "pending": 3 },
    "checkedIn": 0
}
```

`startsAt` and `endsAt` are in milliseconds since 1970 (UTC). `path` is the
event's page in Blocklive's admin.

### A guest

```json
{
    "ticketId": "c7d2…",
    "orderId": "e90b…",
    "orderedAt": "2026-11-02T10:15:00+00:00",
    "buyer": "Sam Lee",
    "email": "sam@…",
    "ticketType": "General admission",
    "orderState": "confirmed",
    "checkin": "not_checked_in"
}
```

`checkin` is `checked_in`, `not_checked_in`, `not_issued` or `unknown`.

## Examples

Every guest's email, one per line:

```sh
blocklive guests list summer-opening --all --json | jq -r '.guests[].email'
```

Guests as a CSV file:

```sh
blocklive guests list summer-opening --all --json \
  | jq -r '.guests[] | [.buyer, .email, .ticketType, .orderState, .checkin] | @csv' \
  > guests.csv
```

How many are checked in:

```sh
blocklive event show summer-opening --json | jq '.checkedIn'
```

Stop a script when the sign-in has ended:

```sh
blocklive whoami --json > /dev/null || { echo "Run: blocklive login"; exit 1; }
```

## Errors

In text, an error is one line on standard error, with the request's ID when
Blocklive answered. With `--json` it is one line on standard output:

```json
{
    "error": {
        "message": "Your sign-in ended. Run `blocklive login`.",
        "code": "not_signed_in",
        "request_id": "6f9e…"
    }
}
```

Quote the `request_id` when you contact Blocklive.

| Code               | Meaning                                                      | What to do                      | Exit |
| ------------------ | ------------------------------------------------------------ | ------------------------------- | ---- |
| `not_signed_in`    | No sign-in on this profile, or it has ended.                 | Run `blocklive login`.          | 3    |
| `forbidden`        | Your role doesn't allow it; the message says why.            | Ask for a role, or use another. | 3    |
| `access_denied`    | The login was refused on the approval page.                  | Run `blocklive login` again.    | 3    |
| `expired_token`    | The login code expired before it was approved.               | Run `blocklive login` again.    | 3    |
| `not_found`        | No such event, or you can't see it. These aren't told apart. | Check the slug and your role.   | 4    |
| `invalid_request`  | An option or argument is wrong.                              | Fix the command.                | 2    |
| `rate_limited`     | Still over the limit after waiting.                          | Wait a minute.                  | 5    |
| `upgrade_required` | This CLI is too old.                                         | Run the install command again.  | 1    |
| `unavailable`      | Blocklive couldn't answer just now.                          | Try again.                      | 1    |

## Requests a minute

A sign-in can make 300 requests a minute. Over that, the CLI prints
`Rate-limited: waiting 60 s…` on standard error and tries again, up to five
times, before it stops with `rate_limited`.

## Exit codes

Scripts can branch on the exit code; a code never changes meaning.

| Code | Meaning                                                  |
| ---- | -------------------------------------------------------- |
| 0    | Done.                                                    |
| 1    | Something went wrong; the message says what.             |
| 2    | The command or an option is wrong.                       |
| 3    | Not signed in, or not allowed.                           |
| 4    | Not found.                                               |
| 5    | Still rate limited after retrying.                       |
| 6    | The same change was already sent with different details. |
| 7    | Some rows of a file were refused.                        |

Codes 6 and 7 are kept for commands that change things, which the CLI doesn't
have yet.
