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

# Suggesting Changes

> How to propose a new record or a change through the BrikSync PropOS API — and why every suggestion waits for a person to approve it.

<Warning>
  **The API cannot change your data.** There is no endpoint that creates or updates a property, a
  unit, a tenant, a lease, a payment, or a maintenance request directly. The only thing an
  integration can do is **suggest** a change. A person at your organisation reviews and approves it
  inside BrikSync, and only that approval applies it. This applies to every integration and every AI
  assistant, with no exceptions.
</Warning>

***

## How it works

1. Your integration sends one or more suggested changes to `POST /api/v1/proposals`.
2. BrikSync records them as a batch, in the state `awaiting_human_approval`. **Nothing has changed yet.**
3. Someone at your organisation — a Property Manager, Landlord, Broker, or Admin, depending on the record — opens **API & Automation** in BrikSync, reviews the suggestion, and approves or dismisses it.
4. Only on approval is the change actually written, under that person's own account.

You can check on a suggestion's status afterwards with `GET /api/v1/proposals` — this can tell you whether it's still waiting, was applied, was dismissed, or expired unreviewed. It cannot approve anything.

***

## Making a suggestion

```
POST /api/v1/proposals
```

Requires the `:propose` scope for whatever you're suggesting a change to (for example, `leases:propose` to suggest a lease change). See [Authentication](/api/authentication) for the full scope list.

Every request needs an `Idempotency-Key` header — more on that below.

### Request body

| Field     | Required | Description                                                                                                                        |
| --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `label`   | No       | A short, plain-English name for this batch, shown to the person reviewing it. For example, `"Annual rent review for Maple Court"`. |
| `changes` | Yes      | An array of 1–200 individual changes.                                                                                              |

Each item in `changes`:

| Field          | Required            | Description                                                                                                    |
| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------- |
| `operation`    | Yes                 | `"create"` or `"update"`.                                                                                      |
| `resourceType` | Yes                 | What kind of record this is about: `property`, `unit`, `tenant`, `lease`, `payment`, or `maintenance_request`. |
| `resourceId`   | Only for `"update"` | The ID of the existing record. Omit when creating.                                                             |
| `fields`       | Yes                 | The suggested values, as an object. Unrecognised field names are rejected rather than silently ignored.        |

```bash theme={null}
curl -X POST https://briksync.com/api/v1/proposals \
  -H "Authorization: Bearer $BRIKSYNC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 2026-08-20-rent-review-maple-court" \
  -d '{
    "label": "Annual rent review for Maple Court",
    "changes": [
      {
        "operation": "update",
        "resourceType": "lease",
        "resourceId": "8f14e...uuid",
        "fields": { "monthly_rent": 1650 }
      }
    ]
  }'
```

### Response

```json theme={null}
{
  "data": {
    "batchId": "...",
    "status": "awaiting_human_approval",
    "message": "These changes have been recorded as suggestions. Nothing has been changed yet. Someone at this organisation must review and approve them in BrikSync before they take effect.",
    "reviewUrl": "https://briksync.com/api-access?batch=...",
    "proposals": [
      {
        "id": "...",
        "operation": "update",
        "resourceType": "lease",
        "summary": "...",
        "status": "proposed",
        "flags": [],
        "expiresAt": "..."
      }
    ]
  }
}
```

A `201` response means the suggestion was **recorded**, not applied — always read the `message` field back to your users or your logs, and never report a proposal as a completed change.

***

## Send related changes together

If several changes belong to the same decision — for example, updating three units' rent as part of one review — send them in a single `changes` array rather than as separate requests. A reviewer sees the whole batch as one thing to approve or dismiss, instead of individual items they'd have to piece back together themselves. Up to 200 changes are allowed per batch.

***

## The Idempotency-Key header

`POST /api/v1/proposals` is the one endpoint in this API that creates something, so it's the one place a network retry could otherwise create a duplicate. Every request must include:

```
Idempotency-Key: <a value unique to this specific request>
```

* **A new key** → the changes are recorded as normal.
* **The same key, sent again with the exact same request body** → you get back the original response. Nothing is recorded twice. This is what makes retries after a timeout safe.
* **The same key, sent again with a different request body** → the request is rejected with `idempotency_conflict` (HTTP 409). This usually means a bug on the calling side — generate a fresh key for a genuinely new request.

Use a value that's unique per distinct batch of changes — a UUID you generate client-side works well, as does a value derived from what you're proposing (like the example above).

***

## Checking on suggestions

```
GET /api/v1/proposals
```

Requires `proposals:read`. Supports `status` (`proposed`, `applied`, `dismissed`, or `expired`), `batchId`, and the same `cursor`/`limit` pagination as every other list endpoint (see [Reading Data](/api/reading-data)).

```bash theme={null}
curl "https://briksync.com/api/v1/proposals?status=proposed" \
  -H "Authorization: Bearer $BRIKSYNC_API_KEY"
```

A suggestion that sits unreviewed for too long moves to `expired` on its own — check back with `GET /api/v1/proposals` rather than assuming a suggestion is still pending indefinitely.

***

## Reviewing and approving suggestions

Approval happens inside BrikSync, not through the API. Go to **API & Automation** in the sidebar to see every suggestion awaiting a decision, who or what proposed it, and what specifically would change — then approve or dismiss it. Property Managers and above can review the queue; only Admins manage the API keys themselves.

***

## Next steps

<CardGroup cols={2}>
  <Card title="Connect an AI Assistant" icon="sparkles" href="/api/mcp">
    The same read-and-suggest model, available to Claude, ChatGPT, and other assistants.
  </Card>

  <Card title="Errors & Limits" icon="gauge" href="/api/errors-and-limits">
    What `idempotency_conflict` and every other error code means.
  </Card>
</CardGroup>
