Skip to main content
Webentor Studio

Help · API reference

Drafts and content

Drafts, content, review and publishing.

All groups

List project draftsGET /api/v1/projects/{project}/drafts

Lists the project's drafts and branches the caller can see (shared branches and their own sessions) in every status, most recently updated first, as one unpaged data list. Needs the draft-read permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)

200 Success.

What comes back
  • data array of object, required

    A list of:

    • id string, required
    • kind "session" | "branch", required
    • title string, required
    • status string, required
    • branch string, required
    • origin string, required
    • created_by string | null, required
    • created_at string, required: ISO 8601 timestamp.
    • updated_at string, required: ISO 8601 timestamp.
    • head_commit string, required
    • base_commit string, required
    • preview_url string | null, required: The line’s stable preview address; null until somebody asks for one.
    • preview_visibility "members" | "public", required
    • preview_public_until one of: string | null, required

      One of:

      1. string. ISO 8601 timestamp.

      2. null

    • expires_at one of: string | null, required: When the line is tidied away: an idle session, or an assistant’s line whose token died. Null for a branch.

      One of:

      1. string. ISO 8601 timestamp.

      2. null

    • publish_at one of: string | null, required

      One of:

      1. string. ISO 8601 timestamp.

      2. null

    • merged_into string | null, required: Where a merged line went: live (published) or the id of the line it was folded into. Null while open.
    • scheduled_by string | null, required: Who set publish_at; null when nothing is scheduled.
Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • default Any other failure, as RFC 9457 problem details.

Create a project draftPOST /api/v1/projects/{project}/drafts

Opens a new draft on its own branch from the live branch and answers 201 with it; title defaults to Untitled changes. Needs the draft-create permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • Idempotency-Key (header, string, optional): Optional. A key the caller chooses, at most 160 characters, kept per team. A repeat of the same request (method, path and body) under the same key is answered with the first result and the header Idempotent-Replay: true, and the work is not done twice. The same key with a different request answers 409; so does a repeat sent while the first is still running, with Retry-After: 5.

Body (application/json)

  • title string, 1 to 120 characters, default "Untitled changes"

201 Success. Headers: Idempotent-Replay.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • 409 Conflict. (code is conflict.)
  • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
  • default Any other failure, as RFC 9457 problem details.

Get a project draftGET /api/v1/projects/{project}/drafts/{draft}

Returns a draft with its head commit, how far it is behind the live branch, its review state and history, preview builds and invitations, and whether publishing it is blocked. Needs the draft-read permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)

200 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • default Any other failure, as RFC 9457 problem details.

Update a project draftPATCH /api/v1/projects/{project}/drafts/{draft}

Renames a draft (title). Needs the draft-create permission. A draft that is already published or discarded keeps its name and the request is refused.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)

Body (application/json)

  • title string, required, 1 to 120 characters

200 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • 409 Conflict. (code is conflict.)
  • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
  • default Any other failure, as RFC 9457 problem details.

Delete a project draftDELETE /api/v1/projects/{project}/drafts/{draft}

Discards a draft: its branch is archived in the repository and open reviews close. Needs the draft-create permission for your own draft and the team-members permission for someone else's. A published draft cannot be discarded.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)

200 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • 409 Conflict. (code is conflict.)
  • default Any other failure, as RFC 9457 problem details.

List draft commentsGET /api/v1/projects/{project}/drafts/{draft}/comments

Returns the draft's whole review thread: every comment (data) and every review request (requests), oldest first, unpaged. Needs the draft-read permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)

200 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • default Any other failure, as RFC 9457 problem details.

Create a draft commentPOST /api/v1/projects/{project}/drafts/{draft}/comments

Adds a comment to the draft's review thread, optionally pinned to a page (page_path) or block (block_id), and notifies the others on the project who may comment. Answers 201 with the comment. Needs the review-comment permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)

Body (application/json)

  • body string, required, 1 to 4000 characters
  • page_path string, at most 300 characters
  • block_id string, at most 64 characters

