Authentication
Every request needs an API key. This page covers the two key types, scopes, regions, rate limits, and idempotency.
Two key types
ibakepro issues two kinds of API key.
- Name
Secret key- Type
- ibp_sk_...
- Description
Server-to-server. May hold any scope, including writes and back-office reads. Accepted by every endpoint.
- Name
Publishable key- Type
- ibp_pk_...
- Description
Browser-safe. Restricted at creation time to a fixed allowlist of catalog, reference, pricing and checkout scopes. Accepted only by the endpoints listed below; every other endpoint rejects it with
403 publishable_key_not_allowed.
A key is a single opaque string in the form
ibp_{type}_{env}_{region}_{secret}, where type is sk or pk, env is
live or test, region is au, us or eu, and secret is 43 base64url
characters. Keys issued today always carry live.
Keys created before the two-type split have no sk/pk segment (for example
ibp_live_au_<43 characters>). They are still accepted and are treated as secret keys.
Endpoints that accept a publishable key
- Name
GET /products, GET /products/{id}- Description
Requires
products:read.
- Name
POST /products/search-token- Description
Requires
products:search.
- Name
GET /availability- Description
Requires
reference:read.
- Name
GET /reference/*- Description
blocked-dates,custom-fields,event-categories,expense-categories,payment-methods,time-slots. Requiresreference:read.
- Name
POST /checkout- Description
Requires
checkout:write.
Orders, customers, expenses and webhooks are secret-key only.
CORS
The endpoints above are the only ones that return CORS headers. They do so on
every response, success and error alike, and they answer an OPTIONS preflight
with 204:
| Header | Value |
|---|---|
Access-Control-Allow-Origin | * |
Access-Control-Allow-Methods | GET, POST, OPTIONS |
Access-Control-Allow-Headers | Authorization, Content-Type, Idempotency-Key |
Access-Control-Max-Age | 86400 |
CORS is a property of the endpoint, not of the key. A secret key called against one of these endpoints gets the same headers.
Obtaining an API key
- Log in to your ibakepro dashboard
- Open Settings > Integrations
- In the Developers section, select Create API key
- Name the key and choose its type (secret or publishable)
- For a secret key, choose a permission group (see Scopes). A publishable key is always issued with the full commerce set
- Create the key and copy it
The key is shown once and cannot be retrieved later; if you lose it, create a
new one. The REST API requires the Business plan. On any other plan every /api/v2
request returns 403 with {"error": "plan_required", "feature": "rest-api", "required": "business"}.
Regional API endpoints
Each account lives in one region. Use the host that matches your account's region. The API key is region-scoped: a key minted for one region only works against that region's host.
- Name
us.api.ibakepro.com- Type
- North America
- Description
USA and Canada region endpoint.
- Name
au.api.ibakepro.com- Type
- Australia
- Description
Australia region endpoint.
- Name
eu.api.ibakepro.com- Type
- Europe
- Description
Europe region endpoint.
The full base URL for every endpoint is https://{region}.api.ibakepro.com/api/v2. The region is read from the host subdomain and compared against the region segment in your key. A mismatch returns 401 invalid_api_key, with no detail about which region the key belongs to.
/api/v1 has been removed. Every request under it returns 410 Gone with
code api_version_deprecated before any authentication runs.
Using your API key
Include your key in the Authorization header as a Bearer token:
Secret key (server-side)
curl https://au.api.ibakepro.com/api/v2/orders \
-H "Authorization: Bearer ibp_sk_live_au_ABC"
Publishable key (browser-safe)
curl https://au.api.ibakepro.com/api/v2/products \
-H "Authorization: Bearer ibp_pk_live_au_ABC"
A bare key with no Bearer prefix is also accepted, but prefer the Bearer form.
Scopes
Every key carries one or more scopes. Each endpoint declares the single scope it requires; a key without it gets 403 insufficient_scope, and the response includes a requiredScope field naming the missing scope.
Scopes backed by a live endpoint
These are the only scopes that can be selected when creating a key. Anything else would grant access to nothing.
- Name
orders:read- Description
GET /orders,GET /orders/{id}.
- Name
orders:write- Description
POST /orders, including any payments recorded as part of the create.
- Name
customers:read- Description
GET /customers,GET /customers/{id}.
- Name
customers:write- Description
POST /customers.
- Name
expenses:read- Description
GET /expenses,GET /expenses/{id}.
- Name
expenses:write- Description
POST /expenses.
- Name
products:read- Description
GET /products,GET /products/{id}.
- Name
products:search- Description
POST /products/search-token, which mints a short-lived, search-only token for the public product catalog.
- Name
reference:read- Description
GET /availabilityand everyGET /reference/*endpoint (payment methods, event categories, expense categories, time slots, blocked dates, custom fields).
- Name
checkout:write- Description
POST /checkout.
- Name
webhooks:manage- Description
Every
/webhooksendpoint: list, create, read, update, delete, rotate the signing secret, send a test event, and list delivery attempts.
Permission groups
Secret keys are created from a group rather than by picking scopes individually.
| Group | Scopes granted |
|---|---|
readOnly | orders:read, customers:read, expenses:read, reference:read |
orderManagement | orders:read, orders:write, customers:read, customers:write |
inventoryManagement | expenses:read, expenses:write |
fullAccess | Every scope in the table above |
commerce | The publishable set below |
Publishable-key scopes
A publishable key may only hold scopes from this allowlist, enforced both when the key is created and when it is edited.
- Name
products:read- Description
Read the product catalog.
- Name
products:search- Description
Mint short-lived, search-only tokens for the public product catalog.
- Name
reference:read- Description
Read reference data and availability.
- Name
pricing:read- Description
Reserved for live price quotes. No endpoint requires it yet, so it currently grants nothing.
- Name
checkout:write- Description
Create hosted checkout sessions.
Rate limiting
Limits are applied per API key.
- 300 read requests per 60 seconds (
GET), ruleapi-read - 100 write requests per 60 seconds (
POST,PUT,PATCH,DELETE), ruleapi-write - 120 requests per 60 seconds per client IP on the publishable-key endpoints, rule
api-public-ip, applied in addition to the per-key limit
Exceeding a limit returns 429 with these headers:
| Header | Description |
|---|---|
Retry-After | Seconds to wait before retrying (60 for all API rules) |
X-RateLimit-Limit | Configured limit for the bucket you hit |
X-RateLimit-Remaining | 0 |
X-RateLimit-Reset | Unix timestamp (seconds) when the bucket refills |
X-RateLimit-Rule | The rule that fired: api-read, api-write or api-public-ip |
Successful responses carry X-RateLimit-Limit only. There is no live remaining counter, so X-RateLimit-Remaining is not sent on a 200.
Wait for Retry-After before retrying.
Idempotency
These POST endpoints accept an Idempotency-Key header so a retried request is processed at most once:
POST /ordersPOST /customersPOST /expensesPOST /checkoutPOST /webhooks
curl -X POST https://au.api.ibakepro.com/api/v2/orders \
-H "Authorization: Bearer {secret_key}" \
-H "Idempotency-Key: 9c1a8f8e-2d34-4c4e-9a0e-f0e2a8c1b7f1" \
-H "Content-Type: application/json" \
-d '{ ... }'
How it works:
- The first request is processed normally. On success the status and body are stored for 24 hours, scoped to your account and to the specific route.
- A retry with the same key, same route and same body replays the stored response, with an
Idempotent-Replayed: trueheader. - A retry with the same key but a different body, or the same key against a different route, returns
422with codeidempotency_key_reused. Use a fresh key for a different operation. - A retry while the original request is still in flight returns
409with coderequest_in_flight. - If the original request failed, the key is released as soon as the failure is returned. The same key can be retried immediately and will be treated as a first attempt.
- A malformed key returns
400with codeinvalid_idempotency_key.
Keys must be 1 to 255 characters and contain only letters, digits, underscore, hyphen, colon and period.