PublishDrive

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.

This guide walks through the complete lifecycle of publishing an audiobook: creating the book record with audio-specific metadata, uploading individual audio tracks and the cover image, wiring tracks to chapters, and publishing. 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)
  • Audio content files (MP3 or M4A/M4B) — one file per chapter
  • A cover image (JPEG or PNG, minimum 2400 × 2400 px, square aspect ratio recommended for audiobooks)
  • SHA-256 hashes of all files

Computing file hashes

shasum -a 256 chapter-01.mp3
shasum -a 256 chapter-02.mp3
shasum -a 256 chapter-03.mp3
shasum -a 256 audiobook-cover.jpg

Full Flow

Step 1 — Create the audiobook record

Send a POST request to /books with format set to audio. Include the audioDetails object for audiobook-specific fields and at least one contributor with a Narrated by role.

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": "audio",
    "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. Narrated by award-winning voice actor James Wilson.",
    "category": ["FIC002000", "FIC014000"],
    "keyword": ["adventure", "historical fiction", "audiobook"],
    "copyright": "SELF",
    "saleTerritory": ["ALL"],
    "publicationDate": "2026-07-01",
    "audioDetails": {
      "audioEdition": "UBR"
    },
    "contributor": [
      {
        "firstName": "Jane",
        "lastName": "Doe",
        "role": "Author"
      },
      {
        "firstName": "James",
        "lastName": "Wilson",
        "role": "Narrated by"
      }
    ],
    "price": [
      { "currency": "USD", "price": 19.99 },
      { "currency": "EUR", "price": 17.99 },
      { "currency": "GBP", "price": 15.99 }
    ]
  }'

Response 201 Created

{
  "bookId": "b2c3d4e5-f6a7-8901-bcde-f23456789012"
}

Save the bookId — every subsequent call needs it.

audioDetails fields

FieldTypeDescription
audioLengthintegerTotal runtime in seconds (e.g. 32400 = 9 hours)
audioEditionstringUBR (unabridged) or ABR (abridged)

Step 2 — Request upload URLs for audio tracks and cover

Send a POST to /books/{bookPublicId}/upload with one entry per file. Use role audio_content for each audio track and audio_cover for the cover image.

Request

curl -X POST https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012/upload \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "referenceId": "ch01",
      "role": "audio_content",
      "filename": "chapter-01.mp3",
      "hashSha256": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
    },
    {
      "referenceId": "ch02",
      "role": "audio_content",
      "filename": "chapter-02.mp3",
      "hashSha256": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3"
    },
    {
      "referenceId": "ch03",
      "role": "audio_content",
      "filename": "chapter-03.mp3",
      "hashSha256": "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4"
    },
    {
      "referenceId": "cover-ref",
      "role": "audio_cover",
      "filename": "audiobook-cover.jpg",
      "hashSha256": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5"
    }
  ]'

Response 201 Created

{
  "data": [
    {
      "id": "11111111-aaaa-bbbb-cccc-111111111111",
      "type": "book-file-upload",
      "attributes": {
        "referenceId": "ch01",
        "role": "audio_content",
        "url": "https://s3.amazonaws.com/bucket/presigned-ch01?...",
        "expiresAt": "2026-07-01T12:00:00Z"
      }
    },
    {
      "id": "22222222-aaaa-bbbb-cccc-222222222222",
      "type": "book-file-upload",
      "attributes": {
        "referenceId": "ch02",
        "role": "audio_content",
        "url": "https://s3.amazonaws.com/bucket/presigned-ch02?...",
        "expiresAt": "2026-07-01T12:00:00Z"
      }
    },
    {
      "id": "33333333-aaaa-bbbb-cccc-333333333333",
      "type": "book-file-upload",
      "attributes": {
        "referenceId": "ch03",
        "role": "audio_content",
        "url": "https://s3.amazonaws.com/bucket/presigned-ch03?...",
        "expiresAt": "2026-07-01T12:00:00Z"
      }
    },
    {
      "id": "44444444-aaaa-bbbb-cccc-444444444444",
      "type": "book-file-upload",
      "attributes": {
        "referenceId": "cover-ref",
        "role": "audio_cover",
        "url": "https://s3.amazonaws.com/bucket/presigned-cover?...",
        "expiresAt": "2026-07-01T12:00:00Z"
      }
    }
  ]
}

Save each id — these are the fileId values you need for the complete, attach, and chapter steps.

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.

Upload Chapter 1

curl -X PUT "https://s3.amazonaws.com/bucket/presigned-ch01?..." \
  -H "Content-Type: audio/mpeg" \
  --data-binary @chapter-01.mp3

Upload Chapter 2

