Booko API v3

Build amazing book discovery and reading list applications

Beta Service

API access is currently in BETA. This service has no guarantees and may change or become unavailable without notice.

Contact the Booko team for support, questions, or to request API access and editor permissions.

Maintaining an older integration? The v1 reference is still published — v1 and v2 remain in service.

Overview

The Booko API v3 provides RESTful endpoints for building applications that help users discover books and manage reading lists. Perfect for book recommendation apps, reading trackers, and book discovery services.

Base URL

https://api.booko.info/api/v3/

What you can build:

  • Reading list management applications
  • Book recommendation systems
  • Book discovery and review platforms
  • Library management systems

Authentication

🎯 JWT Tokens (Recommended)

For the best performance and security, use JWT tokens. You can exchange your API token for a short-lived JWT:

POST /api/tokens/exchange
curl -X POST https://api.booko.info/api/tokens/exchange \
  -H "Authorization: Bearer your-api-token"

# Response:
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 1800,
  "scope": "read"
}

JWT Benefits: Stateless authentication, no database lookups, 30-minute lifespan, automatic refresh capability.

🔑 API Token (Direct)

For simpler use cases, use your API token directly:

Authorization: Bearer your-api-token

🛡️ OAuth 2.0 (For User Apps)

For applications that need user authorization, use our OAuth 2.0 flow with PKCE:

1 GET /oauth/authorize - Authorization request
2 POST /oauth/token - Token exchange
3 POST /oauth/token - Token refresh

Getting Started

1

Get API Access

Contact Booko to get your API token and access credentials.

2

Choose Authentication

Use JWT tokens for best performance, or API tokens for simplicity.

3

Make Your First Request

Try fetching your user info with GET /me

Quick Test
curl -H "Authorization: Bearer your-token" \
     https://api.booko.info/api/v3/me

User Information

GET /me

Get current user information and OAuth application details.

Response Example:

{
  "resource_owner": {
    "id": 123,
    "name": "John Doe",
    "email": "john@example.com",
    "is_editor": false,
    "created_at": "2023-01-01T00:00:00Z"
  },
  "application": {
    "name": "My Book App",
    "scopes": ["read"]
  }
}

Products

Manage individual books and their metadata. Products represent specific editions with GTINs/ISBNs.

GET /products/:id Public

Get detailed information about a specific product. ID can be GTIN, ISBN, or internal ID.

Response Example:

{
  "type": "product",
  "id": 123,
  "gtin": "9781234567890",
  "title": "The Great Book",
  "subtitle": "A Wonderful Story",
  "author": "Jane Smith",
  "publisher": "Great Publisher",
  "published_on": "2023-01-01",
  "package": "Paperback",
  "cover_url": "https://covers.booko.info/...",
  "description": "An amazing book about...",
  "path": "/products/9781234567890",
  "work": {
    "id": 456,
    "name": "The Great Book",
    "gtins": ["9781234567890", "9780987654321"]
  }
}
POST /products Editor Required
PUT/PATCH /products/:id Editor Required

Create new products or update existing ones. Requires editor permissions.

Request Body:

{
  "product": {
    "gtin": "9781234567890",
    "title": "Book Title",
    "subtitle": "Book Subtitle",
    "author": "Author Name",
    "publisher": "Publisher Name",
    "published_on": "2023-01-01",
    "package": "Paperback"
  }
}

Reading Lists

Manage user reading lists that can contain products, works, or series.

GET /lists

Get user's lists or public discoverable lists.

Query Parameters:

  • discoverable=true - Get public lists
  • sort_by - name, created_at, updated_at (default: updated_at)
  • sort_direction - asc/desc (default: desc)
  • per_page - Items per page (default: 20)
  • page - Page number (default: 1)
POST /lists

Create a new reading list.

Request Body:

{
  "name": "My Reading List",
  "visibility": "hidden",
  "region": 1,
  "gtins": ["9781234567890", "9780987654321"]
}
Visibility Options:
  • hidden - Only visible to owner
  • sharable - Visible via direct link
  • discoverable - Public and searchable
GET /lists/:id
PUT/PATCH /lists/:id
DELETE /lists/:id

Get, update, or delete a specific list. ID can be numeric ID or list key.

List Items

Manage individual items within reading lists.

GET /lists/:list_id/items

Get all items in a list with pagination.

POST /lists/:list_id/items

Add items to a list. Supports single items or bulk operations.

Single Item:

{
  "type": "Product",
  "id": "9781234567890",
  "quantity": 1
}

Multiple Items:

{
  "items": [
    {
      "type": "Product",
      "id": "9781234567890",
      "quantity": 1
    },
    {
      "type": "Work", 
      "id": "123",
      "quantity": 1
    }
  ]
}
Supported Types:
  • Product - Individual books with GTINs
  • Work - All editions of a book
  • Series - Complete book series
PUT/PATCH /lists/:list_id/items/:id
DELETE /lists/:list_id/items/:id

Update item quantity or remove items from lists.

Price Alerts

Create and manage price alerts for books. Get notified when prices drop below your target price.

GET /alerts

Get user's alerts with filtering and sorting options.

Query Parameters:

  • active - Filter by active status: true/false
  • sort - Sort by: created_at, product_title, new_price (default: updated_at)

