Example: Ebook Upload
End-to-end walkthrough — create an ebook, upload EPUB and cover files, and publish to stores using the PublishDrive Distribution API.
This guide walks through the complete lifecycle of publishing an ebook: creating the book record, uploading the EPUB manuscript and cover image, and publishing to distribution channels. Every request uses curl against the staging environment.
Replace YOUR_API_KEY with your actual API key. All UUIDs and presigned URLs shown here are examples — your responses will contain unique values.
See also: List books, Get a book, Update a book, Upload API primer, Unpublish and delete.
Prerequisites
- A valid PublishDrive API key (request one from support)
- An EPUB file for the ebook content
- A cover image (JPEG or PNG, minimum 1400 × 2100 px recommended)
- SHA-256 hashes of both files
Computing file hashes
shasum -a 256 my-novel.epub
shasum -a 256 cover.jpgFull Flow
Step 1 — Create the book record
Send a POST request to /books with the ebook metadata. Required fields: format, title, language, description, category, copyright, saleTerritory, publicationDate, contributor, and price.
Request
curl -X POST https://api.sandbox.dev.publishdrive.com/v2/distribution/books \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "ebook",
"title": "The Great Adventure",
"subtitle": "A Journey Through Time",
"language": ["en"],
"description": "An epic tale of discovery and wonder spanning three continents and two centuries.",
"category": ["FIC002000", "FIC014000"],
"keyword": ["adventure", "historical fiction", "epic"],
"copyright": "SELF",
"saleTerritory": ["ALL"],
"publicationDate": "2026-06-15",
"contributor": [
{
"firstName": "Jane",
"lastName": "Doe",
"role": "Author"
},
{
"firstName": "John",
"lastName": "Smith",
"role": "Editor"
}
],
"price": [
{ "currency": "USD", "price": 9.99 },
{ "currency": "EUR", "price": 8.99 },
{ "currency": "GBP", "price": 7.99 }
]
}'Response 201 Created
{
"bookId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Save the bookId — you need it for every subsequent call.
Step 2 — Request upload URLs for the EPUB and cover
Send a POST to /books/{bookPublicId}/upload with an array describing each file. Use role ebook_content for the manuscript and ebook_cover for the cover image.
Request
curl -X POST https://api.sandbox.dev.publishdrive.com/v2/distribution/books/a1b2c3d4-e5f6-7890-abcd-ef1234567890/upload \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"referenceId": "epub-ref",
"role": "ebook_content",
"filename": "my-novel.epub",
"hashSha256": "9c50bbd0c11fda120232a970f3ee67f993459bb81fda6f35d7ac4cfa9b45d5f5"
},
{
"referenceId": "cover-ref",
"role": "ebook_cover",
"filename": "cover.jpg",
"hashSha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
}
]'Response 201 Created
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "book-file-upload",
"attributes": {
"referenceId": "epub-ref",
"role": "ebook_content",
"url": "https://s3.amazonaws.com/bucket/presigned-epub-url?...",
"expiresAt": "2026-06-10T12:00:00Z"
}
},
{
"id": "660f9500-f3ac-52e5-b827-557766551111",
"type": "book-file-upload",
"attributes": {
"referenceId": "cover-ref",
"role": "ebook_cover",
"url": "https://s3.amazonaws.com/bucket/presigned-cover-url?...",
"expiresAt": "2026-06-10T12:00:00Z"
}
}
]
}Each item gives you:
id— thefileIdyou will use in the complete and attach stepsurl— the presigned S3 URL toPUTyour file bytes toexpiresAt— deadline for the upload (presigned URLs are time-limited)
Step 3 — Upload file bytes to the presigned URLs
Use HTTP PUT to upload each file directly to its presigned URL. No API key header is needed — the URL itself carries authorization.
Upload the EPUB
curl -X PUT "https://s3.amazonaws.com/bucket/presigned-epub-url?..." \
-H "Content-Type: application/epub+zip" \
--data-binary @my-novel.epubUpload the cover
curl -X PUT "https://s3.amazonaws.com/bucket/presigned-cover-url?..." \
-H "Content-Type: image/jpeg" \
--data-binary @cover.jpgPresigned URLs expire. Upload promptly after requesting them. If one expires, request a new URL with a fresh call to the upload endpoint.
Step 4 — Attach each file to the book
After the bytes are on S3, confirm each upload and link it to the book in one call: PATCH /books/{bookPublicId}/file/{fileId}/attach with the original filename and the same hashSha256 you used when requesting the upload URL. The book will not reference the asset until this call succeeds. If the uploaded bytes do not match the declared hash, the API returns 422.
Attach the EPUB
curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/a1b2c3d4-e5f6-7890-abcd-ef1234567890/file/550e8400-e29b-41d4-a716-446655440000/attach \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "my-novel.epub",
"hashSha256": "9c50bbd0c11fda120232a970f3ee67f993459bb81fda6f35d7ac4cfa9b45d5f5"
}'Attach the cover
curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/a1b2c3d4-e5f6-7890-abcd-ef1234567890/file/660f9500-f3ac-52e5-b827-557766551111/attach \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "cover.jpg",
"hashSha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
}'Response 200 OK (for each)
{}Step 5 — Publish the book
Once metadata and files are complete, send the book to distribution channels.
Request
curl -X POST https://api.sandbox.dev.publishdrive.com/v2/distribution/books/a1b2c3d4-e5f6-7890-abcd-ef1234567890/publish \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'Response 204 No Content
The book is now queued for distribution to all stores enabled in your territory settings.
Verify the book status
After publishing, retrieve the book to confirm its state.
curl -X GET https://api.sandbox.dev.publishdrive.com/v2/distribution/books/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "apikey: YOUR_API_KEY"Quick reference
| Step | Method | Endpoint | Purpose |
|---|---|---|---|
| 1 | POST | /books | Create book record with metadata |
| 2 | POST | /books/{id}/upload | Get presigned URLs for files |
| 3 | PUT | (presigned URL) | Upload raw bytes to S3 |
| 4 | PATCH | /books/{id}/file/{fileId}/attach | Confirm upload and link file to book |
| 5 | POST | /books/{id}/publish | Send to distribution |
Common errors
| Status | Meaning | Fix |
|---|---|---|
401 | Missing or invalid API key | Check the apikey header |
404 | Book or file not found | Verify the bookPublicId or fileId |
409 | Presigned URL already used | Request a new upload URL |
422 | Validation error | Check the detail field in the Problem response for missing/invalid fields |
Example: Upload API primer
Request presigned URLs, confirm bytes on storage, and attach files — compact curl reference with links to full format walkthroughs.
Example: Audiobook Upload
End-to-end walkthrough — create an audiobook, upload audio tracks and cover art, define chapters, and publish to stores using the PublishDrive Distribution API.
