Skip to content

Create project

POST
/v1/projects

Start a new book by pointing it at a file you already uploaded (POST /uploads or an anonymous estimate's anonymousUploadKey). This is the entry point into the whole translation pipeline — normalize, then process batches, then export. Provide exactly one source; a destination language you don't pass falls back to your saved default.

Authorizations

Bearer

JWT bearer token from POST /v1/auth/login.

Type
HTTP (bearer)
or
ApiKey

Scoped API key for non-interactive clients (issued by PBI #1426).

Type
API Key (header: X-Api-Key)

Request Body

application/json

Request body for creating a project. Supply exactly one source: UploadKey (the
key returned by POST /uploads after a browser upload), AnonymousUploadKey
(the anonymousUploadKey from a signed-out POST /v1/anonymous-estimate, adopted into this
new project without re-uploading — PBI #1880), or SourcePath (a server-side
PDF/folder, kept for admin/scripted use).

The anonymousUploadKey from a signed-out POST /v1/anonymous-estimate, adopted into this project without re-uploading (PBI #1880).

The book's display name.

A server-side path to an existing PDF/folder (admin/scripted use only) — omit for a normal upload-based project.

The uploaded file's size in bytes, if known — used to estimate cost before processing starts.

Format"int64"
Pattern"^-?(?:0|[1-9]\\d*)$"

The language to translate into; omit to use the account's default.

Valid values"en""es""fr""de""it""pt""nl""pl""ru""uk""tr""ar""he""hi""ja""ko""zh""la""el""sv"

The key returned by POST /uploads after a browser upload; the usual way to supply a source file.

Responses

Created

application/json

The top-level unit of work: one book (or set of screenshots) being translated page-by-page,
together with all of its pages and the state of the human-in-the-loop approval ladder.

Number of batches the system has processed and auto-confirmed. Starts at 0 (a brand-new project),
and the batch-size ladder reads directly from this value — see BatchPolicy.

Format"int32"
Pattern"^-?(?:0|[1-9]\\d*)$"

When the project was created (UTC).

Format"date-time"

The page IDs that make up the batch currently being processed. Empty when no batch is in flight.
The pipeline auto-confirms the round once its pages are processed (each PageStatus.Approved);
a page that fails is recorded as PageStatus.Failed and excluded so it stays retryable.

When this project becomes eligible for deletion (UTC) — DateTime TranslationProject.CreatedAtUtc plus the
retention window that applies for its current ProjectStatus TranslationProject.Status. A never-started draft
(bool RetentionPolicy.IsNeverStartedStatus(ProjectStatus status)) uses the shorter never-started window (PBI #2240);
once started it uses the normal window. Computed via RetentionPolicy, so it always agrees
with the policy and round-trips automatically; serialized onto the list/detail DTO so the UI can show a
retention notice. Read-only (no setter) — nothing persists it independently.

Format"date-time"

Stable identifier for this project.

Format"uuid"

Human-friendly project name (often the book title). Mutable so the owner can rename
a project after creation; the rename transition persists it through the store, which keeps the
promoted Name column and the jsonb payload in sync.

The user who owns this project (multi-tenancy). null for legacy / un-owned
projects (tests, the single-user filesystem store). When set, the API scopes every project
operation to the authenticated owner.

Format"uuid"

All pages of the book, in page order.

The length of the retention window in whole days that applies for the current ProjectStatus TranslationProject.Status,
surfaced alongside DateTime TranslationProject.ExpiresAtUtc so the UI can render "Kept N days · expires <date>"
without hard-coding the policy. Shorter for a never-started draft (PBI #2240).

Format"int32"
Pattern"^-?(?:0|[1-9]\\d*)$"

A project-wide correction of the source language (PBI #1368). When set it is the default source
language for pages that have no per-page string? BookPage.SourceLanguageOverride — applied
when a page is processed and as the fallback for display/translation. null when
per-page auto-detection stands. A per-page override always wins over this.

Durable object-storage key of the uploaded source (e.g.
uploads/{ownerId}/{uploadId}/book.pdf) when the project was created by uploading a file
through the browser rather than pointing at a server-side path. null for
legacy server-path projects. The normalize transition downloads this to the project's working
volume before rendering, so processing works on any instance without a shared filesystem.

Absolute or repo-relative path to the original input (a PDF, a folder of images, …).
Recorded for provenance and so a project can be re-normalized if needed. For projects created
from a browser upload this starts empty and the normalize transition fills it in with the local
working copy hydrated from string? TranslationProject.SourceObjectKey.

Size in bytes of the original uploaded source file, captured at creation time from the browser
upload, so the library dashboard can show "how big is this book" without re-reading the blob.
null for legacy / server-path projects whose size was never recorded.

Format"int64"
Pattern"^-?(?:0|[1-9]\\d*)$"

Where the project is in its overall lifecycle.

Valid values"Created""Calibrating""Processing""PausedNeedsCredit""PausedNeedsCapacity""Complete""CompletedWithErrors""Failed""Cancelling""Cancelled"

The language this project is translated into (PBI #1451) — a supported ISO-639 code from
SupportedLanguages, lower-cased. Chosen at creation (defaulting to the owner's
UserPreferences.DefaultTargetLanguageCode) and threaded through the translation stage so the
pipeline targets this language rather than a hardcoded English. Defaults to
string SupportedLanguages.Default (en), so a project created before this field existed
deserialises as English and no null ever reaches the pipeline.

Playground

Server
Authorization
Body

Samples

Powered by VitePress OpenAPI