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

# Access rules

> Schedule a start and an end, cap the number of scans, require a password, and pause, reactivate or delete a QR code.

> [!NOTE]
>
> The GetQR API is in beta and is available to selected workspaces. Details may change before the general release.

Control when a QR code resolves, how many times it can be scanned, whether it asks for a password, and whether it is paused or deleted.

## Before you start

* **Role.** Setting rules, pausing, reactivating and deleting need write access to QR codes in the workspace. See [Authentication](https://docs.getqr.com/api/authentication.md).
* **Subscription.** Every API request needs an active subscription of the workspace owner, including these.

## The access object

Send an `access` object when you [create](https://docs.getqr.com/api/endpoints/qr-codes.md#create-a-qr-code) or [update](https://docs.getqr.com/api/endpoints/qr-codes.md#update-a-qr-code) a QR code:

```text theme={null}
POST  /api/v1/qrs
PATCH /api/v1/qrs/{qrId}
```

| Field | Type | Description |
| - | - | - |
| `activeAt` | string (ISO 8601) \| null | Scheduled start. Before this moment, scans show the paused page instead of the destination. `null` means active immediately. |
| `pauseAt` | string (ISO 8601) \| null | Scheduled end. At and after this moment, scans show the paused page. `null` means no end date. |
| `scanLimit` | integer \| null | Maximum number of scans over the QR code's lifetime. Once exceeded, scans show the paused page. `null` means unlimited. |
| `password` | string \| null | Password visitors must enter before being redirected. Sending it also turns protection on. |
| `passwordProtected` | boolean | Whether the QR code asks for a password. `false` switches protection off but keeps the stored password. `true` turns it back on. |

Fields you omit stay unchanged. Send `null` to clear a rule. A partial `access` object never resets rules you didn't mention.

> [!WARNING]
>
> Access rules belong under `access`. Sending `activeAt`, `pauseAt`, `scanLimit`, `password` or `passwordProtected` under `link` gets `422`.

## Schedule a start and an end

`activeAt` and `pauseAt` are independent: set either one or both. Both take ISO 8601 date-times, with `Z` or a UTC offset.

```bash theme={null}
curl -X PATCH "https://getqr.com/api/v1/qrs/qr_abc123" \
  -H "Authorization: Bearer $GETQR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "access": {
      "activeAt": "2026-08-01T09:00:00Z",
      "pauseAt": "2026-08-31T23:59:59Z"
    }
  }'
```

Send `null` to clear the schedule. This makes the QR code active immediately and removes the end date:

```json theme={null}
{
  "access": { "activeAt": null, "pauseAt": null }
}
```

## Scan limit

Cap the total number of scans. After that, the QR code stops resolving:

```json theme={null}
{
  "access": { "scanLimit": 500 }
}
```

The lifetime scan counter always runs, whether or not a limit is set. That makes changing the limit predictable:

* **Raising the limit** frees up exactly (new limit minus total scans) more scans.
* **Lowering the limit** below the current total blocks the QR code immediately.
* **Setting a limit later** counts the scans taken while no limit was set.

`scanLimit` must be a positive integer, up to 2147483647. Send `null` for unlimited.

## Password protection

Set a password through the same `access` object. The stored password is kept when you switch protection off, so you can turn it back on without sending it again.

**1. Set or change the password**

This also turns protection on.

```json theme={null}
{ "access": { "password": "hunter2" } }
```

**2. Turn protection off**

The stored password is kept.

```json theme={null}
{ "access": { "passwordProtected": false } }
```

**3. Turn protection back on**

No need to resend the password. This works only once a password has been set. Otherwise the request gets `422`.

```json theme={null}
{ "access": { "passwordProtected": true } }
```

* **On create.** Send `password` to turn protection on. `passwordProtected` on its own has no effect until a password exists.
* **Removing the password.** Send `"password": null`. Protection turns off too.
* **Reading.** Responses never return the password, only `access.passwordProtected`.

## Pause, reactivate and delete

Pausing and reactivating are separate endpoints rather than `access` fields, because they take effect at once instead of on a schedule.

| Method | Path | Description |
| - | - | - |
| `POST` | `/api/v1/qrs/{qrId}/pause` | [Pause the QR code now](https://docs.getqr.com/api/endpoints/qr-codes.md#pause-a-qr-code). Scans show the paused page until you reactivate it. |
| `POST` | `/api/v1/qrs/{qrId}/activate` | [Reactivate a paused QR code](https://docs.getqr.com/api/endpoints/qr-codes.md#reactivate-a-qr-code). Any schedule and scan limit still apply. |
| `DELETE` | `/api/v1/qrs/{qrId}` | [Delete the QR code](https://docs.getqr.com/api/endpoints/qr-codes.md#delete-a-qr-code) and its short link permanently. |

Pause and activate take no request body and return the updated [QR code](https://docs.getqr.com/api/endpoints/qr-codes.md#the-qr-code-object):

```bash theme={null}
curl -X POST "https://getqr.com/api/v1/qrs/qr_abc123/pause" \
  -H "Authorization: Bearer $GETQR_API_KEY"
```

```json theme={null}
{
  "id": "qr_abc123",
  "archived": true,
  "…": "…"
}
```

You can also set the paused state with `PUT /api/v1/qrs/{qrId}` and `{ "archived": true }`, or with `archived` in a `PATCH`. See [Set the paused state](https://docs.getqr.com/api/endpoints/qr-codes.md#set-the-paused-state).

Deleting removes the QR code and its short link together:

```json theme={null}
{ "id": "qr_abc123", "deleted": true }
```

> [!WARNING]
>
> Deleting can't be undone. The short link stops resolving, so printed codes stop working. Pause the QR code instead if you may need it again.

## When changes take effect

* **Next scan.** Rules are checked when a code is scanned, so a change applies from the next scan, not retroactively.
* **Paused page.** A QR code blocked by a schedule, a scan limit or a pause shows the paused page. The scan isn't redirected.
* **Password.** Visitors who already entered the password keep access until the password changes, or until protection is switched off and on again.
* **Clock.** Schedules use the server clock in UTC, not the visitor's local time.
* **Rules combine.** A QR code resolves only when it isn't paused, is within its schedule and is under its scan limit.

## Common issues

> [accordion] 422 when setting a rule under link
>
> Send the rule under `access`, not `link`.

> [accordion] 422 when turning password protection on
>
> The QR code has no password yet. Send `password` instead of `passwordProtected: true`.

> [accordion] The QR code still shows the paused page after reactivating
>
> A schedule or scan limit still applies. Check `access.activeAt`, `access.pauseAt` and `access.scanLimit` in the [QR code](https://docs.getqr.com/api/endpoints/qr-codes.md#get-a-qr-code), and compare `scans` with the limit.

> [accordion] I need the link to expire
>
> `link.expiresAt` isn't available on this API. Use `access.pauseAt` instead.

## What's next

> [card] [QR codes](https://docs.getqr.com/api/endpoints/qr-codes.md)

> [card] [QR code data by type](https://docs.getqr.com/api/guides/qr-types.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.