# Getting started

Welcome to the BookSpot OCTO API documentation. This API follows the [OCTO specification](https://docs.octo.travel/) for tours, activities, and attractions booking, with additional capabilities.

To learn more about how to set up your authentication token, please [read this help article](https://help.bookspot.io/en/articles/13002223-octo-integration).

## Base URL

All API requests should be made to:

```
https://api.bookspot.io/octo/v1
```

## Authentication

All API requests require Bearer token authentication.

### Getting Your API Token

1. Log in to your BookSpot account
2. Navigate to **Settings → Integrations → OCTO API**
3. Click **Create Token**
4. Copy your token and store it securely

### Using Your Token

Include the token in the `Authorization` header:

```http
Authorization: Bearer your-api-token-here
```

## Required Headers

Every request must include the following headers:

| Header              | Required | Description                                           |
| ------------------- | -------- | ----------------------------------------------------- |
| `Authorization`     | Yes      | Bearer token for authentication                       |
| `Octo-Capabilities` | Yes      | Comma-separated list of enabled capabilities          |
| `Accept-Language`   | No       | Preferred language (ISO 639-1 code, e.g., `sv`, `en`) |

### Example Request

```http
GET /octo/v1/products HTTP/1.1
Host: your-domain.com
Authorization: Bearer your-api-token-here
Octo-Capabilities: pricing,content,extras
Accept-Language: sv
```

## Capabilities

Capabilities are optional features that extend the API response. Enable them by including them in the `Octo-Capabilities` header.

| Capability | Description                                           |
| ---------- | ----------------------------------------------------- |
| `pricing`  | Include pricing information (in minor currency units) |
| `content`  | Include localized content (titles, descriptions)      |
| `extras`   | Include addon products (extras) for units             |

### Example

To enable pricing and content:

```
Octo-Capabilities: pricing,content
```

To enable all capabilities:

```
Octo-Capabilities: pricing,content,extras
```

## Content Localization

When the `content` capability is enabled, you can request content in a specific language using the `Accept-Language` header.

### Request

```http
Accept-Language: sv
```

### Response Headers

| Header                     | Description                                 |
| -------------------------- | ------------------------------------------- |
| `Content-Language`         | The language used in the response           |
| `Octo-Available-Languages` | Comma-separated list of available languages |

## Error Handling

The API returns errors in the following format:

```json
{
  "error": "ERROR_CODE",
  "errorMessage": "Human-readable description of the error"
}
```

### Common Error Codes

| Code                   | HTTP Status | Description                                     |
| ---------------------- | ----------- | ----------------------------------------------- |
| `INVALID_PRODUCT_ID`   | 400         | The product ID was invalid or not found         |
| `INVALID_BOOKING_UUID` | 400         | The booking UUID was invalid or not found       |
| `UNPROCESSABLE_ENTITY` | 400         | Request is valid but cannot be processed        |
| `Unauthorized`         | 401         | Invalid or missing authentication token         |
| `Too Many Requests`    | 429         | Rate limit exceeded — see **Rate Limits** below |

### Rate Limits

Every API token is independently rate-limited. Two limits apply simultaneously:

| Limit                     | Window          | Purpose                       |
| ------------------------- | --------------- | ----------------------------- |
| **300 requests / minute** | Sliding 60s     | Sustained throughput cap      |
| **25 requests / second**  | 5s burst window | Protects against short spikes |

Limits are scoped **per API token** — different tokens (even for the same shop) have independent counters.

#### Response Headers

Every successful response includes:

| Header                  | Description                              |
| ----------------------- | ---------------------------------------- |
| `X-RateLimit-Limit`     | The current limit being tracked          |
| `X-RateLimit-Remaining` | Requests remaining in the current window |

#### When You Hit a Limit

Exceeding either limit returns `HTTP 429 Too Many Requests` with a `Retry-After` header indicating the number of seconds to wait before retrying:

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 12
```

We recommend implementing exponential backoff on `429` responses and respecting `Retry-After`. If your integration consistently approaches the limits, contact support to discuss options.

## API Flow

{% stepper %}
{% step %}

### Get Products

List available products.
{% endstep %}

{% step %}

### Check Availability

Find available time slots.
{% endstep %}

{% step %}

### Create Reservation

Reserve a booking (expires if not confirmed).
{% endstep %}

{% step %}

### Confirm Booking

Finalize the booking.
{% endstep %}
{% endstepper %}

Products → Availability → Reserve → Confirm

## Next Steps

* [Supplier](/octo-api-core/supplier.md) - Get supplier information
* [Products](/octo-api-core/products.md) - List and retrieve products
* [Availability](/octo-api-core/availability.md) - Check availability
* [Bookings](/octo-api-core/bookings.md) - Manage bookings


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bookspot.io/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
