Booking
Sell an organization's bookable resources on its own website, as requests that an operator approves.
The booking API lets an organization sell its rooms and other bookable resources on its own website. A guest picks a time on the website, and your backend sends Hydda One a booking request. The request waits until an operator at the organization approves or rejects it. The API never confirms a booking by itself.
A company pays for each request. You name the company by its Swedish organisation number. Your Application never sees or names a customer contract. Hydda One decides which contract the booking is billed to.
What the token needs
The caller is the organization’s own Application, with a token from the client_credentials grant. See Authentication.
An administrator of the organization grants the Application the Booking Integration role. The role is granted at each business whose resources the Application may sell. Only an organization’s own Application can hold this role. An installed connector cannot. See Roles.
Every route under /v1/booking answers 403 to any other token, such as a person’s token or an installed connector’s token.
Call the API from your website’s backend. The client secret must never reach a visitor’s browser.
Which resources you can sell
A resource is listed only when all three of these hold:
- It is live.
- An operator marked it as bookable from outside.
- It belongs to a business where your Application holds the role.
Any other resource answers 404, as if it did not exist.
A resource carries its name, type, description, capacity and time zone. It also carries its booking rules, the opening hours in effect, its default price, VAT and pricing unit. roomLayouts lists the layouts a request may name. It is empty unless the room is furnished. imageUrls come in display order. purchaseTermsUrl links to the resource’s purchase terms.
A request from the API always costs the resource’s default price. No other price applies.
The flow
Each call is described in the booking reference.
- List the resources. Call
GET /v1/booking/resources. PassoperationalContextIdto list one business only. Read one resource withGET /v1/booking/resources/{resourceId}. - Read the free time. Call
GET /v1/booking/resources/{resourceId}/availabilitywithfromDateandtoDate. Both are local dates in the resource’stimeZone, and both are included. The range can be at most 31 days. - List the add-on products. Call
GET /v1/booking/resources/{resourceId}/add-on-products. A guest can order them with the booking, throughaddOnLines. This step is optional. - Look up the paying company. Call
POST /v1/booking/company-lookupswithorganizationNumber. Any written form of the number works. The number travels in the body so that it stays out of URLs and access logs. - Preview the request. Call
POST /v1/booking/booking-requests/previewwithbookableResourceId,timeSpec, and optionallyroomLayoutandaddOnLines. The answer has the exactstartsAtandendsAt, thequote, and the price of the add-ons. A preview writes nothing. - Send the request. Call
POST /v1/booking/booking-requestswith the preview’s fields plusbookingId,guestandcompany. The answer is the request withstatusset topending_approval. Hydda One emails the guest that the request was received. - Follow the request. Call
GET /v1/booking/booking-requests/{bookingId}to see its status. Hydda One does not call your backend when the status changes.
Free time by booking model
The resource’s bookingRules.model decides the shape of the free time. It also decides which timeSpec a request sends.
model |
Free time | What a request sends |
|---|---|---|
time_interval |
windows: periods where a unit is free the whole time. Each start sits on the rules’ increment. |
A startsAt and endsAt inside one window, within the rules’ durations. |
time_slots |
slots: each free slot, with its timeSpec. |
That slot’s timeSpec, unchanged. |
date_interval |
freeNights: each date whose night nobody holds. |
A fromDate and toDate over a run of free nights, within the rules’ minimum and maximum nights. |
date_span |
days: each date with units left, the count in remaining, and its timeSpec. |
That day’s timeSpec, unchanged. |
The free time already accounts for the opening hours, the minimum notice, the buffer between bookings and the two-year booking horizon. It counts every booking that holds time, including requests still waiting for approval.
Treat the free time as a guide. A request checks every rule again when Hydda One writes it. On a resource with several units, a long request or a stay of several nights can still be refused.
The paying company
The company lookup answers two fields:
existsistruewhen the organization already holds the company as a customer.invoicingDetailsRequiredistruewhen Hydda One cannot invoice the company yet. The request must then carrycompany.nameandcompany.billingAccount.
Send company.name and company.billingAccount together, or leave both out. When the lookup says they are not required, Hydda One does not use them.
The lookup never returns the company’s name, id or contracts.
Request statuses
status |
Meaning |
|---|---|
pending_approval |
The request waits for an operator. It holds its time, so nobody else can book it. |
confirmed |
An operator approved the request. Hydda One emails the guest a confirmation. |
rejected |
An operator refused the request. Its time is free again. |
expired |
Nobody decided in time. Its time is free again. |
cancelled |
The booking was cancelled. Its time is free again. |
A request expires after bookingRules.approvalExpiryMinutes, counted from when you sent it. When the field is absent, the request waits until an operator decides.
Rules for callers
Send each request once, with your own id
You mint bookingId, a UUID, before you send the request. Mint one id per guest request and keep it.
If a call times out, send the same request again with the same bookingId. Hydda One answers with the first request and writes nothing new. It does not check the body again, so a changed body with the same id is ignored.
If another booking already holds your bookingId, the answer is 409 with BOOKING_REQUEST_ID_ALREADY_USED. Mint a new id and send the request again.
The resource reads, the company lookup and the preview write nothing. You can repeat them freely.
Read the status yourself
Hydda One never calls your backend. Read the request with GET /v1/booking/booking-requests/{bookingId} to learn its status. You can read only requests your own Application made. Any other id answers 404.
Limits
| What | Limit |
|---|---|
limit on the resource list |
1 to 100. Defaults to 50. |
| Availability range | At most 31 days. |
guest.name, company.name |
1 to 200 characters. |
Requests under /v1/booking |
600 a minute from each IP address. |
Page through the resource list with nextCursor. Pass it as cursor, with the same operationalContextId as the first page. A cursor sent with a different filter answers 400.
All your website’s visitors reach Hydda One through your one backend. They therefore share the rate limit. A request over the limit gets 429.
Errors to handle
| Code | Status | When |
|---|---|---|
VALIDATION_FAILED |
400 | A body, query or path parameter does not match its schema. |
BOOKING_EXTERNAL_INVOICING_DETAILS_REQUIRED |
400 | The company needs company.name and company.billingAccount, and the request has neither. |
BOOKING_EXTERNAL_BILLING_ACCOUNT_INCOMPLETE |
400 | company.billingAccount lacks something an invoice needs, such as a contact name. detail names what is missing. |
BOOKING_REQUEST_ID_ALREADY_USED |
409 | Another booking holds your bookingId. |
BOOKING_SLOT_TAKEN |
409 | The time is no longer free. |
BOOKING_BUFFER_CONFLICT |
409 | The time is too close to another booking. |
BOOKING_NOTICE_TOO_SHORT |
400 | The booking starts too soon. |
BOOKING_OUTSIDE_OPEN_HOURS |
400 | The time falls outside the opening hours. |
BOOKING_TIME_SPEC_MODEL_MISMATCH |
400 | The timeSpec does not match the resource’s booking model. |
BOOKING_ROOM_LAYOUT_NOT_OFFERED |
400 | The roomLayout is not one of the resource’s roomLayouts. |
The other booking rules have codes of their own, such as BOOKING_DURATION_TOO_SHORT or BOOKING_STAY_TOO_LONG. A request that breaks a rule gets the same code an operator’s booking would get. Show the guest that the time cannot be booked, and read the free time again.
A 404 without a code means the resource or request does not exist, or your Application cannot see it.
Errors lists every booking code and its status.