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

# List Content

Retrieve a paginated list of your store's catalog with powerful filtering, sorting, and response shaping capabilities.

## Endpoint

```
GET /api/v3/content
```

---

## Query Parameters

### Pagination

| Parameter  | Type    | Default | Description                                    |
| ---------- | ------- | ------- | ---------------------------------------------- |
| `per_page` | integer | 100     | Items per page (1-500)                         |
| `cursor`   | string  | -       | Cursor token from `links.next` or `links.prev` |

### Includes

| Parameter | Type   | Description                                                                     |
| --------- | ------ | ------------------------------------------------------------------------------- |
| `include` | string | Comma-separated: `prices`, `description`, `metadata`, `geographic_restrictions` |

### Fields Selection

| Parameter | Type   | Description                              |
| --------- | ------ | ---------------------------------------- |
| `fields`  | string | Comma-separated list of fields to return |

### Sorting

| Parameter | Type   | Default         | Description                                |
| --------- | ------ | --------------- | ------------------------------------------ |
| `sort`    | string | `-published_at` | Sort field. Prefix with `-` for descending |

**Allowed sort fields:** `created_at`, `updated_at`

### Filters

| Parameter             | Type   | Description                                                                                                   |
| --------------------- | ------ | ------------------------------------------------------------------------------------------------------------- |
| `filter[query]`       | string | Search by title/name                                                                                          |
| `filter[id]`          | string | Filter by internal ID                                                                                         |
| `filter[external_id]` | string | **Deprecated.** Filter by external ID. Use `filter[identifier]` instead.                                      |
| `filter[file_type]`   | string | Filter by content type: `pdf`, `epub`, `audio`, `physical`                                                    |
| `filter[author]`      | string | Filter by author slug                                                                                         |
| `filter[audience]`    | string | Filter by target audience                                                                                     |
| `filter[language]`    | string | Filter by 2-letter language code (e.g., `en`, `es`)                                                           |
| `filter[free_issues]` | flag   | Present to filter free content only (no value needed)                                                         |
| `filter[discounted]`  | flag   | Present to filter discounted content only (no value needed)                                                   |
| `filter[identifier]`  | string | Search by identifier value (normalized: all non-alphanumeric characters are stripped and value is lowercased) |

### Date Range Filters

| Parameter                  | Type     | Format                | Description                      |
| -------------------------- | -------- | --------------------- | -------------------------------- |
| `filter[created_at][from]` | datetime | `YYYY-MM-DD HH:mm:ss` | Content created after this date  |
| `filter[created_at][to]`   | datetime | `YYYY-MM-DD HH:mm:ss` | Content created before this date |
| `filter[updated_at][from]` | datetime | `YYYY-MM-DD HH:mm:ss` | Content updated after this date  |
| `filter[updated_at][to]`   | datetime | `YYYY-MM-DD HH:mm:ss` | Content updated before this date |

:::info Date Range Rules

- `updated_at.from` must be within the last month
- `updated_at.to` cannot be a future date
- `created_at.from` can point to any past date
- `created_at.to` cannot be a future date
- `created_at` range between `from` and `to` must not exceed 1 month
  :::

---

## Response Structure

### Core Object

Always present in the response:

```json
{
  "id": "468166",
  "external_id": "9781496822482",
  "name": "Conversations with Donald Hall",
  "slug": "conversations-with-donald-hall",
  "lang": "en",
  "file_type": "epub",
  "audience": "adult",
  "subtitle": "Interviews spanning five decades",
  "publication_place": "Jackson, MS",
  "edition_year": 2019,
  "cover_url": "https://.../468166.jpg",
  "reader_url": "https://.../read/...",
  "product_url": "https://.../library/publication/...",
  "created_at": "2021-03-19T00:00:00Z",
  "updated_at": "2025-12-03T15:30: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
  },
  "subscribers_only": false,
  "conversion_status": "done",
  "identifiers": [
    {
      "type": "isbn_digital",
      "value": "978-1-496-82248-2",
      "is_primary": true
    }
  ]
}
```