curl -X PUT "https://s3.amazonaws.com/bucket/presigned-ch02?..." \
  -H "Content-Type: audio/mpeg" \
  --data-binary @chapter-02.mp3

Upload Chapter 3

curl -X PUT "https://s3.amazonaws.com/bucket/presigned-ch03?..." \
  -H "Content-Type: audio/mpeg" \
  --data-binary @chapter-03.mp3

Upload the cover

curl -X PUT "https://s3.amazonaws.com/bucket/presigned-cover?..." \
  -H "Content-Type: image/jpeg" \
  --data-binary @audiobook-cover.jpg

Presigned URLs expire. Upload all files promptly after requesting them. If one expires, request a new URL with a fresh call to the upload endpoint.

For audiobooks with many chapters, you can upload multiple files in parallel — each presigned URL is independent.

Step 4 — Attach each file to the book

After the bytes are on S3, confirm each upload and link it to the book with PATCH /books/{bookPublicId}/file/{fileId}/attach using the same filename and hashSha256 you used when requesting URLs.

Attach Chapter 1

curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012/file/11111111-aaaa-bbbb-cccc-111111111111/attach \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "chapter-01.mp3",
    "hashSha256": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
  }'

Attach Chapter 2

curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012/file/22222222-aaaa-bbbb-cccc-222222222222/attach \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "chapter-02.mp3",
    "hashSha256": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3"
  }'

Attach Chapter 3

curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012/file/33333333-aaaa-bbbb-cccc-333333333333/attach \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "chapter-03.mp3",
    "hashSha256": "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4"
  }'

Attach the cover

curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012/file/44444444-aaaa-bbbb-cccc-444444444444/attach \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "audiobook-cover.jpg",
    "hashSha256": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5"
  }'

Response 200 OK (for each)

{}

Step 5 — Define chapters via Update Book

Audiobook chapters are not created by the upload or attach calls. You must explicitly map each audio content file to a chapter by calling PATCH /books/{bookPublicId} with a chapters array.

Each chapter entry requires:

FieldTypeDescription
fileIdUUIDThe fileId of the attached audio content file
sequenceintegerChapter order (1-based); acts as the upsert key
titlestringChapter display title
titleAsciistringASCII-only version of the title (optional, use when title contains non-ASCII characters)

Request

curl -X PATCH https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012 \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chapters": [
      {
        "fileId": "11111111-aaaa-bbbb-cccc-111111111111",
        "sequence": 1,
        "title": "Chapter 1: The Beginning"
      },
      {
        "fileId": "22222222-aaaa-bbbb-cccc-222222222222",
        "sequence": 2,
        "title": "Chapter 2: The Journey"
      },
      {
        "fileId": "33333333-aaaa-bbbb-cccc-333333333333",
        "sequence": 3,
        "title": "Chapter 3: The Arrival"
      }
    ]
  }'

Response 200 OK

{
  "bookId": "b2c3d4e5-f6a7-8901-bcde-f23456789012"
}

Each audio content file must belong to exactly one chapter. Make sure every attached audio content file is assigned to a chapter before publishing.

Step 6 — Publish the audiobook

Once all files are attached and chapters are defined, send the audiobook to distribution.

Request

curl -X POST https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012/publish \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Response 204 No Content

The audiobook is now queued for distribution to all stores enabled in your territory settings.


Verify the audiobook status

After publishing, retrieve the book to confirm its state and chapter assignments.

curl -X GET https://api.sandbox.dev.publishdrive.com/v2/distribution/books/b2c3d4e5-f6a7-8901-bcde-f23456789012 \
  -H "apikey: YOUR_API_KEY"

Quick reference

StepMethodEndpointPurpose
1POST/booksCreate audiobook with format: "audio" and audioDetails
2POST/books/{id}/uploadGet presigned URLs for audio tracks + cover
3PUT(presigned URL)Upload raw bytes to S3
4PATCH/books/{id}/file/{fileId}/attachConfirm upload and link each file
5PATCH/books/{id}Define chapters mapping tracks to sequence
6POST/books/{id}/publishSend to distribution

Key differences from ebook upload

AspectEbookAudiobook
Formatebookaudio
Content roleebook_content (single EPUB)audio_content (one per chapter)
Cover roleebook_coveraudio_cover
Extra metadataaudioDetails with audioLength and audioEdition
ChaptersNot applicableRequired — map each audio file to a chapter via Update Book
ContributorAuthor, Editor, etc.Must include at least one Narrated by contributor

Common errors

StatusMeaningFix
401Missing or invalid API keyCheck the apikey header
404Book or file not foundVerify the bookPublicId or fileId
409Presigned URL already usedRequest a new upload URL
422Validation errorCheck the detail field — common causes: missing chapters, mismatched fileId in chapter definition, missing narrator contributor

On this page