Publication Requests API
Canonical API flow for preparing private previews and publishing an owner's exact family-branch selection.
Publication Requests API
For the owner-facing explanation of private previews, public URLs, branches, and recovery, see Publishing People and Public Family Branches.
The publication API has one public workflow: create a request, wait for its private preview, and submit one owner-confirmed Publish command. Verification, approval records, promotion planning, preflight, artifact writes, and anonymous public-result checks are automatic internal stages.
Automation tokens with tree:publication:update may create and inspect requests
or retry safe stored work. Publishing and discarding require an interactive
owner session. A token can prepare work but cannot authorize public disclosure.
Minimal sequence
POST /api/trees/:treeId/publication/requestswith explicitTreePersonids.- Poll the returned request or operation until the request is
ready_to_review. - Show the private preview links and branch ids to the owner.
POST /api/trees/:treeId/publication/requests/:requestId/publishwith the exact preview revision, selected branch ids, and an idempotency key.- Poll until
publishedorneeds_attention.
The publish intent is immutable. Reusing its idempotency key with a different revision or branch selection returns a conflict. Retry resumes only the stored stage and cannot broaden the selection. Refresh creates a new private preview and therefore requires a new Publish confirmation.
Owner-visible request states
preparing_preview, ready_to_review, publishing, published,
needs_attention, and discarded are the complete owner-visible state set.
Machine stage details appear only as bounded progress and safe issues.
Endpoint contracts
POST /api/trees/:treeId/publication/requests
Create an owner-only publication preview request.
| Field | Value |
|---|---|
| Operation | createPublicationRequest |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
| Request schema | createPublicationRequestSchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 202 | publicationRequestResponseSchema | Private preview preparation was queued. |
| 400 | apiErrorSchema | Invalid selection. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 500 | apiErrorSchema | Request creation failed. |
| 503 | apiErrorSchema | Publication coordination is unavailable. |
Request example:
{
"treePersonIds": [
"tp-a",
"tp-b"
],
"language": "ru",
"note": "Maternal branch"
}
Notes:
- Creation never makes data public.
- Preview generation continues without an open browser tab.
GET /api/trees/:treeId/publication/requests
List compact active publication requests or history.
| Field | Value |
|---|---|
| Operation | listPublicationRequests |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
| Query schema | listPublicationRequestsQuerySchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 200 | publicationRequestListResponseSchema | Cursor-paginated compact request cards. |
| 400 | apiErrorSchema | Invalid query. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 500 | apiErrorSchema | Request list failed. |
| 503 | apiErrorSchema | Publication storage is unavailable. |
Query example:
{
"view": "active",
"limit": 25
}
Notes:
- List responses exclude snapshots, graph geometry, digests, and machine-check arrays.
GET /api/trees/:treeId/publication/requests/:requestId
Read one private publication request and its family branches.
| Field | Value |
|---|---|
| Operation | getPublicationRequest |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
Responses:
| Status | Schema | Description |
|---|---|---|
| 200 | publicationRequestResponseSchema | Request detail with private preview links and safe issues. |
| 400 | apiErrorSchema | Invalid parameters. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 404 | apiErrorSchema | Request not found. |
| 409 | apiErrorSchema | Request state conflict. |
| 500 | apiErrorSchema | Request read failed. |
| 503 | apiErrorSchema | Publication storage is unavailable. |
Notes:
- Automation-token responses set canPublish to false.
POST /api/trees/:treeId/publication/requests/:requestId/publish
Publish the exact family branches confirmed by the owner.
| Field | Value |
|---|---|
| Operation | publishPublicationRequest |
| Auth | interactive owner session |
| Required role | OWNER |
| Request schema | publishPublicationRequestSchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 202 | publicationRequestResponseSchema | The exact publish intent was accepted. |
| 400 | apiErrorSchema | Invalid selection. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Automation tokens are not allowed. |
| 404 | apiErrorSchema | Request not found. |
| 409 | apiErrorSchema | Preview or idempotency conflict. |
| 500 | apiErrorSchema | Publish intent creation failed. |
| 503 | apiErrorSchema | Publication coordination is unavailable. |
Request example:
{
"previewRevisionId": "revision-1",
"branchIds": [
"branch-a"
],
"idempotencyKey": "publish-request-1-revision-1"
}
Notes:
- Verification, approvals, preflight, execution, and public-result checks run automatically.
POST /api/trees/:treeId/publication/requests/:requestId/refresh
Prepare a new immutable private preview for the same selection.
| Field | Value |
|---|---|
| Operation | refreshPublicationRequest |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
| Request schema | publicationRequestCommandSchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 202 | publicationRequestResponseSchema | Preview refresh was queued. |
| 400 | apiErrorSchema | Invalid request. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 404 | apiErrorSchema | Request not found. |
| 409 | apiErrorSchema | Request cannot be refreshed. |
| 500 | apiErrorSchema | Refresh failed. |
| 503 | apiErrorSchema | Publication coordination is unavailable. |
Request example:
{}
Notes:
- A changed preview always requires a new owner Publish confirmation.
POST /api/trees/:treeId/publication/requests/:requestId/retry
Retry only the stored retryable stage.
| Field | Value |
|---|---|
| Operation | retryPublicationRequest |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
| Request schema | publicationRequestCommandSchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 202 | publicationRequestResponseSchema | The exact failed operation was requeued. |
| 400 | apiErrorSchema | Invalid request. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 404 | apiErrorSchema | Request not found. |
| 409 | apiErrorSchema | Failure is not retryable. |
| 500 | apiErrorSchema | Retry failed. |
| 503 | apiErrorSchema | Publication coordination is unavailable. |
Request example:
{}
Notes:
- Retry cannot change revision, branches, identities, or digests.
POST /api/trees/:treeId/publication/requests/:requestId/discard
Discard an unpublished private preview request.
| Field | Value |
|---|---|
| Operation | discardPublicationRequest |
| Auth | interactive owner session |
| Required role | OWNER |
| Request schema | publicationRequestCommandSchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 200 | publicationRequestResponseSchema | Request moved to history. |
| 400 | apiErrorSchema | Invalid request. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Automation tokens are not allowed. |
| 404 | apiErrorSchema | Request not found. |
| 409 | apiErrorSchema | Publishing or published request cannot be discarded. |
| 500 | apiErrorSchema | Discard failed. |
| 503 | apiErrorSchema | Publication storage is unavailable. |
Request example:
{}
Notes:
- Discard never unpublishes an already completed public result.
GET /api/trees/:treeId/publication/operations/:operationId
Read safe automatic publication progress.
| Field | Value |
|---|---|
| Operation | getPublicationOperation |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
Responses:
| Status | Schema | Description |
|---|---|---|
| 200 | publicationOperationResponseSchema | Automatic operation status and safe issue. |
| 400 | apiErrorSchema | Invalid parameters. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 404 | apiErrorSchema | Operation not found. |
| 409 | apiErrorSchema | Operation state conflict. |
| 500 | apiErrorSchema | Operation read failed. |
| 503 | apiErrorSchema | Publication storage is unavailable. |
Notes:
- Responses never expose leases, storage keys, receipts, or execution cursors.
GET /api/trees/:treeId/publication/candidates
Discover bounded age-eligible publication candidates.
| Field | Value |
|---|---|
| Operation | queryPublicationCandidates |
| Auth | owner session or tree:publication:update token |
| Required role | OWNER |
| Token scope | tree:publication:update |
| Query schema | publicationCandidateQuerySchema |
Responses:
| Status | Schema | Description |
|---|---|---|
| 200 | publicationCandidateListResponseSchema | Bounded candidate page. |
| 400 | apiErrorSchema | Invalid query. |
| 401 | apiErrorSchema | Authentication required. |
| 403 | apiErrorSchema | Owner access or token scope required. |
| 500 | apiErrorSchema | Candidate discovery failed. |
| 503 | apiErrorSchema | Tree data is unavailable. |
Query example:
{
"q": "Иван",
"limit": 25
}
Notes:
- Candidate discovery never authorizes publication.