PublishDrive
Api

Request file upload URLs

Request presigned URLs to upload files. Upload each file with PUT to the returned URL before it expires, then complete the flow with PATCH /api/books/{bookPublicId}/file/{fileId}/attach.

Requesting upload URLs does not change book status. If the book is not draft, a successful file attach moves it to draft; call POST /api/books/{bookPublicId}/publish again after all uploads and book updates are finished.

POST
/books/{bookPublicId}/upload
apikey<token>

In: header

Path Parameters

bookPublicId*string
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://api.publishdrive.com/v2/distribution/books/e9e0d212-52cb-11f1-8d0d-aedf0546306a/upload" \  -H "Content-Type: application/json" \  -d '[    {      "referenceId": "epub-ref",      "role": "ebook_content",      "filename": "mybook.epub",      "hashSha256": "9c50bbd0c11fda120232a970f3ee67f993459bb81fda6f35d7ac4cfa9b45d5f5"    }  ]'

[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://s3.example.com/presigned-epub",
    "expiresAt": "2026-03-05T10:00:00Z"
  }
]

{
  "title": "Bad Request",
  "status": 400,
  "detail": "Invalid file role for this book format.",
  "instance": "/v2/distribution/books/e9e0d212-52cb-11f1-8d0d-aedf0546306a/upload",
  "invalidParams": [
    {
      "name": "0.role",
      "reason": "Role is not allowed for this upload batch."
    }
  ]
}

Empty
{
  "message": "Book not found"
}
Empty
{
  "type": "string",
  "title": "string",
  "status": 0,
  "detail": "string",
  "instance": "string",
  "invalidParams": [
    {
      "name": "string",
      "reason": "string"
    }
  ]
}

On this page