Introduction

Blue's LTCR Workshop Booking API lets long-term-rental partner integrators — such as the team that operates bluecarrental.is — book workshop service appointments (tire change, oil and lube service, or other work) on behalf of the long-term-rental customers they serve, for the cars those customers are renting from Blue Car Rental. It replaces a previous manual booking workflow.

Base URLs

EnvironmentBase URL
Productionhttps://ltcr-workshop-booking-api.bluecarrental.is
Staginghttps://ltcr-workshop-booking-api.staging.bluecarrental.is

API version

This document covers v1. All paths are prefixed with /api/v1/workshop. All timestamps are RFC 3339 in UTC. Requests and responses are JSON.

Partners own the customer-facing UI. Blue Car Rental owns this API and its database. There is no partner-facing admin panel in v1.

Getting started

Four steps to your first booking:

  1. Request an API key from Blue Car Rental (see Authentication).
  2. Call GET /api/v1/workshop/locations to list active workshop locations.
  3. Call GET /api/v1/workshop/availability to retrieve bookable slots for the location and date range your customer is choosing from.
  4. Call POST /api/v1/workshop/bookings with the chosen slot and the customer's contact details. The response includes a tokenised cancel URL Blue Car Rental will email the customer.

End-to-end example

# 1. List locations
curl -s https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/locations \
  -H "X-API-Key: bws_a1b2c3d4_"

# 2. Check availability for Keflavík next week
curl -s "https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/availability?location=keflavik&from=2026-05-19&to=2026-05-23" \
  -H "X-API-Key: bws_a1b2c3d4_"

# 3. Book the 09:00 slot on 2026-05-19
curl -s -X POST https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/bookings \
  -H "X-API-Key: bws_a1b2c3d4_" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9b1c-7e2f-2026-05-19-keflavik-AB123" \
  -d '{
    "location": "keflavik",
    "slot_start_at": "2026-05-19T09:00:00Z",
    "service_type": "dekkjaskipti",
    "customer": {"name": "Kalli Bimbo", "email": "kalli@example.is", "phone": "+3546901588"},
    "license_plate": "AB123"
  }'

Authentication

Every request must include an API key in the X-API-Key header. Keys are issued by Blue Car Rental — there is no self-service signup.

Header

X-API-Key: bws_a1b2c3d4_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0

Key format

An API key is three underscore-separated parts: a fixed scheme tag, a public prefix, and a secret.

PartExampleNotes
bwsbwsScheme tag. Always bws.
Prefixa1b2c3d48 hex characters. Identifies your partner record. Safe to log.
Secrete5f6…b032 hex characters. Never log, never expose to the customer browser.

Onboarding

Email Blue Car Rental to request a key. You will receive one production key and one staging key. Keys are not recoverable: if you lose a key, Blue Car Rental rotates it and issues a new one.

Rotation and deactivation

Blue Car Rental can rotate or deactivate any key at any time. Your integration should handle:

Treat the secret half of the key like a password. Keep it on the server. Never embed an API key in a customer-facing web or mobile bundle.

Concepts

Locations

A location is a physical workshop site. The v1 launch ships with one location: keflavik (Keflavík). The schema is multi-location-ready; new locations are added over time by Blue Car Rental.

Slots and availability

Slots are not stored — they are derived per request from operating-hour rules, blackouts, and existing bookings. Always call /availability immediately before showing a calendar to the customer. Do not cache slots client-side. The server caches the response for 30 seconds.

Service types

ValueMeaning
dekkjaskiptiTire change.
smurthjonustaOil and lube service.
annadOther / free-form (use the message field on the booking to describe).

Idempotency

The POST /bookings endpoint accepts an Idempotency-Key header (≤255 characters). Replaying the same key with the same payload returns the original booking instead of creating a duplicate. Replaying the same key with a different payload returns 409 idempotency_conflict. Keys are honoured for 24 hours; after that they are pruned and a replay creates a new booking.

Cancellation flow

When a booking is created, Blue Car Rental emails the customer a confirmation with a tokenised cancel link. The customer clicks the link to cancel. Partners do not call /cancel directly — the endpoint is documented for completeness only.

Rate limits

ScopeLimit
Per IP, global1000 requests/minute
Per API key, all endpoints500 requests/minute
Per API key, POST /bookings60 requests/minute

Exceeded → 429 rate_limited with a Retry-After header. Back off and retry.

Time zones

All slot_start_at values are UTC. The workshop in Keflavík operates in Atlantic/Reykjavik. Render times in the customer's local timezone in your UI, but always send and store UTC.

List locations

GET /api/v1/workshop/locations

List active workshop locations.

Request

curl -s https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/locations \
  -H "X-API-Key: bws_a1b2c3d4_<your-secret>"

Response

200 Success

{
  "locations": [
    {"slug": "keflavik", "name": "Keflavík", "timezone": "Atlantic/Reykjavik"}
  ]
}

Use the slug value as the location parameter in subsequent calls.

Check availability

GET /api/v1/workshop/availability

List bookable slots in a date range for a single location.

Query parameters

NameTypeRequiredNotes
locationstringYesLocation slug (e.g. keflavik).
fromdate (YYYY-MM-DD)YesInclusive.
todate (YYYY-MM-DD)YesInclusive. Max 90 days from from.
service_typestringNoAccepted but ignored in v1.

Request

curl -s "https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/availability?location=keflavik&from=2026-05-19&to=2026-05-23" \
  -H "X-API-Key: bws_a1b2c3d4_<your-secret>"

