Contents

REST API - Plugixa Chauffeur

Everything the admin app and the booking wizard do, they do over REST, under the namespace plugixa-chauffeur/v1. Anything the screens can do is therefore scriptable, and every rule is enforced at the route rather than in the page.

This is the API the plugin’s own screens use. It is not a separately versioned public API, and the plugin makes no promise that routes, parameters or response shapes stay the same between versions. Pin the plugin version you build against, and test after updating.

Authentication

There are two kinds of route.

Managed routes are for staff. The plugin adds no authentication of its own: it relies on whatever WordPress provides, then checks the permissions of the user WordPress identified.

Caller How
The admin app The logged-in cookie plus a REST nonce in the X-WP-Nonce header, the normal WordPress way
A script or another system Any method WordPress accepts for REST requests, such as an application password for an account that holds the permissions below

Public routes, under /public, are open to visitors because the booking wizard runs for people who are not logged in. They are described in Public routes.

Permissions

Called in the tables below What the caller needs
Manage The plugixa_chauffeur_manage capability
Manage + delete plugixa_chauffeur_manage and plugixa_chauffeur_delete
Administrator The WordPress manage_options capability
Public Nothing

Activation gives administrators five capabilities: plugixa_chauffeur_manage, plugixa_chauffeur_edit, plugixa_chauffeur_delete, plugixa_chauffeur_publish and plugixa_chauffeur_settings. Version 1.0.0 checks two of them, plugixa_chauffeur_manage and plugixa_chauffeur_delete. The other three are granted but no route tests them.

Every DELETE route needs both capabilities. Deleting is a separate grant from managing so that you can give day-to-day booking work to a role that cannot destroy records. A caller with manage but without delete gets 403 on DELETE and can still create and edit.

Both names can be changed with the plugixa_chauffeur_manage_capability and plugixa_chauffeur_delete_capability filters. See Hooks reference.

A caller who fails the check, logged in or not, gets status 403 with the code rest_forbidden and one of these messages:

Route kind Message
Manage “You do not have permission to perform this action.”
Manage + delete “You do not have permission to delete this item.”
Administrator “Administrator access required.”

Request and response shape

Send request bodies as JSON with Content-Type: application/json. The write routes read the JSON body only; form-encoded fields are ignored.

A successful response wraps its payload:

{
  "success": true,
  "message": "",
  "data": { }
}

A refusal is a standard WordPress REST error with a readable message and an HTTP status.

Code Status When
rest_forbidden 403 The permission check failed
rest_error 400, 404, 500 or 502 Validation failed, the record does not exist, the write failed, or Stripe refused
plugixa_chauffeur_unavailable 422 The pickup time is outside the availability rules
rest_no_route 404 The route does not exist, which includes every Pro route on a free site

List parameters

The list routes share these query parameters.

Parameter Meaning
limit or per_page Rows per page, 20 by default. -1 returns everything.
offset Rows to skip. Or pass page and let it be calculated.
orderby or sort_by A column from the route’s own list; anything else falls back to its default
order or sort_order ASC or DESC
search Text to match
filter An object holding any of the filters, for example filter[status]=pending

A list response’s data holds items, total, limit and offset.

Routes

Paths are relative to /wp-json/plugixa-chauffeur/v1.

Settings and dashboard

Method Route Needs What it does
GET /settings Administrator Every setting, with defaults filled in for keys never saved
POST /settings Administrator Merge the keys in the body into the stored settings. Keys you leave out are kept.
GET /settings/dashboard Manage Counts, the five latest bookings, the next five pickups, and 30 days of totals by day, service, vehicle and status, with the previous 30 days for comparison

The settings keys are listed in Settings.

Bookings

Method Route Needs What it does
GET /bookings Manage List bookings. search matches number, customer name and email; status filters. Sort by created_at, pickup_datetime, status, price_total or booking_number. The response adds status_counts.
POST /bookings Manage Create a booking by hand. See the note below.
GET /bookings/calendar Manage Bookings whose trip overlaps from to to (dates, default the current month), optionally one status or one vehicle_id. Returns events with start and end.
GET /bookings/{id} Manage One booking, with vehicle_name and driver_name
PUT /bookings/{id} Manage Update the fields sent
DELETE /bookings/{id} Manage + delete Delete the booking

Writable booking fields: status, service_type, transfer_type, pickup_address, dropoff_address, pickup_datetime, return_datetime, customer_name, customer_email, customer_phone, notes, payment_method, payment_status, currency, booking_form_id, vehicle_id, driver_id, passengers, luggage, travel_minutes, pickup_lat, pickup_lng, dropoff_lat, dropoff_lng, duration_hours, distance_km, price_base, price_distance and price_time.

status is one of pending, processing, completed, cancelled, on_hold, refunded or failed; anything else is saved as pending.

