> ## Documentation Index
> Fetch the complete documentation index at: https://galejames.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cache book details for faster performance

> Use ETag and Cache-Control headers to cache book details and reduce unnecessary API calls.

You can use `GET /v2/books/{bookId}` endpoint to return `ETag` and `Cache-Control` headers you need to cache book details and reduce unnecessary API calls.

## Prerequisites

Before you begin, ensure you meet the following prerequisites:

* Familiarity with BookHub Publisher API v2.
* A valid JWT for authentication.
* A `bookId` for the book whose details you want to cache. In Python examples, the `bookId` is assigned to a `book_id` variable following Python naming conventions. When you create a book (`POST /v2/books`), it create a `bookId` and displays it in the `201 Created` response. If you don't know the `bookId`, you can find it using the (`GET /v2/books`).
* Access to your codebase that integrates with the BookHub Publisher API v2.

## Step 1: Make an initial request

Send a `GET` request to retrieve book details. The response includes an `ETag` header with a unique identifier for the current version of the resource, and a `Cache-Control` header indicating how long the response can be cached.

> [!NOTE]
>
> The examples in this document use `123e4567-e89b-41d4-a716-426614174000`) as the `bookId` in the cURL examples and `book_id` in the Python examples.

```python theme={null}
import requests

BASE_URL = "https://api.bookhub.com/api"
TOKEN = "YOUR_JWT_TOKEN"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}

response = requests.get(
    f"{BASE_URL}/v2/books/123e4567-e89b-41d4-a716-426614174000",
    headers=HEADERS
)
response.raise_for_status()
etag = response.headers.get('ETag')
book_data = response.json()['data']
```

### Response headers

```bash theme={null}
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Cache-Control: max-age=3600, must-revalidate
```

## Step 2: Use `ETag` for conditional requests

For subsequent requests, include the `If-None-Match` header with the `ETag` value from Step 1. If the book details haven't changed, the server returns `304 Not Modified`. `304` means use your stored data. If they have changed, the server returns a `200 OK` with updated details.

```python theme={null}
response = requests.get(
    f"{BASE_URL}/v2/books/123e4567-e89b-41d4-a716-426614174000",
    headers={**HEADERS, 'If-None-Match': etag}
)

if response.status_code == 304:
    print("Data unchanged, using cache")
else:
    response.raise_for_status()
    book_data = response.json()['data']
```

## Step 3: Test your implementation

Send an initial request and store the `ETag`; then send a second conditional request with the `ETag` from the initial request, including the `If-None-Match` header. Confirm the second request returns `304 Not Modified` if the book details haven't changed.

### Initial request

```bash theme={null}
curl -X GET "https://api.bookhub.com/api/v2/books/123e4567-e89b-41d4-a716-426614174000" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -v
```

### Conditional request

```bash theme={null}
curl -X GET "https://api.bookhub.com/api/v2/books/123e4567-e89b-41d4-a716-426614174000" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H 'If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"'
```

The second request should return `304 Not Modified` if the book details haven't changed.

## Response

A `304 Not Modified` response returns no headers beyond the standard HTTP response headers — no body is returned. The `Cache-Control: max-age=3600, must-revalidate` header in the initial response means the cached data is valid for 3600 seconds (one hour). After expiry, the cache must revalidate with the server before serving the cached response.

A `200 OK` response returns updated book details:

```json theme={null}
{
  "status": "success",
  "data": {
    "bookId": "123e4567-e89b-41d4-a716-426614174000",
    "title": "The Great Adventure",
    "author": "Jane Smith",
    "description": "An epic tale of courage and discovery",
    "language": "en-US",
    "publisher": "Adventure Books Inc",
    "publishedDate": "2024-03-15",
    "isbn": "978-0-1234-5678-9",
    "price": 24.99,
    "status": "ACTIVE",
    "coverImages": [
      "https://covers.bookhub.com/great-adventure-front.jpg"
    ],
    "genres": [
      "Fiction",
      "Adventure"
    ],
    "bookFormat": "Hardcover",
    "createdDate": "2024-12-25T10:30:00Z",
    "updatedDate": "2024-12-26T15:45:00Z",
    "hitCount": 1247
  }
}
```

### Error handling

| Code | Cause | Resolution |
| - | - | - |
| `401` | Unauthorized (for example, a missing or invalid JWT) | If you receive a `401`, check your JWT and try again. |
| `404` | Not found (for example, `bookId` does not exist) | If you receive a `404`, check your `bookId` or `book_id` and try again. |
| `429` | Rate limit exceeded (for example, 150 requests per minute) | Wait until the time in the `X-RateLimit-Reset` header, then retry. See [Monitor rate limits](/how-to-guides/how-to-guides-monitor-rate-limits). |

## Next steps

Explore related topics:

### How-to guides

* [Handle pagination](/how-to-guides/how-to-guides-handle-pagination) — Manage large result sets when retrieving all books.
* [Rank books by hitCount to find top performers](/how-to-guides/how-to-guides-use-hitcount-to-track-book-performance) — Use the `hitCount` field to rank books by buyer interest and flag your top performers.

### Reference

* [Get a specific book](/reference/reference-api-endpoints#get-a-specific-book) — Explore all available API endpoints and their parameters for BookHub Publisher API v2.
* [Data models](/reference/reference-data-models) — Explore schema definitions for BaseBook, BookWithAnalytics, Pagination, and Error response objects in the BookHub Publisher API v2.

***


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.