201 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
  • default Any other failure, as RFC 9457 problem details.

Compare a draft against liveGET /api/v1/projects/{project}/drafts/{draft}/compare

Compares two versions, by default the live branch (from) against the draft (to), and lists what changed, naming pages whose editor work is not saved yet (unsaved). Comparing live against the draft also returns code an assistant wrote, with diffs. Needs the draft-read permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)
  • from (query, string, optional)
  • to (query, string, optional)

200 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • default Any other failure, as RFC 9457 problem details.

List draft content in a collectionGET /api/v1/projects/{project}/drafts/{draft}/content/{collection}

Lists a collection's entries on the draft. Without paging parameters it answers the whole list as a bare array; with limit (1 to 500) or after (a slug) it answers entries and next, in slug order. x-webentor-commit gives the draft's head. Needs the draft-read permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)
  • collection (path, string)
  • after (query, string, optional)
  • limit (query, string, optional)

200 Success.

What comes back

One of:

  1. A list of:

    • slug string, required
    • fields object, required: The entry’s scalar fields (title, description, order, …); _invalid: true for a file that does not parse.
    • counts object, required: How many blocks a page has; empty for an entry that does not parse.
    • entries array of object, required

      A list of:

      • slug string, required
      • fields object, required: The entry’s scalar fields (title, description, order, …); _invalid: true for a file that does not parse.
      • counts object, required: How many blocks a page has; empty for an entry that does not parse.
    • next string | null, required: The after for the next page; null on the last.
Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
  • default Any other failure, as RFC 9457 problem details.

Create a draft content entryPOST /api/v1/projects/{project}/drafts/{draft}/content/{collection}

Creates an entry (slug, data) on the draft as a commit and answers 201 with the commit. Needs the content-write permission. The draft must be open, and an existing slug is refused.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)
  • collection (path, string)

Body (application/json)

  • slug string, required, 1 to 200 characters: The new entry’s slug; / makes a nested path.
  • data any, required: The entry, shaped by the collection’s own schema. The editor door’s describe_collection tool reads it.

201 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 403 Not allowed. (code is forbidden.)
  • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
  • default Any other failure, as RFC 9457 problem details.

Get a draft content entryGET /api/v1/projects/{project}/drafts/{draft}/content/{collection}/{slug}

Returns one entry's document on the draft. The ETag is the draft's head commit; send it back as If-Match when writing. Needs the draft-read permission.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)
  • collection (path, string)
  • slug (path, string): May contain unencoded /: this is a path, not a single segment. Encoded slashes will not match.

200 Success.

Errors it can answer
  • 401 Authentication required. (code is unauthenticated.)
  • 404 Not found. Also returned when the resource exists but the caller may not see it, so that the two cannot be told apart. (code is not_found.)
  • default Any other failure, as RFC 9457 problem details.

Write a draft content entryPUT /api/v1/projects/{project}/drafts/{draft}/content/{collection}/{slug}

Writes an entry's whole document on the draft as a commit and answers with the commit and whether anything changed. Needs the content-write permission, and the draft must be open. With If-Match set to the ETag you read, the write is refused with 412 if the draft has moved since.

Who may call it: A signed-in session, or an access token (write to change anything)

Parameters

  • project (path, string)
  • draft (path, string)
  • collection (path, string)
  • slug (path, string): May contain unencoded /: this is a path, not a single segment. Encoded slashes will not match.
  • If-Match (header, string, optional): Optimistic concurrency: the revision the write is based on.

Body (application/json)

The whole entry, replacing what is there: read it with GET at the same address, change it, send it back. Send the ETag that read answered as If-Match, so a change made in between is refused with 412 rather than overwritten. A document that does not fit its envelope is refused with 422 and issues; one that fits the envelope but not the project’s block or collection schema fails the next build, so validate it first (GET …/validate, or the editor door’s describe_collection and validate_content tools).