Three behaviours to know about:

  • price_total cannot be set directly. On create it is the sum of price_base, price_distance and price_time. On update it is recalculated as that sum only when at least one of the three is in the request; otherwise the stored total, including any pricing-rule adjustment, is left alone.
  • POST /bookings does no pricing or availability work. It does not call the fare calculator, does not run pricing rules, does not check availability and does not send the booking emails. It stores what you send.
  • A status change fires the status action, which sends the customer’s status email. See Emails.

Booking forms

Method Route Needs What it does
GET /booking-forms Manage List forms. search matches the name.
POST /booking-forms Manage Create a form. name is required.
GET /booking-forms/{id} Manage One form
PUT /booking-forms/{id} Manage Update the fields sent
DELETE /booking-forms/{id} Manage + delete Delete the form

Fields: name, enable_distance, enable_hourly, enable_flat, enable_return, default_service_type, currency, min_lead_time (minutes), min_passengers, status (published or draft), display_order and settings.

Vehicles

Method Route Needs What it does
GET /vehicles Manage List vehicles. Filters: search, status, vehicle_type_id.
POST /vehicles Manage Create a vehicle. name is required. A new vehicle is a draft unless status says published.
GET /vehicles/{id} Manage One vehicle
PUT /vehicles/{id} Manage Update the fields sent
DELETE /vehicles/{id} Manage + delete Delete the vehicle
POST /vehicles/reorder Manage Set display order. Body: items, a list of { "id", "display_order" }.

Fields: name, slug, description, vehicle_type_id, image_id, gallery (attachment IDs), max_passengers, max_luggage, base_location_id, base_price, price_per_distance, price_per_hour, min_price, status and display_order.

Vehicle types

Method Route Needs What it does
GET /vehicle-types Manage List vehicle types. search filters.
POST /vehicle-types Manage Create a type. name is required.
GET /vehicle-types/{id} Manage One type
PUT /vehicle-types/{id} Manage Update the fields sent
DELETE /vehicle-types/{id} Manage + delete Delete the type. Its vehicles are kept and lose their type.
POST /vehicle-types/reorder Manage Set display order, as for vehicles

Locations

Method Route Needs What it does
GET /locations Manage List locations. Filters: search, type.
POST /locations Manage Create a location. name is required. Other fields: address, latitude, longitude, place_id, type, display_order.
GET /locations/{id} Manage One location
PUT /locations/{id} Manage Update the fields sent
DELETE /locations/{id} Manage + delete Delete the location
POST /locations/reorder Manage Set display order, as for vehicles

Availability

Method Route Needs What it does
GET /availability Manage The availability rules
PUT /availability Manage Replace the availability rules
POST /availability Manage The same as PUT

Body: enabled, lead_time_minutes, horizon_days, business_hours (keys 1 for Monday to 7 for Sunday, each with open, start and end as HH:MM) and blackout_dates (a list of start, end and label, dates as YYYY-MM-DD). The body replaces the stored rules as a whole, so send all of it. See Availability.

Drivers PRO

Method Route Needs What it does
GET /drivers Manage List drivers with a booking_count. search matches name, email and phone; status filters.
POST /drivers Manage Create a driver. name is required.
GET /drivers/{id} Manage One driver
PUT /drivers/{id} Manage Update the fields sent
DELETE /drivers/{id} Manage + delete Delete the driver and clear them from every booking

Fields: name, slug, email, phone, photo_id, bio, status (active or inactive) and display_order.

Pricing rules PRO

Method Route Needs What it does
GET /pricing-rules Manage List rules in running order. search matches the name.
POST /pricing-rules Manage Create a rule. name is required.
GET /pricing-rules/{id} Manage One rule
PUT /pricing-rules/{id} Manage Update the fields sent
DELETE /pricing-rules/{id} Manage + delete Delete the rule

Fields: name, status, priority, adjustment_type (set_value, increase_value, decrease_value, increase_percent or decrease_percent), adjustment_value, stop_processing, display_order and conditions.

conditions is an object with any of service_types, vehicle_ids, days_of_week (0 for Sunday to 6 for Saturday), date_from, date_to, min_distance, max_distance, min_passengers and max_passengers. Sending conditions replaces the whole object. vehicle_ids is honoured by the engine but has no field in the admin form. See Pricing rules.

Routes PRO

Method Route Needs What it does
GET /routes Manage List flat-rate routes. search matches the name and both labels.
POST /routes Manage Create a route. name is required.
GET /routes/{id} Manage One route
PUT /routes/{id} Manage Update the fields sent
DELETE /routes/{id} Manage + delete Delete the route

Fields: name, pickup_label, dropoff_label, price, status (active or inactive) and display_order.

Reports PRO

Method Route Needs What it does
GET /reports/summary Manage Totals, breakdowns, a daily series and up to 1,000 booking rows for bookings created between from and to

from and to are YYYY-MM-DD. Without them the range is the last 30 days.

Public routes

These four routes take no capability and no login. Each is limited in what it can read or write.

Method Route What it does
GET /public/form/{id} The configuration of one published booking form
POST /public/quote Prices for a trip, one per suitable vehicle
POST /public/book Create a booking. Needs the booking nonce.
POST /public/stripe-webhook Receive payment confirmations from Stripe. Needs a valid signature.