Response

200 Success

{
  "location": "keflavik",
  "slots": [
    {"start_at": "2026-05-19T09:00:00Z", "end_at": "2026-05-19T10:00:00Z"},
    {"start_at": "2026-05-19T10:00:00Z", "end_at": "2026-05-19T11:00:00Z"}
  ]
}
Only bookable slots appear. Closed days, blackouts, and already-booked slots are simply absent. Response is cached for 30 seconds at the HTTP layer.

Create a booking

POST /api/v1/workshop/bookings

Create a workshop booking.

Headers

NameRequiredNotes
X-API-KeyYesYour partner API key.
Content-TypeYesapplication/json.
Idempotency-KeyNo (recommended)Up to 255 chars. See Concepts → Idempotency.

Request body

FieldTypeRequiredNotes
locationstringYesLocation slug.
slot_start_atstring (RFC 3339 UTC)YesMust align with a slot returned by /availability.
service_typestringYesOne of dekkjaskipti, smurthjonusta, annad.
customer.namestringYes
customer.emailstringYesConfirmation email is sent here.
customer.phonestringYesE.164 recommended.
license_platestringYesPlate of the long-term rental car.
mileageintegerNoCurrent odometer.
messagestringNoFree text from the customer.

Request

curl -s -X POST https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/bookings \
  -H "X-API-Key: bws_a1b2c3d4_<your-secret>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9b1c-7e2f-2026-05-19-keflavik-AB123" \
  -d '{
    "location": "keflavik",
    "slot_start_at": "2026-05-19T09:00:00Z",
    "service_type": "dekkjaskipti",
    "customer": {"name": "Kalli Bimbo", "email": "kalli@example.is", "phone": "+3546901588"},
    "license_plate": "AB123",
    "mileage": 12345,
    "message": "Vil skipta yfir í sumardekk."
  }'

Response

201 Created

{
  "booking_id": "5f8e3b1c-4e2a-4a91-9b8f-2c7d6e5a4b3c",
  "status": "active",
  "location": "keflavik",
  "slot_start_at": "2026-05-19T09:00:00Z",
  "slot_end_at": "2026-05-19T10:00:00Z",
  "service_type": "dekkjaskipti",
  "cancel_url": "https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/bookings/5f8e3b1c-4e2a-4a91-9b8f-2c7d6e5a4b3c/cancel?token=..."
}

Error responses

Read a booking

GET /api/v1/workshop/bookings/{id}

Read a booking record. Two authentication modes are supported.

Authentication modes

ModeHowWhen to use
API keyX-API-Key headerPartner backend reading the booking.
Cancel token?token=<cancel_token> query stringPartner frontend confirmation page (no API secret in the browser bundle).

Request

curl -s https://ltcr-workshop-booking-api.bluecarrental.is/api/v1/workshop/bookings/5f8e3b1c-4e2a-4a91-9b8f-2c7d6e5a4b3c \
  -H "X-API-Key: bws_a1b2c3d4_<your-secret>"

Response

200 Success

{
  "booking_id": "5f8e3b1c-4e2a-4a91-9b8f-2c7d6e5a4b3c",
  "status": "active",
  "location": "keflavik",
  "slot_start_at": "2026-05-19T09:00:00Z",
  "slot_end_at": "2026-05-19T10:00:00Z",
  "service_type": "dekkjaskipti",
  "customer": {"name": "Kalli Bimbo", "email": "kalli@example.is", "phone": "+3546901588"},
  "license_plate": "AB123",
  "mileage": 12345,
  "message": "Vil skipta yfir í sumardekk.",
  "cancelled_at": null
}

Error responses

Cancel a booking

GET /api/v1/workshop/bookings/{id}/cancel

Single-click cancellation via the tokenised link in the confirmation email.

Partners do not call this endpoint directly. Blue Car Rental sends the customer a tokenised cancel link; the link target is this endpoint. Documented here for completeness so partners understand the round-trip.

Query parameters

NameRequiredNotes
tokenYesThe cancel token from the confirmation email.

Response

Determined by the Accept header:

200 Cancelled (JSON)

{
  "booking_id": "5f8e3b1c-4e2a-4a91-9b8f-2c7d6e5a4b3c",
  "status": "cancelled",
  "cancelled_at": "2026-05-17T14:23:08Z"
}

Error responses

Errors

Errors return a uniform JSON envelope:

{
  "error": "slot_taken",
  "message": "That slot was just booked. Please choose another time.",
  "details": {
    "slot_start_at": "2026-05-19T09:00:00Z"
  }
}

HTTP status codes

StatusMeaningRetry?
400 validation_failedMalformed request body or missing/invalid field.No.
401 unauthorizedMissing or invalid API key.No. Stop and contact Blue Car Rental.
403 forbiddenPartner deactivated, or cancel token does not match.No.
404 not_foundBooking ID unknown.No.
409 slot_takenSlot was just booked by someone else.No — terminal. Offer a different slot.
409 idempotency_conflictSame Idempotency-Key, different payload.No. Generate a new key.
409 already_cancelledBooking already cancelled (cancel endpoint only).No — treated as success.
409 too_late_to_cancelSlot start is in the past (cancel endpoint only).No.
422 slot_unavailableSlot is outside operating hours, on a blackout, or otherwise no longer offered.No. Refresh /availability.
429 rate_limitedRate limit exceeded.Yes, after Retry-After.
5xx internal_errorServer-side failure.Yes, with the same Idempotency-Key and exponential backoff.

Retry guidance