Update Content
Modify existing content items. Update metadata, pricing, access settings, files, or any other content attributes.
Endpoint
PUT /api/v3/content/{content_id}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
content_id | string | Content internal ID or external ID |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
id_type | string | internal | internal for numeric ID, external for external ID |
include | string | - | Comma-separated: prices, description, metadata, geographic_restrictions |
fields | string | - | Comma-separated list of fields to return |
Request Body
All fields are optional. Only include fields you want to update. Omitted fields are left unchanged.
All array and object fields use full replacement semantics. When you include an array field in the request, it replaces all existing values — including when you send an empty array [], which removes all existing values for that field.
For example, sending "keywords": [] will clear all keywords from the content item. Only include array fields you intend to update.
Core Fields
| Field | Type | Description |
|---|---|---|
name | string | Content title (max 255 chars) |
description | string | Full content description (HTML allowed) |
published_at | string | Publication date (YYYY-MM-DD only) |
lang | string | Language code |
audience | string | Target audience |
subtitle | string | Content subtitle (max 255 chars) |
publication_place | string | Place of publication (max 255 chars) |
edition_year | integer | Edition year (4 digits, e.g., 2025) |
File Update
| Field | Type | Description |
|---|---|---|
file | string | Storage path to new content file (mutually exclusive with file_url) |
file_url | string | External URL for new content file (mutually exclusive with file) |
cover | string | Storage path to new cover image (mutually exclusive with cover_url) |
cover_url | string | External URL for new cover (mutually exclusive with cover) |
file_url/cover_url: Provide a publicly accessible URL. The platform will download the file automatically.file/cover: Provide a storage path from SFTP upload. Contact support to enable SFTP access for your account.
When you update a content file, the platform creates a new version of the file. Previous versions are retained internally. The content will be re-processed after the file update, and the conversion_status will change to reflect the processing state. Only PDF and EPUB content types support file updates. For audiobooks, use the Audiobook Tracks API to manage audio files.
The replacement file must match the original content type. For example, you cannot replace a PDF with an EPUB. To change the content type, delete and recreate the content item.
Pricing
| Field | Type | Description |
|---|---|---|
prices | array | Complete price array (replaces all prices) |
The prices array replaces all existing prices. Include all currencies you want to keep. Sending an empty array [] removes all prices.
Prices support starts_at and ends_at fields for scheduled pricing: [{currency_id, amount, starts_at, ends_at}]. Dates should be in YYYY-MM-DD format.
Access Settings
| Field | Type | Description |
|---|---|---|
free | boolean | Enable/disable free access |
free_until | string|null | Free access expiration (YYYY-MM-DD or null to remove) |
require_login | boolean | Require login for free access |
preview | boolean | Enable/disable preview |
preview_require_login | boolean | Require login for preview |
Marketplace
| Field | Type | Description |
|---|---|---|
show_in_marketplace | boolean | Make content available in the Publica.la marketplace. When true, the content is listed for other tenants to discover and add to their stores. Send false to remove from marketplace. |
Metadata
| Field | Type | Description |
|---|---|---|
author | array | Author names (replaces all, max 200 chars each) |
publisher | array | Publisher names (replaces all, max 200 chars each) |
keywords | array | Keywords (replaces all, max 200 chars each) |
bisac | array | BISAC codes (replaces all, max 4 codes) |
category | array | Category names (replaces all, max 200 chars each) |
collection | array | Collection names (replaces all, max 200 chars each) |
country | array | Country names (replaces all, max 200 chars each) |
edition | array | Edition names (replaces all, max 200 chars each) |
narrator | array | Narrator names (replaces all, max 200 chars each) |
publishing_group | array | Publishing group names (replaces all, max 200 chars each) |
custom_metadata | object | Custom taxonomy groups: {"group_slug": ["value1"]}. Sending {"group_slug": []} clears that group |
share_with_tenants_ids | array | Tenant IDs (strings) to share this content with. See Content Sharing |
format_group_ids | array | Format group IDs (strings) to associate this content with |
Geographic Restrictions
| Field | Type | Description |
|---|---|---|
geographic_restrictions | object|null | {included: [...], excluded: [...]} or null to remove |
Identifiers
| Field | Type | Description |
|---|---|---|
identifiers | array | Array of identifier objects (replaces all, max 20) |
identifiers[].type | string | Identifier type: isbn_digital, isbn_printed, uuid, ddc, external_id |
identifiers[].value | string | Identifier value (max 255 chars). Validated per type (e.g., ISBN-10/ISBN-13 checksum) |
identifiers[].is_primary | boolean | Mark as primary identifier (optional, defaults to false) |
The identifiers array uses full replacement semantics, just like other array fields. Sending "identifiers": [] will remove all identifiers and clear external_id. Only include identifiers you want to keep. Omitting identifiers from the request preserves existing identifiers unchanged.
Types isbn_digital, isbn_printed, uuid, and external_id require tenant-level uniqueness — two content items cannot share the same identifier of these types, regardless of which is primary. Only one identifier can be marked as primary. If none is marked, the first one is auto-promoted.
Physical Product Fields
| Field | Type | Description |
|---|---|---|
binding_type | string | Binding type |
pages | integer | Number of pages |
height | float | Height in cm |
width | float | Width in cm |
weight | float | Weight in grams |
stock | boolean | In stock status |
editing_location | string | Editing/printing location |
thickness | float | Thickness in cm (min: 0) |
Request Examples
Update Basic Information
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Book Title",
"description": "<p>Updated description with more details...</p>"
}'
Update by External ID
curl -X PUT "https://yourstore.publica.la/api/v3/content/9781234567890?id_type=external" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"name": "Revised Edition",
"published_at": "2025-01-15"
}'
Update Pricing
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"prices": [
{ "currency_id": "USD", "amount": 24.99 },
{ "currency_id": "EUR", "amount": 21.99 },
{ "currency_id": "GBP", "amount": 19.99 }
]
}'
Enable Free Access
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"free": true,
"free_until": "2025-06-30",
"require_login": true
}'
Disable Free Access
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"free": false,
"free_until": null
}'
Update Metadata
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"author": ["Jane Smith", "John Doe"],
"publisher": ["New Publisher Name"],
"keywords": ["updated", "keywords", "list"],
"bisac": [
{ "code": "FIC000000" },
{ "code": "FIC019000" }
]
}'
Update Cover Image
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"cover_url": "https://example.com/new-cover.jpg"
}'
Replace Content File
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"file_url": "https://example.com/files/updated-book-v2.pdf"
}'
Replace Content File via SFTP
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"file": "uploads/updated-book-v2.pdf"
}'
Update Identifiers
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"identifiers": [
{ "type": "isbn_digital", "value": "978-0-306-40615-7", "is_primary": true },
{ "type": "ddc", "value": "823.914" }
]
}'
Update Geographic Restrictions
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"geographic_restrictions": {
"included": ["US", "CA", "GB"],
"excluded": []
}
}'
Remove Geographic Restrictions
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"geographic_restrictions": null
}'
Update Physical Product
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"stock": true,
"pages": 380,
"weight": 520
}'
Combined Update
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166?include=prices,metadata" \
-H "X-User-Token: your-api-token" \
-H "Content-Type: application/json" \
-d '{
"name": "Complete Updated Title",
"description": "<p>Fully revised and updated edition...</p>",
"published_at": "2025-02-01",
"prices": [
{ "currency_id": "USD", "amount": 29.99 }
],
"author": ["Updated Author"],
"keywords": ["revised", "updated", "2025"],
"preview": true
}'
Response
Success Response (200 OK)
{
"data": {
"id": "468166",
"external_id": "9781234567890",
"name": "Updated Book Title",
"slug": "updated-book-title",
"lang": "en",
"file_type": "pdf",
"audience": "adult",
"subtitle": null,
"publication_place": null,
"edition_year": 2025,
"cover_url": "https://cdn.publica.la/covers/468166.jpg",
"reader_url": "https://yourstore.publica.la/reader/updated-book-title",
"product_url": "https://yourstore.publica.la/library/publication/updated-book-title",
"created_at": "2021-03-19T00:00:00.000000Z",
"updated_at": "2025-12-23T14:30:00.000000Z",
"published_at": "2025-01-15T00:00:00.000000Z",
"license": "retail",
"free": {
"enabled": false,
"until": null,
"require_login": false
},
"preview": {
"enabled": true,
"require_login": false
},
"conversion_status": "done",
"identifiers": []
}
}
When updating content files, the response will show an updated conversion_status. Use Get Content to poll for processing completion, just as you would after creating new content.
Response with Includes
{
"data": {
"id": "468166",
"external_id": "9781234567890",
"name": "Updated Book Title",
"slug": "updated-book-title",
"lang": "en",
"file_type": "pdf",
"audience": "adult",
"subtitle": null,
"publication_place": null,
"edition_year": 2025,
"cover_url": "https://cdn.publica.la/covers/468166.jpg",
"reader_url": "https://yourstore.publica.la/reader/updated-book-title",
"product_url": "https://yourstore.publica.la/library/publication/updated-book-title",
"created_at": "2021-03-19T00:00:00.000000Z",
"updated_at": "2025-12-23T14:30:00.000000Z",
"published_at": "2025-01-15T00:00:00.000000Z",
"license": "retail",
"free": {
"enabled": false,
"until": null,
"require_login": false
},
"preview": {
"enabled": true,
"require_login": false
},
"conversion_status": "done",
"prices": [{ "currency_id": "USD", "amount": 29.99 }],
"description": "<p>Fully revised and updated edition...</p>",
"publisher": ["New Publisher Name"],
"author": ["Updated Author"],
"bisac": [{ "code": "FIC000000", "label": "Fiction > General" }],
"keywords": ["revised", "updated", "2025"],
"country": [],
"edition": [],
"narrator": [],
"publishing_group": [],
"thema": [],
"series": [],
"category": [],
"collection": [],
"metrics": {
"total_pages": 320,
"total_words": 85000,
"total_seconds": 0
},
"custom_metadata": {},
"geographic_restrictions": null,
"identifiers": [
{
"type": "isbn_digital",
"value": "978-0-306-40615-7",
"is_primary": true
}
]
}
}
Error Handling
Content Not Found (404)
{
"message": "Content not found."
}
Validation Errors (422)
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name may not be greater than 255 characters."],
"prices.0.currency_id": ["The selected prices.0.currency_id is invalid."]
}
}
Duplicate Identifier (422)
{
"message": "The given data was invalid.",
"errors": {
"identifiers.0.value": [
"This isbn_digital identifier is already in use as primary for another content."
]
}
}
Authentication Error (401)
{
"message": "Unauthenticated."
}
Common Error Causes
| Error | Cause |
|---|---|
| Content not found | Invalid ID or wrong id_type |
| Duplicate identifier | Another content has this identifier as primary |
| Invalid currency | Currency code not in system |
| Invalid BISAC code | BISAC code doesn't exist |
| File URL inaccessible | Cannot download from provided URL |
| Invalid date format | Date not in YYYY-MM-DD or ISO 8601 format |
| File update not allowed | File updates only supported for PDF and EPUB content types |
Best Practices
1. Use Partial Updates
Only include fields you're changing:
// Good - minimal payload
{ "name": "New Title" }
// Avoid - unnecessary fields
{
"name": "New Title",
"description": "Same description",
"prices": [...],
"author": [...]
}
2. Retrieve Before Update
For complex updates, get current state first:
# Get current prices
curl -X GET "https://yourstore.publica.la/api/v3/content/468166?include=prices"
# Then update with new price added
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166" \
-d '{ "prices": [existing_prices + new_price] }'
3. Use Include for Verification
Request includes in response to verify update:
curl -X PUT "https://yourstore.publica.la/api/v3/content/468166?include=prices,metadata" \
-d '{ "prices": [...], "author": [...] }'
See Also
- Get Content - Retrieve content details
- Delete Content - Remove content
- Create Content - Add new content
- Overview - API overview