One of:

    • title string
    • description string
    • region string
    • blocks array of object, required

      A list of:

      • type string, required

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Delete a draft content entryDELETE /api/v1/projects/{project}/drafts/{draft}/content/{collection}/{slug}

    Deletes an entry from the draft as a commit and answers with the commit. Needs the content-write permission. The draft must be open.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)
    • collection (path, string)
    • slug (path, string): May contain unencoded /: this is a path, not a single segment. Encoded slashes will not match.

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • default Any other failure, as RFC 9457 problem details.

    Rename a draft content entryPOST /api/v1/projects/{project}/drafts/{draft}/content/{collection}/{slug}/rename

    Moves an entry to a new slug (to) on the draft as a commit, carrying any unsaved editor work with it. Needs the content-write permission. The draft must be open, and a slug that is taken is refused.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)
    • collection (path, string)
    • slug (path, string): May contain unencoded /: this is a path, not a single segment. Encoded slashes will not match.

    Body (application/json)

    • to string, required, 1 to 200 characters: The new slug.

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Get draft historyGET /api/v1/projects/{project}/drafts/{draft}/history

    Returns the draft branch's commits, newest first, up to limit (50 by default, at most 200), as a data list with no further paging. Needs the draft-read permission.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)
    • limit (query, integer, optional), at most 200, default 50

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • default Any other failure, as RFC 9457 problem details.

    Create a draft keepPOST /api/v1/projects/{project}/drafts/{draft}/keep

    Postpones the cleanup of an idle editing session or assistant line, so it is not removed for another 30 days; the answer gives the new expires_at. Needs the draft-create permission. A branch never expires, so asking for one is refused.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Get draft manifestGET /api/v1/projects/{project}/drafts/{draft}/manifest

    Returns the project's content manifest (collections and their schemas) and lock file as they are on the draft. Needs the draft-read permission.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • default Any other failure, as RFC 9457 problem details.

    Create a draft mergePOST /api/v1/projects/{project}/drafts/{draft}/merge

    Merges the draft into the live branch or into another line (into), without deploying anything; the live site changes only when published. Into live it needs the deploy-production permission, and under review_required the draft must be approved and editors and developers may not publish; into a line it needs the content-write permission. Conflicting files come back as a 409, and decisions settles them.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • into string, default "live": Where to merge: live, or the id of another line.
    • decisions object: Repository path → the side that wins what that file could not merge. For a page this settles only the blocks both sides changed (the 409 names them under conflicts); the other edits of both sides are kept. For any other file the chosen side is taken whole. The answer lists what a decision set aside under discarded.

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 409 Conflict. (code is conflict.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Preview a draftPOST /api/v1/projects/{project}/drafts/{draft}/preview

    Queues a preview build of the draft's head, or of an older commit of it (at), and answers with build_id, the line's lasting preview address (url) and this build's address (build_url). A finished build of the same commit is reused. Needs the draft-read permission. The draft must be open.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)
    • at (query, string, optional)

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 404 Not found. Also returned when the resource exists but the caller may not see it, so that the two cannot be told apart. (code is not_found.)
    • 409 Conflict. (code is conflict.)
    • default Any other failure, as RFC 9457 problem details.

    Replace preview accessPUT /api/v1/projects/{project}/drafts/{draft}/preview/access

    Sets who can open the draft's preview: team members only (members) or anyone with the link (public) for days (1, 7 or 30; 7 by default). Needs the draft-create permission.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • visibility "members" | "public", required
    • days one of: 1 | 7 | 30: How long a public preview stays public; 7 when omitted.

      One of:

      1. 1

      2. 7

      3. 30

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Create a preview invitePOST /api/v1/projects/{project}/drafts/{draft}/preview/invites

    Invites one person by email to the draft's preview and emails them a personal link; the answer carries the link and whether it was emailed. Needs the draft-create permission.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • email string (email), required, at most 200 characters, matches ^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$

    201 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Delete a preview inviteDELETE /api/v1/projects/{project}/drafts/{draft}/preview/invites/{invite}

    Revokes one person's invitation to the draft's preview, so the personal link they were emailed stops working at once. The revocation is recorded. Needs the draft-create permission.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)
    • invite (path, string)

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 404 Not found. Also returned when the resource exists but the caller may not see it, so that the two cannot be told apart. (code is not_found.)
    • default Any other failure, as RFC 9457 problem details.

    Publish a draftPOST /api/v1/projects/{project}/drafts/{draft}/publish

    Publishes the draft: merges it into the live branch and queues a production build, answering 202 with the commit and build_id; the site changes when the build finishes. It needs the deploy-production permission, and under review_required the draft must be approved and editors and developers may not publish. Refused for a draft already published or discarded, while a rollback is unresolved, or with unsaved editor work.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)
    • Idempotency-Key (header, string, optional): Optional. A key the caller chooses, at most 160 characters, kept per team. A repeat of the same request (method, path and body) under the same key is answered with the first result and the header Idempotent-Replay: true, and the work is not done twice. The same key with a different request answers 409; so does a repeat sent while the first is still running, with Retry-After: 5.

    202 Success. Headers: Idempotent-Replay.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 409 Conflict. (code is conflict.)
    • default Any other failure, as RFC 9457 problem details.

    Submit a draft for reviewPOST /api/v1/projects/{project}/drafts/{draft}/review

    Sends the draft for review, optionally with a note, and notifies the named reviewer (reviewer_id) or else everyone who may decide. Needs the review-submit permission. A draft already published or discarded is refused, and reviewer_id must be someone on the project.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • note string, at most 2000 characters
    • reviewer_id string (uuid), matches ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$: A member to ask; omitted, anyone who may decide.

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Approve or reject a draftPOST /api/v1/projects/{project}/drafts/{draft}/review/decision

    Approves the draft or requests changes (decision), optionally with a note. Needs the review-decide permission. The draft must be in review, nobody may approve their own draft, and an approval is refused if the draft has changed since it was sent, or since reviewed_head.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • decision "approve" | "request_changes", required
    • note string, at most 2000 characters
    • reviewed_head string, matches ^[0-9a-f]{7,64}$: The draft’s head_commit the reviewer read; a decision on a version that has moved is refused.

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 409 Conflict. (code is conflict.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Replace a draft schedulePUT /api/v1/projects/{project}/drafts/{draft}/schedule

    Schedules the draft to publish itself at at (ISO 8601), or cancels the schedule with null; permissions are checked again when it fires. Setting a time needs the deploy-production permission, and under review_required the draft must be approved and editors and developers may not publish. at may be at most a year ahead, unsaved editor work is refused, and a closed draft cannot be scheduled.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • at one of: string (date-time) | null, required: When to publish, ISO 8601; null cancels.

      One of:

      1. string (date-time)

      2. null

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 409 Conflict. (code is conflict.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Synchronise a draftPOST /api/v1/projects/{project}/drafts/{draft}/sync

    Brings the live branch, or another line named in from, into the draft, keeping the draft's changes; nothing to bring in answers Already up to date. Needs the content-write permission. The draft must be open; conflicting files come back as a 409, and decisions settles them.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    Body (application/json)

    • from string, default "live": What to bring in: live, or the id of another line.
    • decisions object: Repository path → the side that wins what that file could not merge. For a page this settles only the blocks both sides changed (the 409 names them under conflicts); the other edits of both sides are kept. For any other file the chosen side is taken whole. The answer lists what a decision set aside under discarded.

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • 403 Not allowed. (code is forbidden.)
    • 409 Conflict. (code is conflict.)
    • 422 Validation failed. The body carries an issues array describing each rejected field. (code is validation_failed.)
    • default Any other failure, as RFC 9457 problem details.

    Validate a draftGET /api/v1/projects/{project}/drafts/{draft}/validate

    Checks the draft's content against the project's schemas and answers ok with a list of problems, each naming what would fail and why. Needs the draft-read permission.

    Who may call it: A signed-in session, or an access token (write to change anything)

    Parameters

    • project (path, string)
    • draft (path, string)

    200 Success.

    Errors it can answer
    • 401 Authentication required. (code is unauthenticated.)
    • default Any other failure, as RFC 9457 problem details.