# TourCockpit API 1.0.0

Base URL `https://tourcockpit.com/api/v1`. Bearer API keys (see https://tourcockpit.com/auth.md). The contract is the OpenAPI 3.1 document at https://tourcockpit.com/api/openapi.json; the interactive reference is at https://tourcockpit.com/api/docs. Every endpoint below is generated from that document.

## Endpoints

- `GET /api/v1/tours`: List tours
- `POST /api/v1/tours`: Create a tour
- `GET /api/v1/tours/{id}`: Get a tour
- `PATCH /api/v1/tours/{id}`: Update a tour
- `POST /api/v1/tours/{id}/archive`: Archive a tour
- `PUT /api/v1/tours/{id}/translations`: Correct a tour's translation in one language: a text keeps the person's wording, null goes back to the automatic translation. A text for a field the tour leaves empty is refused (400)
- `GET /api/v1/schedule`: List scheduled instances in a date range
- `PUT /api/v1/schedule/instances`: Place (or reactivate) a tour on a date: 201 when it made the departure, 200 when it found the one already on that day
- `POST /api/v1/schedule/instances`: Add a departure to a day (a second one of the same tour is a parallel departure)
- `PATCH /api/v1/schedule/instances/{id}`: Change a departure: its guide, chauffeur, van, length, note, reserved operators or tour
- `POST /api/v1/schedule/instances/{id}/cancel`: Cancel a scheduled instance
- `POST /api/v1/schedule/instances/{id}/move`: Move a departure, with its bookings, to another day
- `POST /api/v1/schedule/instances/{id}/link`: Link two departures of one day into a convoy
- `POST /api/v1/schedule/instances/{id}/unlink`: Take a departure out of its convoy
- `PUT /api/v1/schedule/instances/{id}/booking-order`: Put a departure's bookings in a new order
- `PUT /api/v1/schedule/order`: Put a day's departures in a new order
- `POST /api/v1/schedule/instances/batch`: Add one more departure of a tour on each of several days, all of them or none
- `PUT /api/v1/planning/mix`: Set how many departures of each vehicle size a tour runs on each day, all the days or none
- `GET /api/v1/bookings`: List bookings
- `POST /api/v1/bookings`: Create a booking
- `GET /api/v1/bookings/{id}`: Get a booking
- `PATCH /api/v1/bookings/{id}`: Update a booking
- `POST /api/v1/bookings/{id}/move`: Move a booking to another instance
- `POST /api/v1/bookings/{id}/cancel`: Cancel a booking
- `GET /api/v1/daily-board`: The Daily Operations Board for a date
- `POST /api/v1/daily-board/availability`: Mark a guide working or off for one day
- `POST /api/v1/daily-board/send`: Send the day's board file to the company's own people, chosen by id, by email or WhatsApp: a status per person, five sends a minute. Made on its own, never in a batch; a dry run makes no file and sends nothing. Sent by a person: an API key gets 422 NOT_A_PERSON
- `POST /api/v1/daily-board/send-to-me`: Send the day's board file to the person asking and to nobody else, by email or WhatsApp. Made on its own, never in a batch; a dry run makes no file and sends nothing. An API key gets 422 NOT_A_PERSON
- `GET /api/v1/daily-board/export-preferences`: How the Export sheet opens for the person asking: their last choice at this company, or null (always null for an API key, which has no sheet of its own)
- `PUT /api/v1/daily-board/export-preferences`: Save how the Export sheet opens for the person asking, at this company; a download keeps the people of the last send. Their own choice only; an API key gets 422 NOT_A_PERSON
- `PUT /api/v1/daily-notes/{date}`: Write or clear the day's general note
- `GET /api/v1/inbox`: The caller's own inbox, newest first; reading it marks nothing read
- `POST /api/v1/inbox/{id}/read`: Mark one of the caller's own inbox items read or unread; an id that is not theirs changes nothing
- `POST /api/v1/inbox/read-all`: Mark everything unread in the caller's own inbox as read
- `GET /api/v1/connected-apps`: The apps reading this company's data from outside: the caller's own, and everyone's and the ones the office ended where the caller's access reaches them
- `POST /api/v1/connected-apps/{id}/disconnect`: End one connected app: the caller's own in every company (mine), or for this company only (company; another person's too, where the caller's access reaches it). Made on its own, never in a batch
- `POST /api/v1/connected-apps/{id}/allow`: Let an app this office ended back in for that person (a manager or the owner). Made on its own, never in a batch
- `GET /api/v1/reference/hotels`: List hotels (all=true also lists the retired rows, where the caller's access reaches them)
- `POST /api/v1/reference/hotels`: Create a hotel
- `PATCH /api/v1/reference/hotels/{id}`: Update a hotel
- `POST /api/v1/reference/hotels/{id}/active`: Retire or restore a hotel
- `GET /api/v1/reference/zones`: List pickup zones in driving order (all=true also lists the retired rows, where the caller's access reaches them)
- `POST /api/v1/reference/zones`: Create a pickup zone
- `PUT /api/v1/reference/zones/order`: Set the driving order of the live pickup zones (the order the grid, the pickers and this list use)
- `PATCH /api/v1/reference/zones/{id}`: Rename a pickup zone (hotels and grid rows keep pointing at it)
- `POST /api/v1/reference/zones/{id}/active`: Retire or restore a pickup zone
- `GET /api/v1/reference/pickup-times`: The times this company offers (includeRetired=1 also lists the retired times, where the caller's access reaches them)
- `POST /api/v1/reference/pickup-times`: Add a pickup time (409 when the company already offers it)
- `PATCH /api/v1/reference/pickup-times/{id}`: Retire or restore a pickup time (rows already holding it keep it)
- `GET /api/v1/reference/tour-zone-pickup-times`: The tour-by-zone pickup grid: every answered cell (a time, or null for No stop)
- `PUT /api/v1/reference/tour-zone-pickup-times`: Replace the whole pickup grid (every time must be one the company offers)
- `PATCH /api/v1/reference/tour-zone-pickup-times`: Answer one cell of the pickup grid: a time the company offers, No stop, or not set
- `POST /api/v1/reference/tour-zone-pickup-times/claim`: Use a time for every future pickup of a tour from a zone, only if the cell is not set yet
- `GET /api/v1/reference/tour-zone-prices`: The tour-by-zone price grid: every cell the office has overridden
- `PUT /api/v1/reference/tour-zone-prices`: Replace the whole price grid (one bad cell rejects the lot)
- `PATCH /api/v1/reference/tour-zone-prices`: Set or clear one cell of the price grid (null is the tour's own price; both null clears it)
- `GET /api/v1/reference/operators`: List operators (all=true also lists the retired rows, where the caller's access reaches them)
- `POST /api/v1/reference/operators`: Create an operator
- `PATCH /api/v1/reference/operators/{id}`: Update an operator
- `POST /api/v1/reference/operators/{id}/active`: Retire or restore an operator
- `GET /api/v1/reference/drivers`: List the guides and drivers (GUIA and CHOFER roster) with the languages they speak (all=true also lists the retired rows, where the caller's access reaches them)
- `POST /api/v1/reference/drivers`: Add a guide or driver to the roster, with the languages they speak
- `PATCH /api/v1/reference/drivers/{id}`: Change a guide or driver (a field left out keeps its value)
- `POST /api/v1/reference/drivers/{id}/active`: Retire or restore a guide or driver
- `GET /api/v1/reference/driver-availability`: Who is off, and who is left, across a window: the Driver Availability grid, read (manager, like the page; no window means today)
- `PUT /api/v1/reference/driver-availability`: Set guides working or off: one day, several cells, or a span with a reason. Several days are all or nothing: a day a guide runs a tour refuses them all (DRIVER_ASSIGNED, naming every blocked guide and their days)
- `GET /api/v1/reference/vehicles`: List the FURGO fleet with each van's seats (all=true also lists the retired rows, where the caller's access reaches them)
- `POST /api/v1/reference/vehicles`: Add a van to the fleet
- `PATCH /api/v1/reference/vehicles/{id}`: Change a van (a field left out keeps its value)
- `POST /api/v1/reference/vehicles/{id}/active`: Retire or restore a van
- `GET /api/v1/reference/child-seats`: List the child-seat options in the order the pickers show them, with their translations (all=true also lists the retired rows, where the caller's access reaches them)
- `POST /api/v1/reference/child-seats`: Add a child-seat option, described in the company's language (the product translates the rest)
- `PUT /api/v1/reference/child-seats/order`: Set the order every child-seat picker shows
- `PATCH /api/v1/reference/child-seats/{id}`: Change a child-seat option (a field left out keeps its value)
- `POST /api/v1/reference/child-seats/{id}/active`: Retire or restore a child-seat option
- `PUT /api/v1/reference/child-seats/{id}/translations`: Correct a child seat's description in one language: a text keeps the person's wording, null goes back to the automatic translation. A text for an empty description is refused (400)
- `GET /api/v1/reference/languages`: List languages
- `GET /api/v1/kpi`: What can be measured, and the questions each calculator answers
- `GET /api/v1/kpi/{slug}`: Run one calculator over a date range: one named number, with its breakdown
- `GET /api/v1/reports/monthly`: Monthly RIEPILOGO rollup
- `GET /api/v1/audit`: Activity log (change history)
- `GET /api/v1/audit/history`: One record's history (or one day's) as the History drawer shows it: who changed what, by name, newest first
- `GET /api/v1/audit/{requestId}/revert-plan`: What reverting one Activity Log event would put back, or why it cannot be reverted
- `POST /api/v1/audit/{requestId}/revert`: Revert one Activity Log event through the same services, all or nothing (409 REVERT_REFUSED says why not)
- `GET /api/v1/company`: Get the company and its policy settings
- `PATCH /api/v1/company`: Update company policy settings
- `POST /api/v1/api-keys`: Mint an API key (raw key shown once)
- `GET /api/v1/api-keys`: List API keys (metadata only)
- `POST /api/v1/api-keys/{id}/revoke`: Revoke an API key
- `GET /api/v1/users`: List users (optionally filtered by operator)
- `POST /api/v1/users`: Invite a user (office MANAGER, or OPERATOR when tourOperatorId is set), by email and, for a desk person with a whatsapp, on WhatsApp too. An address that already has an account elsewhere is added with no invitation (added: true)
- `PATCH /api/v1/users/me`: Change your own profile: name, WhatsApp number, notifications and language (anyone signed in; a company key is not a person)
- `PATCH /api/v1/users/{id}`: Update a team member: name, active, WhatsApp number, an office member's notification switches, and their language, where the caller's access reaches it
- `POST /api/v1/users/{id}/resend-invite`: Send the sign-in link again to someone who has not signed in yet, and start their reminders again
- `PUT /api/v1/users/{id}/read-only`: Make a member read only in this company, or give them changes back (the Owner, as a person)
- `GET /api/v1/signup-requests`: The tour operators' requests still waiting, newest first
- `POST /api/v1/signup-requests/{id}/invite`: Accept a request: the operator (an existing one, or a new one named as the request names it) and an invited user, in one. The phone the request gave becomes the user's WhatsApp and gets the invitation too, unless another active user already has that number (409 REQUEST_HAS_ACCOUNT when the address already has an account: remove the request instead)
- `POST /api/v1/signup-requests/{id}/decline`: Decline a request, once; nothing is sent to the person who asked
- `POST /api/v1/signup-requests/{id}/remove`: Take a waiting request off the list, made by mistake or whose address already has an account; nothing is sent to the person who asked, who may ask again, and its reminders stop
- `POST /api/v1/batch`: Make several writes in one go: all of them or none
- `GET /api/v1/operator/board`: The operator's restricted board for a date
- `GET /api/v1/operator/sales`: What this desk sold for the company: bookings, guests and booking value, by payment and by tour
- `GET /api/v1/operator/bookings`: The operator's own bookings over a window of tour dates, by guest, room or hotel
- `POST /api/v1/operator/bookings`: Add a booking for the operator
- `POST /api/v1/operator/bookings/extra-van`: Open an extra van for a tour and a day with a booking for the operator, or join the departure of that tour that has room (409 NO_FREE_VAN when no extra van is left that day)
- `GET /api/v1/operator/bookings/{id}`: Get one of the operator's own bookings
- `PATCH /api/v1/operator/bookings/{id}`: Edit one of the operator's own bookings
- `GET /api/v1/operator/colleagues`: The people of the operator's own team
- `POST /api/v1/operator/colleagues`: Invite a colleague into your team (ten an hour)
- `GET /api/v1/operator/crew`: Who guides and who drives the departures this operator can see, by name only
- `POST /api/v1/operator/colleagues/{id}/deactivate`: Switch off a colleague of the operator's own team; bringing them back is the office's
- `POST /api/v1/operator/colleagues/{id}/resend-invite`: Send a colleague of the operator's own team their invitation again, and start their reminders again
- `POST /api/v1/operator/bookings/{id}/cancel`: Cancel one of the operator's own bookings, up to the company's cancellation notice (409 PAST_CANCELLATION_NOTICE after it)
- `GET /api/daily-board/pdf`: Daily Operations Board as a PDF (non-versioned, binary)
- `PUT /api/daily-board/export-preferences`: Save the Export sheet's last choice for the signed-in person at this company (non-versioned)
