Envelope

Versioning your team (API)

How to update a published team, manage version drafts, and roll back regressions — all via the API.

Authenticate every request with your API key:

Authorization: Bearer <your-api-key>

All endpoints are prefixed with /api. The base URL is your Envelope instance origin (e.g. https://openenvelope.org/api).


How versioning works

Every published team has a stable id and slug that never change across versions. Deployers install once using that identifier and keep pointing at it forever. When you publish an update, they are not migrated automatically — they continue running on their installed version until they choose to upgrade.

Updates flow through a draft cycle:

  1. Create a version draft from the published team — POST /templates/:id/new-version
  2. Edit the draft freely — PATCH /templates/:draftId
  3. Publish the draft — POST /templates/:draftId/publish

Envelope merges the draft into the published parent, increments the version number, and deletes the draft. The parent's id and slug remain unchanged. You can only have one active version draft per team at a time.


Version numbering

Versions follow semver (MAJOR.MINOR.PATCH).

| Bump | When to use | |---|---| | PATCH | Bug fixes, prompt improvements — no contract change | | MINOR | New optional inputs or outputs, new agents added | | MAJOR | Removing or renaming inputs, outputs, or agent keys — breaking change |

Deployers with existing installs receive notifications on MAJOR bumps. When in doubt, bump MAJOR.


1. Create a version draft

POST /templates/:id/publish

Wait — first create the draft:

POST /templates/:id/new-version

No request body. :id must be a published template. Calling this on a draft returns 409.

Response: 201 Created

{
  "id": "tpl_draft456",
  "slug": "support-triage-v2",
  "parentTemplateId": "tpl_abc123",
  "version": 2,
  "status": "draft"
}

The draft inherits all content from the published parent — name, description, agents, prompts, pricing, access policy. Store the draft id. All edits and the eventual publish use this ID, not the parent's.


2. Edit the draft

PATCH /templates/:draftId
{
  "definition": { ... },
  "changeLog": "v2: Added escalation specialist for P1 tickets."
}

The published parent is completely unaffected while you work. Edit prompts, restructure the agent hierarchy, update pricing — none of it touches live installs.

Attempting to PATCH the published parent directly returns 409 Conflict.


3. Publish the update

POST /templates/:draftId/publish
{
  "changeLog": "v2: Added escalation specialist. P1 detection improved with urgency classifier."
}

Always include a changeLog string. It appears in every deployer's version history and is the primary signal they use to decide whether to upgrade.

Envelope:

  1. Copies the draft's content into the published parent
  2. Increments the parent's version number
  3. Deletes the draft
  4. Leaves the parent's id and slug unchanged

Response: Returns the updated parent template with the new version number.

Existing installs continue running on their previous version. They are never updated automatically.


4. Roll back to a previous version

If a new version introduces a regression, restore any prior version from its snapshot:

POST /templates/:id/rollback
{
  "version": 1
}

:id is the published parent template ID. version is the version number to restore.

Response: 201 Created — returns a new draft pre-loaded with that version's full definition.

The published parent keeps running while you review the restored draft. Adjust it if needed, then publish it as you would any update. This is non-destructive — rolling back never overwrites the live team.

Snapshots are only stored for versions published after this feature was introduced. Older versions cannot be restored.


5. Archive a team

Archiving delists the team from the Library and blocks new installs. Existing installs keep running until the deployer removes them.

POST /templates/:id/archive

No request body. :id must be a published template. Archiving a draft returns 409 — delete drafts instead.

Response: Returns the updated template with status: "archived".

Use archiving when you want to retire a team that still has active installs. You cannot delete a published template with active installs.


6. Delete a team

DELETE /templates/:id

Permanently removes the template. No response body — returns 204 No Content on success.

Only available for:

  • Draft templates (any install count)
  • Published or archived templates with zero active installs

Attempting to delete a template with active installs returns 409 with "canArchive": true. Archive first, wait for deployers to remove their installs, then delete.


Lifecycle reference

| State | Visible in Library | Accepts new installs | Editable | Next transition | |---|---|---|---|---| | Draft | No | No | Yes — PATCH /templates/:id | Publish → Published | | Published | Yes | Yes | No — create version draft first | New-version → Version draft; Archive → Archived | | Version draft | No | No | Yes — PATCH /templates/:draftId | Publish → merges into parent | | Archived | No | No | No | Delete (only if 0 installs) |


Impact on installs

| Action | Library listing | Existing installs | |---|---|---| | Publish new version | Updated version shown | Unaffected — keep running previous version | | Archive | Removed | Unaffected — keep running until deployer removes | | Delete (0 installs) | Removed | No installs exist |