:::info Identifiers Always Included
The `identifiers` array is always present in every response. You do not need to request it via the `include` parameter. See [Get Content - Identifiers](./content-v3-get.md#identifiers-always-included) for the full field reference and supported types.
:::

:::info Physical Stock
Items with `file_type: physical` also carry `stock_quantity` (and the deprecated `stock`), without needing an `include`. See [Get Content - Physical Stock](./content-v3-get.md#physical-stock-physical-content-only).
:::

### Optional Includes

#### Prices Block (`include=prices`)

```json
{
  "prices": [
    {
      "currency_id": "USD",
      "amount": 9.99
    },
    {
      "currency_id": "EUR",
      "amount": 8.5
    }
  ]
}
```

#### Description Block (`include=description`)

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

#### Metadata Block (`include=metadata`)

```json
{
  "publisher": ["Vintage"],
  "author": ["Jane Doe"],
  "bisac": [
    { "code": "FIC019000", "label": "Fiction > Literary" },
    { "code": "FIC000000", "label": "Fiction > General" }
  ],
  "keywords": ["fiction", "literary", "contemporary"],
  "country": ["United States"],
  "edition": ["First Edition"],
  "narrator": [],
  "publishing_group": [],
  "thema": ["FBA"],
  "series": [],
  "category": ["Fiction"],
  "collection": ["Summer Reading"],
  "metrics": {
    "total_pages": 320,
    "total_words": 85000,
    "total_seconds": 0
  },
  "custom_metadata": {
    "genre": ["Literary Fiction", "Contemporary"],
    "reading_level": ["Advanced"]
  }
}
```

#### Geographic Restrictions Block (`include=geographic_restrictions`)

Indicates which countries can sell or access the content based on territorial rights.

**Possible Values:**

- **`null`**: No restrictions, content is available worldwide
- **Object with `included` and `excluded` arrays**: Territorial rights information

**No restrictions (worldwide):**

```json
{
  "geographic_restrictions": null
}
```

**Whitelist (available only in specific countries):**

```json
{
  "geographic_restrictions": {
    "included": ["AR", "CL", "UY"],
    "excluded": []
  }
}
```

**Blacklist (worldwide except specific countries):**

```json
{
  "geographic_restrictions": {
    "included": ["WORLD"],
    "excluded": ["US", "CA"]
  }
}
```

### Response Wrapper

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

---

## Field Reference

### Core Fields

| Field               | Type    | Description                                                                                                                  |
| ------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `id`                | string  | Unique issue identifier (numeric as string)                                                                                  |
| `external_id`       | string  | **Deprecated.** Synced from primary identifier value. Use `identifiers` instead.                                             |
| `name`              | string  | Publication title                                                                                                            |
| `slug`              | string  | URL-friendly identifier                                                                                                      |
| `lang`              | string  | Language code                                                                                                                |
| `file_type`         | string  | Content type: `pdf`, `epub`, `audio`, `physical`                                                                             |
| `updated_at`        | string  | ISO 8601 last update timestamp                                                                                               |
| `audience`          | string  | Target audience                                                                                                              |
| `subtitle`          | string  | Content subtitle                                                                                                             |
| `publication_place` | string  | Place of publication                                                                                                         |
| `edition_year`      | integer | Edition year (4 digits)                                                                                                      |
| `cover_url`         | string  | Cover image URL                                                                                                              |
| `reader_url`        | string  | Direct reader link                                                                                                           |
| `product_url`       | string  | Storefront product page                                                                                                      |
| `created_at`        | string  | ISO 8601 creation timestamp                                                                                                  |
| `published_at`      | string  | ISO 8601 publication date                                                                                                    |
| `license`           | string  | License type: `retail`, `shared`, `owner`                                                                                    |
| `free`              | object  | Free access information                                                                                                      |
| `preview`           | object  | Preview access information                                                                                                   |
| `subscribers_only`  | boolean | Whether content is restricted to subscribers (see [Subscribers-Only Access](./content-v3-create.md#subscribers-only-access)) |
| `conversion_status` | string  | File processing status (see [Conversion Status](./content-v3-create.md#conversion-status))                                   |

### Free Access Object

| Field           | Type    | Description                               |
| --------------- | ------- | ----------------------------------------- |
| `enabled`       | boolean | Whether free access is available          |
| `until`         | string  | Free access expiration date               |
| `require_login` | boolean | Whether login is required for free access |

### Preview Object

| Field           | Type    | Description                           |
| --------------- | ------- | ------------------------------------- |
| `enabled`       | boolean | Whether preview is available          |
| `require_login` | boolean | Whether login is required for preview |

---

## Examples

### Basic List

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content" \
  -H "X-User-Token: your-api-token" \
  -H "Accept: application/json"
```

### With Includes

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?include=prices,description" \
  -H "X-User-Token: your-api-token"
```

### Search by Title

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?filter[query]=harry" \
  -H "X-User-Token: your-api-token"
```

### Search by Identifier

Search across all identifier types. All non-alphanumeric characters are stripped automatically, so `978-0-306-40615-7` and `9780306406157` match the same content.

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?filter[identifier]=9780306406157" \
  -H "X-User-Token: your-api-token"
```

### Sparse Fieldsets

```bash
# Only return id, name, and cover_url
curl -X GET "https://yourstore.publica.la/api/v3/content?fields=id,name,cover_url" \
  -H "X-User-Token: your-api-token"
```

### Selective Fields with Includes

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?include=prices&fields=id,name,prices" \
  -H "X-User-Token: your-api-token"
```

### Incremental Sync (Updated Content)

```bash
# Content updated in the last 7 days
curl -X GET "https://yourstore.publica.la/api/v3/content?filter[updated_at][from]=2024-12-25 00:00:00&filter[updated_at][to]=2024-12-31 23:59:59" \
  -H "X-User-Token: your-api-token"
```

### Filter by Creation Date

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?filter[created_at][from]=2024-01-01 00:00:00&filter[created_at][to]=2024-12-31 23:59:59" \
  -H "X-User-Token: your-api-token"
```

### Sort by Update Date

```bash
# Newest updates first
curl -X GET "https://yourstore.publica.la/api/v3/content?sort=-updated_at" \
  -H "X-User-Token: your-api-token"

# Oldest first
curl -X GET "https://yourstore.publica.la/api/v3/content?sort=created_at" \
  -H "X-User-Token: your-api-token"
```

### Get Geographic Restrictions

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?include=geographic_restrictions&fields=id,name,geographic_restrictions" \
  -H "X-User-Token: your-api-token"
```

### Combined Filters

```bash
curl -X GET "https://yourstore.publica.la/api/v3/content?\
filter[created_at][from]=2024-01-01 00:00:00&\
sort=-updated_at&\
include=prices&\
fields=id,name,created_at,updated_at,prices&\
per_page=50" \
  -H "X-User-Token: your-api-token"
```

### Pagination Flow

```bash
# First page
curl -X GET "https://yourstore.publica.la/api/v3/content?per_page=100" \
  -H "X-User-Token: your-api-token"

# Response includes:
# "links": { "next": "...?cursor=eyJjcmVhdGVkX2F0IjoiMjAyNC0xMi0wMyAxMDoxMDowNCIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0" }

# Next page
curl -X GET "https://yourstore.publica.la/api/v3/content?per_page=100&cursor=eyJjcmVhdGVkX2F0..." \
  -H "X-User-Token: your-api-token"
```

---

## Error Handling

### Validation Errors (422)

```json
{
  "message": "The given data was invalid.",
  "errors": {
    "filter.unknown_key": ["The selected filter.unknown_key is invalid."],
    "filter.created_at.from": [
      "The filter.created_at.from field must match the format Y-m-d H:i:s."
    ],
    "per_page": ["The per page must be between 1 and 500."]
  }
}
```

### Invalid Includes (422)

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

### Authentication Errors (401)

```json
{
  "message": "Unauthenticated."
}
```

---

## Best Practices

1. **Use `per_page` wisely** - Higher values reduce API calls but increase payload size
2. **Always check `meta.has_more`** - Don't assume based on item count
3. **Use `fields` parameter** - Reduce payload size by requesting only needed fields
4. **Cache cursor tokens** - Store the last cursor for resumable syncs
5. **Use incremental sync** - For regular updates, use `updated_at` filter instead of fetching everything

---

## OpenAPI Specification

Download the machine-readable contract: [content_v3.yml](/swagger-ui/content_v3.yml).

---

## See Also

- [Get Content](./content-v3-get.md) - Retrieve single content items
- [Create Content](./content-v3-create.md) - Add new content
- [Overview](./content-v3-overview.md) - API overview and authentication
- [Migration Guide](./content-v3-migration.md) - Upgrading from API v1
