CR Bee Docs
Settings

Management API

Read and write your fleet, pricing, and settings over the REST API

The management API lets an integration change the same data the admin panel does — vehicles, categories, addons, coupons, locations, seasons, pricing, and tenant settings — without a browser session. It lives under /api/v1/manage and is the write half of the CR Bee REST API.

Typical uses: syncing a fleet from another system, bulk price updates at the start of a season, or scripting the setup of a new account.

Creating a read & write key

Every /manage endpoint — including the GETs — needs an API key created with write access. An ordinary key returns 403.

  1. Go to Settings > API Keys
  2. Click Create API Key
  3. Enter a Key name (e.g. "Fleet sync")
  4. Tick Read & write
  5. Click Generate Key and copy the key — it is shown only once

Keys with write access are marked Read & write in the key list.

A read & write key can change your fleet, your prices and your public settings, and it can delete records. It is not limited to a subset of them. Only issue one to an integration you control, keep it out of browser code, and revoke it the moment it is no longer needed.

Making a request

Base URL:

https://your-slug.crbeeapp.com/api/v1

Custom domains work too: https://your-domain.com/api/v1.

Send the key as a bearer token and JSON as the body:

Authorization: Bearer crb_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
Content-Type: application/json

Every successful response wraps its payload in a data key:

RequestResponse body
GET /manage/cars{ "data": [ { ...car }, ... ] }
GET /manage/cars/{id}{ "data": { ...car } }
POST /manage/cars{ "data": { "id": "car_..." } } (status 201)
PUT /manage/cars/{id}{ "data": { "id": "car_..." } }
DELETE /manage/cars/{id}{ "data": { "id": "car_..." } }

A create or replace returns only the ID. Read the record back if you need the stored row.

Resources

The same five operations — list, create, read, replace, delete — exist for each of these, at /manage/{resource}:

ResourcePath
Vehicles/manage/cars
Categories/manage/categories
Feature labels/manage/features
Addons/manage/addons
Coupons/manage/coupons
Locations/manage/locations
Seasons/manage/seasons
Duration tiers/manage/duration-tiers
Price groups/manage/price-groups
Pricing adjustments/manage/pricing-adjustments
Availability blocks/manage/availability-blocks
Price group mappings/manage/price-group-maps

Price group mappings have no replace operation — PUT /manage/price-group-maps/{id} answers 405. Delete the mapping and create the replacement.

Updates are PUT, and a PUT sends the complete record. The body is validated by the same schema as POST, so a field you leave out is written with that field's default rather than keeping the value already stored. The working pattern is: GET the record, change what you need in the object you got back, PUT the whole thing.

Operations that are not plain CRUD

OperationEndpoint
Clone a vehiclePOST /manage/cars/{id}/clone
Duplicate a season with its pricesPOST /manage/seasons/{id}/duplicate
Read tenant settingsGET /manage/settings
Replace tenant settingsPUT /manage/settings
Reorder addons or locationsPUT /manage/sort-order
Read / replace one-way feesGET / PUT /manage/location-fees
Read / save pricing rulesGET / PUT /manage/pricing-rules
Copy prices between seasonsPOST /manage/pricing-rules/copy-season

PUT /manage/location-fees and PUT /manage/pricing-rules take a batch and apply it in one transaction. These two are the exception to the replace rule: entries you do not send are left alone, and a null price (pricePerDay for rules, feeValue for fees) deletes that entry.

PUT /manage/settings follows the same contract as the resource PUTs — it writes the whole settings object, so start from GET /manage/settings. It also accepts two optional fields that are not stored, labels_locale and trust_locale, naming which locale the labels and the trust banners/messages in the request belong to. Both default to the tenant's default locale.

Errors

Errors are JSON with an error string, and details on a validation failure:

{
  "error": "Validation error",
  "details": {
    "slug": ["Slug must be lowercase alphanumeric with hyphens"]
  }
}
StatusMeaning
400The body failed validation, or a referenced record does not exist
401The API key is missing, malformed, expired, or wrong
403The key is valid but was not created with read & write access
404Unknown resource name, or no such record for this tenant
405That resource has no replace operation — only /manage/price-group-maps
409A conflict — a duplicate slug, name or coupon code; a block overlapping confirmed bookings; deleting the default price group
429Rate limited — see Retry-After
500The write failed. Nothing was saved

An ID belonging to another tenant answers 404, never 403.

Rate limits

Limits are per API key, in a one-minute window:

Limit
Reads (GET)60 requests/minute
Writes (POST, PUT, DELETE)30 requests/minute

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 also carries Retry-After in seconds. See Rate Limits.

Examples

Add a vehicle

curl -X POST https://your-slug.crbeeapp.com/api/v1/manage/cars \
  -H "Authorization: Bearer crb_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Toyota Yaris",
    "slug": "toyota-yaris",
    "categoryId": "cat_abc123",
    "description": "Compact, fuel-efficient hatchback",
    "quantity": 4,
    "transmission": "manual",
    "fuelType": "petrol",
    "seats": 5,
    "doors": 5,
    "status": "published"
  }'
{ "data": { "id": "car_xyz789" } }

The car is created as a draft unless you send "status": "published".

Change a price

Prices live in pricing rules, one per car (or category) × season × duration tier × price group. Save them in a batch:

curl -X PUT https://your-slug.crbeeapp.com/api/v1/manage/pricing-rules \
  -H "Authorization: Bearer crb_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {
        "scopeType": "car",
        "scopeId": "car_xyz789",
        "seasonId": "sea_summer",
        "tierId": "tier_3_6",
        "priceGroupId": "pg_default",
        "pricePerDay": 42.50
      }
    ]
  }'
{ "data": { "count": 1 } }

Set "pricePerDay": null on the same combination to remove that price. If any referenced season, tier, price group, car or category does not exist, the whole batch is rejected with 400.

Reorder addons

Send the IDs in the order you want them shown; the first gets position 0.

curl -X PUT https://your-slug.crbeeapp.com/api/v1/manage/sort-order \
  -H "Authorization: Bearer crb_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "resource": "addons",
    "orderedIds": ["addon_gps", "addon_childseat", "addon_extradriver"]
  }'
{ "data": { "count": 3 } }

resource accepts addons and locations. Everything else is ordered by its own sortOrder field, which you set on the record itself.

Full reference

Request and response schemas for every endpoint are in the API Reference and the interactive API Explorer, under the Management tag.

On this page