Skip to main content

⚠️ API in active development

The API v3 is currently in beta, if you encounter any issue or have questions, please reach out to our support team at [email protected].

Content API v3

Introduction

The Content API v3 is a lightweight, cursor-paginated feed of a store's catalog, optimized for fast, flexible, and bandwidth-efficient integrations. By combining the filter, include, and fields parameters you can shape the payload to match exactly what your integration needs:

  • Trim columnsfields=id,name,cover_url returns only three attributes per item.
  • On-demand blocksinclude=prices adds the active prices.
  • Combine bothinclude=prices,description&fields=id,name,description,prices for a compact object ready to render.

This "shape your data" approach lowers bandwidth, speeds up responses, and avoids client-side post-processing.


Authentication

HeaderExampleDescription
X-User-Tokensk_live_abc123API-Key generated in your dashboard. Only accepts tokens via header for security.

All requests must be performed over HTTPS.


Endpoint

GET /api/v3/content

Query Parameters

ParameterTypeDescription
filter[query]stringSearch by title/name.
filter[external_id]stringExact match search by external_id/ISBN-13.
per_pageintegerItems per page (1-500, default 100).
cursorstringCursor token returned by links.next / links.prev.
includestringComma-separated includes: prices, description.
fieldsstringComma-separated list of fields to return.

Response Structure

Core object (always present):

{
"id": 468166,
"external_id": "9781496822482",
"name": "Conversations with Donald Hall",
"slug": "conversations-with-donald-hall",
"lang": "en",
"file_type": "epub",
"cover_url": "https://.../468166.jpg",
"reader_url": "https://.../read/...",
"product_url": "https://.../book/...",
"created_at": "2021-03-19T00:00:00Z",
"published_at": "2019-09-13T00:00:00Z",
"license": "retail",
"free": {
"enabled": false,
"until": "2025-12-12T00:00:00Z",
"require_login": false
},
"preview": {
"enabled": true,
"require_login": false
}
}

Optional Includes

When requested via include parameter:

Prices Block

{
"prices": [
{
"currency_id": "USD",
"amount": 9.99
},
{
"currency_id": "EUR",
"amount": 8.50
}
]
}

Description Block

{
"description": "A comprehensive collection of interviews with Donald Hall..."
}

Response Wrapper

{
"data": [ /* core ± extras */ ],
"links": {
"next": "https://.../content?cursor=abc123&per_page=100",
"prev": null
},
"meta": {
"has_more": true
}
}

Field Reference

Core Fields

FieldTypeDescription
idintegerUnique issue identifier
external_idstringISBN-13 or external reference
namestringPublication title
slugstringURL-friendly identifier
langstringLanguage code
file_typestringContent type: pdf, epub, audio, physical
audiencestringTarget audience
cover_urlstringCover image URL
reader_urlstringDirect reader link
product_urlstringStorefront product page
created_atstringIssue creation date (ISO 8601)
published_atstringPublication date (ISO 8601)
licensestringLicense type: retail, ppu, shared, owner
freeobjectFree access information
previewobjectPreview access information

Free Access Object

FieldTypeDescription
enabledbooleanWhether free access is available
untilstringFree access expiration date
require_loginbooleanWhether login is required for free access

Preview Object

FieldTypeDescription
enabledbooleanWhether preview is available
require_loginbooleanWhether login is required for preview

Pagination Workflow

  1. Perform the initial request without cursor.
  2. Store the links.next token (if any) and display the current page.
  3. To fetch the next batch, send cursor=<token>.
  4. Continue until links.next is null or meta.has_more is false.
Best practice

Always rely on meta.has_more rather than counting items to detect the end of the catalog.


Error Handling

Validation Errors (422)

Invalid parameters return 422 Unprocessable Entity:

{
"message": "The given data was invalid.",
"errors": {
"filter.unknown_key": ["The selected filter.unknown_key is invalid."],
"per_page": ["The per page must be between 1 and 500."]
}
}

Invalid Includes (422)

Invalid include parameters return 422 Unprocessable Entity:

{
"message": "Requested include(s) are not allowed. Allowed include(s) are: prices, description"
}

Authentication Errors (401)

Missing or invalid authentication:

{
"message": "Unauthenticated."
}

Examples

Minimal request

GET /api/v3/content?filter[query]=harry&per_page=100 HTTP/1.1
Host: {store_final_domain}
X-User-Token: sk_live_xxx

Selective fields and includes

GET /api/v3/content?include=prices,description&fields=id,name,description,prices&per_page=100 HTTP/1.1
Host: {store_final_domain}
X-User-Token: sk_live_xxx

Search by ISBN

GET /api/v3/content?filter[external_id]=9781496822482 HTTP/1.1
Host: {store_final_domain}
X-User-Token: sk_live_xxx

OpenAPI Specification

Download the machine-readable contract at content_v3.yml.


See Also

X

Graph View