Authentication and scopes

How an API key is sent, what it covers, the scopes it carries and what the account's plan changes.

API documentationGuides · Authentication and scopes

Sending the key

Every call carries the account key in the Authorization header, with the Bearer scheme:

curl https://api.mabellenote.com/v1/me \
  -H "Authorization: Bearer mbn_live_..."

The key never goes in the URL or in the request body. Only GET /v1/health and GET /v1/openapi.json work without a key.

A key's lifecycle

  • Creation: in the app, Settings › Integration, API & webhooks, by an owner or an admin. Every new key is announced by email to the account's owners and admins.
  • Shown once: the full key only appears when it is created. It can never be retrieved afterwards, not even by support. The app only shows its visible prefix, such as mbn_live_AbC1, so you can recognize it.
  • Coverage: a key covers the whole account, that is all its locations, current and future.
  • Number: an account has at most 10 active keys.
  • Expiration: optional, chosen at creation (30 days, 90 days, one year or never). After that date, the API answers 401 api_key_expired.
  • Revocation: immediate and final. The next call receives 401 api_key_revoked.
  • Ownership: a key belongs to the account, not to the person who created it. It keeps working if that person leaves the account, and the owners are told.
SituationResponse
No Authorization header, or no Bearer scheme401 authentication_required
Unknown key, or a key that does not start with mbn_live_401 invalid_api_key
Revoked key401 api_key_revoked
Expired key401 api_key_expired

Scopes

A key carries the list of scopes chosen when it was created. The app offers templates: Read only (locations, reviews, statistics, private feedback), CRM (read access and customer base), Till (locations, contacts, visits and promo codes) or Custom. Scopes cannot be edited afterwards: to change them, create a new key, switch your integration to it, then revoke the old one.

An operation called without the scope it requires answers 403 insufficient_scope. The scope each operation requires is listed in the reference.

ScopeWhat it allowsOperations
account:readIdentify the account and the key behind the call. Always granted, whatever the key.GET /v1/me
establishments:readRead locations, their Google connection and their review counters.GET /v1/establishmentsGET /v1/establishments/{establishmentId}
reviews:readRead reviews, their published reply and their analysis.GET /v1/reviewsGET /v1/reviews/{reviewId}
stats:readRead review statistics per day or per month.GET /v1/establishments/{establishmentId}/stats
feedbacks:readRead private feedback left through your QR codes. Personal data.GET /v1/feedbacksGET /v1/feedbacks/{feedbackId}
contacts:readRead the customer base: contact details, consents and visits. Personal data.GET /v1/contactsGET /v1/contacts/{contactId}
contacts:writeCreate and update contacts, with their proof of consent.POST /v1/contactsPATCH /v1/contacts/{contactId}
visits:writeRecord a customer's visit to a location.POST /v1/visits
replies:writeSubmit a reply draft, to be reviewed in the app.PUT /v1/reviews/{reviewId}/reply-draft
replies:publishPublish a reply on Google, for locations that allowed it.POST /v1/reviews/{reviewId}/reply
promo_codes:redeemRedeem a promo code from a cash register.POST /v1/promo-codes/redeem
ai:generateRequest an AI-written reply draft, which uses credits.POST /v1/reviews/{reviewId}/reply-drafts
events:readRead the account's event log.GET /v1/eventsGET /v1/events/{eventId}
webhooks:manageManage webhook endpoints.GET /v1/webhook-endpointsPOST /v1/webhook-endpointsDELETE /v1/webhook-endpoints/{endpointId}POST /v1/webhook-endpoints/{endpointId}/test

The contacts:read scope gives access to personal data: your customers' contact details, consents and history. Only grant it to tools that need it.

Two scopes require more than a ticked box:

  • contacts:write: when the key is created, the owner or admin certifies that the customers sent by the tool have given their consent. The writes guide details the consent proof.
  • replies:publish: it only takes effect for locations that allowed publishing through the API in the app. See publishing on Google.

Plan and account state

  • Pro plan: the API is included in the Pro plan, and during the free trial. An account without an effective Pro plan receives 403 plan_upgrade_required. Its keys are kept and work again, unchanged, as soon as the account is back on Pro.
  • Read-only account: with an effective Pro plan, a read-only account keeps answering reads and sending its webhooks. Writes receive 403 tenant_read_only there. The account.readOnly field of GET /v1/me shows this state.

The API checks, in this order: the key, the plan, the account state for a write, the scope, then the rate limit.

Isolation between accounts

The account always comes from the key: no path or parameter names it. An identifier that belongs to another account answers 404 not_found, exactly like an identifier that does not exist.

Checking a key

GET /v1/me answers for any valid key, whatever its other scopes. It is the call to use to test a connection from your tool: it returns the account, the effective plan, and the key's name, prefix, scopes and expiration date.

Good practices

  • Create one key per integration, with a clear name: you will know which one to revoke.
  • Grant only the scopes you need.
  • Keep keys in a secrets manager or an environment variable, never in code.
  • To replace a key without downtime, create the new one, deploy it, then revoke the old one.

Updated on October 25, 2026