Hire A Bus
Sign in
Authentication

One bearer token, and only the permissions you were given

Every call carries Authorization: Bearer <token>. A token holds an explicit list of scopes; anything it was not granted is refused, and a token granted nothing can do nothing.
Hire A Bus operator APIVersion 1.0.042 endpointshttps://hireabus.com

Getting a key

Keys belong to the operator, not to you. An admin on their account opens their API keys screen, picks the scopes your system needs, and gives you the key that appears — once. We store only a hash of it, so nobody, including us, can read it back. If it is lost, the operator revokes it and mints another.

Ask for the narrowest set that does the job. It is the operator who decides, and a request for everything is a slower conversation than a request for two scopes with a reason attached.

Open the API keys screen

Using it

curl https://hireabus.com/api/v1/me \
  -H "Authorization: Bearer $HIREABUS_API_KEY" \
  -H "Accept: application/json"

/api/v1/me needs no scope and is the cheapest way to check a key is alive and which operator it belongs to. Send the header on every request — there are no cookies, no session and no CSRF token on this API.

Scopes

These are the whole list. There is no free-text scope and no wildcard: a key holds cases from this table and nothing else, which is why a scope added tomorrow cannot silently widen a key issued today.

jobs:readSee job requests

Read the job requests in your inbox, without customer contact details.

  • GET /api/v1/jobs
  • GET /api/v1/jobs/{ref} — One job, addressed by its trip ref
quotes:writeSend and update quotes

Submit, revise, withdraw and decline quotes, and answer booking requests.

  • POST /api/v1/jobs/{ref}/confirm-booking-request — Accept a customer's booking request: charges their saved card for the deposit and confirms the booking
  • POST /api/v1/jobs/{ref}/decline — Turn the job down
  • POST /api/v1/jobs/{ref}/quote — Submit a quote, or revise one already submitted
  • POST /api/v1/jobs/{ref}/reject-booking-request — Turn a booking request down, with a reason the customer is shown
  • POST /api/v1/jobs/{ref}/unconfirm — Drop a confirmed quote to `likely` without touching the price. The customer can still request to book; it just stops being instantly bookable
  • POST /api/v1/jobs/{ref}/withdraw — Retract a quote the customer has not yet acted on
bookings:readSee confirmed bookingsIncludes customer contact details

Read your confirmed bookings, including the customer contact details you already see in the portal.

  • GET /api/v1/bookings
  • GET /api/v1/bookings/{ref}
  • POST /api/v1/bookings/{ref}/driver — Assign (or re-assign) a driver and vehicle registration
drivers:readSee your drivers

Read your driver roster.

  • GET /api/v1/drivers
drivers:writeAdd and update drivers

Add drivers to your roster and update their details.

  • POST /api/v1/bookings/{ref}/driver — Assign (or re-assign) a driver and vehicle registration
  • POST /api/v1/drivers — Add a driver to the roster
  • POST /api/v1/drivers/{id}/reinvite — Re-send the driver's app sign-in link
payouts:readSee your payouts

Read your payout history and what is on its way.

  • GET /api/v1/payouts
webhooks:manageManage event notifications

Set up and remove the URLs we notify when something changes.

  • GET /api/v1/webhooks
  • POST /api/v1/webhooks — Subscribe a URL
  • DELETE /api/v1/webhooks/{id}
  • GET /api/v1/webhooks/{id}/deliveries — The delivery log for one subscription — what we sent, when, and what status came back. This is the endpoint an integrator uses to answer "did you send it?" without asking us

A job before a deposit is paid carries the itinerary and nothing that identifies the customer — no name, no email, no phone number. Those appear on a booking once it is won, and only to a key holding a scope that says so.

Tokens for the mobile app

The Hire A Bus operator and driver apps get their token a different way — a sign-in link or an SMS code exchanged for a bearer, rotated per device and revocable per handset. These endpoints exist for those apps; a third-party integration uses a key from the portal instead.

EndpointWhat it does
GET /api/v1/auth/devicesThe signed-in devices for the calling operator user
DELETE /api/v1/auth/devices/{id}Sign a device out. Takes effect on that device's very next call
POST /api/v1/auth/exchangeExchange a consumed sign-in link for a bearer token
POST /api/v1/auth/linkRequest a sign-in link
POST /api/v1/auth/rotateRotate the presented token. The old one dies in the same request

When we say no

Every failure has the same shape. Branch on error.code, which is stable; error.message is written for a human and may be reworded.

{
  "error": {
    "code": "missing_ability",
    "message": "This key is not allowed to send quotes.",
    "missing_ability": "quotes:write"
  }
}
Statuserror.codeWhat it means
401unauthenticatedNo token, or one that has expired or been revoked. Nothing to retry — get a new key.
403missing_abilityThe key is real but is not allowed to do this. `error.missing_ability` names the one scope it is short of.
404not_foundNo such thing on your account. A reference belonging to another operator answers 404, not 403, so the API cannot be used to discover what exists.
429rate_limitedToo fast. `Retry-After` says how long to wait.

A 403 is the only one worth special-casing: it names the exact scope the key is short of, so your error message to the operator can tell them what to tick when they mint the replacement.

Looking after the key

Keep it server-side. It is a credential for someone else's business: it can see their jobs, and depending on scope it can price work and see the people who booked it. Do not put it in a mobile app, a browser or a repository, and rotate it if it has ever been somewhere it should not have been — the operator can revoke and re-issue in under a minute.