Authentication and keys
Every request carries an API key in the Authorization header, as a bearer token:
A missing, malformed, or revoked key, or a key whose broker was deactivated, all get the same answer. The message is identical on purpose, so someone guessing keys learns nothing from it.
Code
Create a key
An admin of the brokerage creates keys.
- In BrokerPlus, go to Settings > Developer.
- Select New key, name it after the integration that will use it, and pick any limits.
- Copy the key. BrokerPlus stores only a hash, so this is the one time you can see it.
A live key starts with bp_live_. A sandbox key starts with bp_test_. A brokerage
can have ten live keys at a time; revoke one to make an eleventh. If you lose a key, revoke it and
make a new one.
What a key can do
There are no scopes. A key acts as the broker who created it, on the team they were working in
when they created it. It sees what that broker sees and can change what that broker can change,
and nothing more. If the broker's access shrinks, so does the key's. Keys made by a view-only
member can read, and every write returns 403 VIEW_ONLY.
So protect a key the way you would protect that broker's password:
- Keep keys on a server. Never ship one in a browser bundle, a mobile app, or a public repository.
- Give each integration its own key, so you can revoke one without breaking the others.
- Revoke a key the moment you think it leaked. Revocation applies to the very next request.
GET /v1/me shows the brokerage, the broker, the team, and the limits of the key you are using.
Call it first when something does not behave the way you expect.
Limits on a key
A limit takes access away from a key. No limit adds access, so a limited key never does more than its broker. You choose limits when you create the key, and you cannot change them later: revoke the key and make another.
| Limit | What the key cannot do |
|---|---|
read_only | Anything but GET. |
leads_only | Anything outside the lead endpoints, GET /v1/me, and GET /v1/custom-fields. It also cannot convert a lead to a deal, or change the lead stages, lead channels, or referral partners. |
no_sending | Anything that puts something in front of a client: a message, a booking, a campaign, an intake email, an equity report, documents to sign. Without this limit, those requests go out at once. See Reaching clients. |
no_documents | Any document endpoint, and message attachments. |
Pick the smallest set that works:
| Integration | Limits |
|---|---|
| A website lead form | leads_only |
| A report, a dashboard, or a warehouse sync | read_only |
| An assistant that drafts work for the broker | no_sending |
| Anything that must not contact clients | no_sending |
| Anything that must not see client files | no_documents |
A request must pass every limit on the key. A refused request returns 403, with the limit in
details.limit:
Code
A read_only key gets READ_ONLY_KEY instead, without details. Limits also apply to
webhooks: a key cannot subscribe to events it could not read.
Connect an assistant without a key
Claude on the web, ChatGPT, and other apps that support MCP connectors don't need a key. They sign in to BrokerPlus with OAuth 2.1, and the broker picks the team and whether the app can only read. The connection then acts exactly like a key with the same team and read-only choice. It shows up with the keys in Settings > Developer, and revoking it there disconnects the app.
See Run an AI assistant for the steps.
Rate limit
Each key can make 600 requests a minute. Every response tells you where you stand:
| Header | Meaning |
|---|---|
RateLimit-Limit | Always 600. |
RateLimit-Remaining | Requests left in the current window. |
Retry-After | Seconds until the window resets. Sent only with a 429. |
Over the limit, the API returns 429 RATE_LIMITED. Wait Retry-After seconds and send the request
again.
The window is fixed, not rolling. It starts at your first request and resets 60 seconds later. Each item in a batch write counts as one request. If a sync keeps hitting the limit, read only what changed: see Staying in sync.