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:
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:
GET /oauth/authorize - Authorization request
POST /oauth/token - Token exchange
POST /oauth/token - Token refresh
Getting Started
Get API Access
Contact Booko to get your API token and access credentials.
Choose Authentication
Use JWT tokens for best performance, or API tokens for simplicity.
Make Your First Request
Try fetching your user info with GET /me
curl -H "Authorization: Bearer your-token" \
https://api.booko.info/api/v3/me
User Information
/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"]
}
}
Search
Search across products, works, and series using our high-performance MeiliSearch integration.
/search
Search for books, works, and series with pagination and filtering. Returns mixed results with relevance scoring.
Query Parameters:
q- Required. Search query stringptype- Product type filter:book,ebook,audiobook,graphic_novel,box_set,video,lego,pop,toy,music,ereader,table_top_game,food_stuff,othertype- Restrict the result kind:workorseries. Omit for mixed resultsper_page- Results per page (max 100, default: 20)page- Page number (default: 1)
ptype takes the type name, singular — an unrecognised value is a
422 whose detail lists the valid set. (The older v1 and v2 search endpoints
also accept the numeric id.)
curl -H "Authorization: Bearer your-token" \
"https://api.booko.info/api/v3/search?q=ruby+programming&ptype=book&per_page=10"
Response Example:
{
"data": [
{
"type": "product",
"id": 123,
"gtin": "9781234567890",
"title": "The Ruby Programming Language",
"subtitle": "Everything You Need to Know",
"author": "Matz Yukihiro",
"publisher": "O'Reilly Media",
"ptype": "book",
"cover_url": "https://covers.booko.info/...",
"search_score": 0.95,
"path": "/products/9781234567890",
"work": {
"id": 456,
"name": "The Ruby Programming Language",
"gtins": ["9781234567890", "9780987654321"]
}
},
{
"type": "work",
"id": 789,
"name": "Programming Ruby",
"author": "Dave Thomas",
"search_score": 0.87,
"path": "/works/789",
"products": [
{
"id": 321,
"gtin": "9785432109876",
"title": "Programming Ruby",
"ptype": "book",
"region": "US"
}
]
}
],
"meta": {
"pagination": {
"page": 1,
"per_page": 10,
"total_hits": 156,
"total_pages": 16,
"has_next_page": true,
"has_previous_page": false
},
"search": {
"query": "ruby programming",
"ptype": "book",
"search_time": 0.045,
"processing_time": 12
}
}
}
Search Features:
- • Mixed Results: Returns products, works, and series in order of relevance
- • Fast Performance: Powered by MeiliSearch for sub-second responses
- • Relevance Scoring: Results include search_score for ranking
- • Efficient Pagination: True pagination without storing results
Result Types:
product- Individual books with GTINs/ISBNs and specific editionswork- Abstract books that group all editions togetherseries- Collections of related works (Harry Potter, etc.)
Search Tips:
- • Use specific terms for better results: "ruby programming" vs "ruby"
- • Filter by ptype to narrow results to specific product types
- • Use pagination for better performance with large result sets
- • Results are ordered by relevance, not alphabetically
Products
Manage individual books and their metadata. Products represent specific editions with GTINs/ISBNs.
/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"]
}
}
/products
Editor Required
/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.
/lists
Get user's lists or public discoverable lists.
Query Parameters:
discoverable=true- Get public listssort_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)
/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 ownersharable- Visible via direct linkdiscoverable- Public and searchable
/lists/:id
/lists/:id
/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.
/lists/:list_id/items
Get all items in a list with pagination.
/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 GTINsWork- All editions of a bookSeries- Complete book series
/lists/:list_id/items/:id
/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.
/alerts
Get user's alerts with filtering and sorting options.
Query Parameters:
active- Filter by active status: true/falsesort- 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
}
}
/alerts/:id
Get details of a specific alert. ID can be alert ID or product GTIN.
/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 booksused_price- Target price for used condition booksinclude_used- Include used books in price checks- Note: At least one of new_price or used_price must be set
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
}
}'
/alerts/:id
Update an existing alert's price targets or settings.
Request Body:
{
"alert": {
"new_price": "22.99",
"active": true
}
}
/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.
/works/:id
Public
Get details about a work and all its editions/products.
/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=videonow 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/searchread onlyquery_type, so a request filtering on any other spelling was silently unfiltered and came back with books. It now acceptsquery_type,ptypeandproduct_typealike, 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_jxlon product responses — the same cover in JPEG XL at the largest rendition we hold. Prefer it if you can decode it and fall back toimage_url. -
v3
A request may name its own region. A signed API request asking for
prices in a given
regiongets 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.