Response Example:

{
  "data": [
    {
      "id": 123,
      "product_id": 456,
      "product_title": "The Great Book",
      "product_gtin": "9781234567890",
      "new_price": "25.99",
      "used_price": "15.99",
      "include_used": true,
      "active": true,
      "region_id": 1,
      "region_name": "Australia",
      "created_at": "2023-01-01T00:00:00Z",
      "updated_at": "2023-01-02T00:00:00Z",
      "deactivated_at": null,
      "sent_date": null,
      "sent_price": null
    }
  ],
  "meta": {
    "total_count": 5,
    "active_count": 3,
    "inactive_count": 2
  }
}
GET /alerts/:id

Get details of a specific alert. ID can be alert ID or product GTIN.

POST /alerts

Create a new price alert or update an existing one for the same product.

Request Body:

{
  "alert": {
    "gtin": "9781234567890",
    "new_price": "25.99",
    "used_price": "15.99",
    "include_used": true,
    "active": true
  }
}
Alert Options:
  • gtin - Product GTIN/ISBN (required)
  • new_price - Target price for new condition books
  • used_price - Target price for used condition books
  • include_used - Include used books in price checks
  • Note: At least one of new_price or used_price must be set
Example Request
curl -X POST https://api.booko.info/api/v3/alerts \
  -H "Authorization: Bearer your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "alert": {
      "gtin": "9781234567890",
      "new_price": "25.99",
      "used_price": "15.99",
      "include_used": true,
      "active": true
    }
  }'
PUT/PATCH /alerts/:id

Update an existing alert's price targets or settings.

Request Body:

{
  "alert": {
    "new_price": "22.99",
    "active": true
  }
}
DELETE /alerts/:id

Deactivate an alert (sets active: false). Alerts are not permanently deleted.

How Alerts Work:
  • • Alerts are automatically checked when prices are updated
  • • You'll receive an email notification when your target price is reached
  • • Alerts can be set for new books, used books, or both
Alert Limitations:
  • • One alert per product per user (creating duplicate updates existing)
  • • Alerts require at least one price target (new_price or used_price)
  • • Alerts are region-specific based on user's default region
  • • Price checking frequency varies based on alert activity

Works & Series

Reading a work or series is public. Editing one is not: creating works and series, merging works, moving editions between them, classifying, and attaching external identifiers all exist under the same paths and require the data:write scope on an editor account.

GET /works/:id Public

Get details about a work and all its editions/products.

GET /series/:id Public

Get details about a series and all its constituent works.

Not documented here yet

These endpoints exist and are live, but aren't written up on this page. Ask us if you need one: work and series writes (POST /works, PATCH /works/:id, POST /works/:id/merge, POST /works/:id/detach_products, PATCH /works/:id/classify, PATCH /works/:id/external_ids, set memberships, POST /series, series_works), contributions, prices, promotions, imports, and the editor-only admin/ endpoints.

Rate Limits

General API Limits

Per Second

1

request per second

Per Hour

100

requests per hour

Per Day

1,000

requests per day

Special Endpoint Limits

Token Exchange

  • 10 requests per minute
  • Applies to POST /api/tokens/exchange
  • Use JWT caching to avoid hitting this limit

Alert Updates

  • 1 update per second (per product)
  • 3 updates per hour (per product)
  • 20 updates per day (per product)
  • Security measure to prevent abuse

JWT Token Benefits

  • • Rate limits embedded in token (no database lookups)
  • • 30-minute lifespan with automatic refresh
  • • Best performance for high-volume applications

Rate Limit Response

When rate limits are exceeded, you'll receive a 429 Too Many Requests response with details about the limit that was exceeded.

Need Higher Limits?

Contact Booko to discuss higher rate limits for your application's needs.

Error Responses

Error Format:

{
  "errors": [
    {
      "type": "error",
      "code": "not_found",
      "detail": "Product with ID '123' not found"
    }
  ]
}

400 Bad Request

Invalid request format or parameters

401 Unauthorized

Authentication required or invalid

403 Forbidden

Insufficient permissions

404 Not Found

Resource does not exist

Changelog

Notable changes to the API. Entries are tagged with the version they affect — v1 and v2 remain in service for existing clients.

10 August 2026

  • v3 DVDs are searchable. ptype=video now has a search index behind it. Previously the only discs search could reach were ones attached to a work; standalone editions were in no index at all and could not be found however you asked.
  • v1 v2 Search honours the product type again. /products/search read only query_type, so a request filtering on any other spelling was silently unfiltered and came back with books. It now accepts query_type, ptype and product_type alike, as either the type name (video) or its id (2).
  • v1 stale_details? can now go false. The field answers "is it worth asking for this product again", rather than reporting staleness no client could ever clear. Fetching a product also queues the detail lookup, so polling gets somewhere.
  • v1 New field image_url_jxl on product responses — the same cover in JPEG XL at the largest rendition we hold. Prefer it if you can decode it and fall back to image_url.
  • v3 A request may name its own region. A signed API request asking for prices in a given region gets that region, instead of having it second-guessed by the caller's geolocation.

Need Help?

For support, questions, or to request editor permissions for product management, contact the Booko team.