The read routes only ever return published forms and published vehicles, and only the columns a visitor is meant to see. A draft form answers 404, “Booking form not found.”

GET /public/form/{id}

Returns id, name, currency, service_types, default_service_type, enable_return, min_passengers, min_lead_time, distance_unit, payment_methods and availability. With Pro and flat rate enabled on the form, it also returns routes.

POST /public/quote

Parameter Meaning
form_id The booking form. Required.
service_type distance, hourly, or flat with Pro
transfer_type one_way or return
distance_km The trip distance, for distance bookings
duration_hours The hours booked, for hourly bookings
passengers Vehicles with fewer seats are left out
pickup_datetime YYYY-MM-DD HH:MM, or with a T between date and time, in the site’s time zone
route_id The chosen route, for flat-rate bookings

Returns currency and vehicles. Each vehicle has vehicle_id, name, description, image_url, vehicle_type_name, max_passengers, max_luggage, price_base, price_distance, price_time and price_total.

The pickup time is checked against the availability rules, so a quote for a closed day is refused with status 422. Nothing is written.

POST /public/book

This is the one public route that writes, and it is gated on a nonce.

The nonce. When the booking form’s shortcode is rendered, the page receives a WordPress nonce for the action plugixa_chauffeur_frontend. The wizard sends it back as nonce in the JSON body; the X-Plugixa-Chauffeur-Nonce header is accepted instead. A request without a valid nonce is refused with status 403, “Security check failed. Please refresh and try again.” A WordPress nonce belongs to the user it was made for and expires, within a day at most, so a page left open or served from a long-lived cache can hold a stale one. See Troubleshooting.

The body takes everything /public/quote takes, plus:

Parameter Meaning
nonce The booking nonce. Required.
vehicle_id The chosen vehicle. Must be published and have enough seats.
customer_name, customer_email Required. The email must be valid.
customer_phone, notes Optional
pickup_address, dropoff_address The addresses as text
luggage Number of bags
payment_method stripe, cash, wire or pickup. A method that is not enabled is replaced by the first enabled one.
return_url Where Stripe sends the customer back to. Must be on this site, or the home page is used.

What the server does, in order: checks the nonce, loads the published form, checks the pickup time against the availability rules, checks it against the form’s own minimum lead time, validates the name and email, loads the published vehicle, and recalculates the fare itself. Any price in the request is ignored. The booking is created with status pending and payment status unpaid.

The response holds booking_id, booking_number, status, price_total, currency, vehicle_name, payment_method, payment_label, payment_type and payment_instructions. For a Stripe booking it also holds checkout_url, the Stripe Checkout page to send the customer to.

POST /public/stripe-webhook

Stripe calls this route server to server, so it cannot carry a WordPress login or nonce. It is authenticated by Stripe’s signature instead.

The signature check. The plugin reads the Stripe-Signature header and the raw request body, and verifies them against the Webhook signing secret from Settings before reading anything from the payload:

  1. The header must contain a timestamp t and at least one v1 signature.
  2. The timestamp must be within 300 seconds of the server’s clock.
  3. An HMAC-SHA256 of timestamp.body, keyed with the signing secret, must equal one of the v1 signatures, compared in constant time.

If any step fails the response is status 400 with {"error": "invalid_signature"} and nothing is changed. An empty signing secret fails the check, so a site with no secret configured rejects every call.

A verified checkout.session.completed event whose session is paid marks the booking named in the session’s metadata as paid, and moves it from pending to processing. A booking that is already paid is left alone, so a repeated delivery is harmless. Every other verified event is acknowledged with {"received": true} and ignored.

The endpoint to register in your Stripe dashboard is:

https://example.com/wp-json/plugixa-chauffeur/v1/public/stripe-webhook

See Payments.

A worked example

Quote a 25 km one-way trip for three passengers on form 1:

curl -X POST https://example.com/wp-json/plugixa-chauffeur/v1/public/quote \
  -H "Content-Type: application/json" \
  -d '{"form_id":1,"service_type":"distance","transfer_type":"one_way","distance_km":25,"passengers":3,"pickup_datetime":"2026-10-10 20:00"}'

List pending bookings as a member of staff, using an application password:

curl -u "dispatcher:xxxx xxxx xxxx xxxx xxxx xxxx" \
  "https://example.com/wp-json/plugixa-chauffeur/v1/bookings?status=pending&limit=50"

Mark booking 42 as completed:

curl -X PUT -u "dispatcher:xxxx xxxx xxxx xxxx xxxx xxxx" \
  -H "Content-Type: application/json" \
  -d '{"status":"completed"}' \
  https://example.com/wp-json/plugixa-chauffeur/v1/bookings/42

Adding your own routes

The plugixa_chauffeur_register_rest_routes action fires on rest_api_init with the namespace, after the plugin’s own routes are registered. See Hooks reference.

Quick Links