Envelope

Installing a team (API)

How to find, install, run, and manage an Envelope team entirely via the API — no workspace required.

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).


1. Find a team

List all published teams:

GET /templates
{
  "templates": [
    {
      "id": "tpl_abc123",
      "slug": "support-triage",
      "name": "Support Triage",
      "description": "Routes inbound tickets to the right queue.",
      "version": 3,
      "requiredSecrets": ["ZENDESK_API_KEY"],
      "requiredVariables": ["QUEUE_EMAIL"]
    }
  ]
}

Fetch a specific team by ID or slug:

GET /templates/:id

Check requiredSecrets and requiredVariables — you'll need to supply these at install time or immediately after.


2. Install the team

POST /installs

Envelope Managed

Envelope provisions and runs the agents. Secrets can be added immediately after install via PATCH /installs/:id/secrets.

{
  "templateId": "tpl_abc123",
  "platform": "envelope",
  "secrets": {
    "ZENDESK_API_KEY": "zdkey_..."
  },
  "variables": {
    "QUEUE_EMAIL": "[email protected]"
  }
}

Paperclip

Agents are provisioned on your Paperclip instance. Supply your Paperclip base URL, API key, and either an existing companyId or a companyName to create a new company.

{
  "templateId": "tpl_abc123",
  "platform": "paperclip",
  "credentials": {
    "paperclipBaseUrl": "https://paperclip.acme.com",
    "paperclipApiKey": "pk_..."
  },
  "companyId": "cmp_xyz",
  "secrets": {
    "ZENDESK_API_KEY": "zdkey_..."
  },
  "variables": {
    "QUEUE_EMAIL": "[email protected]"
  }
}

Supply companyName instead of companyId to have Envelope create the Paperclip company for you. The created company ID is returned in the response.

Response

{
  "installId": "inst_abc123",
  "platform": "envelope",
  "status": "completed",
  "deployedAgents": [
    { "key": "coordinator", "externalId": "agent_...", "name": "Coordinator" }
  ]
}

Note the installId — every subsequent API call for this deployment uses it.

Optional install fields

| Field | Type | Description | |---|---|---| | adapterType | string | Override the adapter type for all agents — claude_local, codex_local, gemini_local, opencode_local, cursor_local, http, etc. | | model | string | Override the model for all agents | | webhookUrl | string | URL Envelope POSTs to when each run completes |


3. Add or update secrets and variables

Supply secrets and variables at install time or add them afterward. Both endpoints accept flat key/value JSON.

Secrets (encrypted at rest, never returned by any API):

PATCH /installs/:installId/secrets
{
  "ZENDESK_API_KEY": "zdkey_new..."
}

Variables (non-sensitive config values):

PATCH /installs/:installId/variables
{
  "QUEUE_EMAIL": "[email protected]"
}

Both endpoints also accept a wrapped format: { "secrets": { ... } } or { "variables": { ... } }.

For Envelope Managed installs, adding the last required secret or variable triggers a run automatically (unless a schedule is configured).


4. Trigger a run

POST /installs/:installId/run
{
  "inputText": "Ticket #8821 — Customer reports login failure after MFA change."
}

| Field | Type | Description | |---|---|---| | inputText | string | Seeds the first agent's input for this run only. If omitted, install variables are used. | | bypassGates | boolean | Skip human review gates. Useful for fully automated batch jobs. Default: false. | | dryRun | boolean | Run the full pipeline with all outbound calls intercepted. Useful for testing. Default: false. |

Response — run completed:

{
  "runId": "run_abc123",
  "status": "completed",
  "response": "Ticket routed to Tier 2 queue. Escalation email sent.",
  "inputTokens": 412,
  "outputTokens": 98
}

Response — run paused at a human gate:

{
  "runId": "run_abc123",
  "status": "paused",
  "pausedAtGate": "manager-review"
}

The install must have status: "completed" before runs can be triggered. A 409 is returned if the install is still provisioning.


5. Receive run completions via webhook

If you passed a webhookUrl at install time, Envelope POSTs to that URL when each run finishes:

{
  "installId": "inst_abc123",
  "runId": "run_abc123",
  "status": "completed",
  "response": "Ticket routed to Tier 2 queue.",
  "inputTokens": 412,
  "outputTokens": 98
}

When a run pauses at a gate, the payload has "status": "paused" and a "pausedAtGate" field identifying which gate triggered.


6. Fetch run history

Individual agent runs, newest first:

GET /installs/:installId/agent-runs?limit=50
{
  "runs": [
    {
      "id": "ar_...",
      "agentKey": "coordinator",
      "runId": "run_abc123",
      "status": "completed",
      "inputTokens": 412,
      "outputTokens": 98,
      "errorMessage": null,
      "createdAt": "2026-05-12T09:41:00.000Z"
    }
  ]
}

limit accepts 1–200. Defaults to 50.

Aggregated daily pass/fail counts:

GET /installs/:installId/run-log?days=7
{
  "days": [
    { "date": "2026-05-06", "ok": 14, "error": 1 },
    { "date": "2026-05-07", "ok": 18, "error": 0 }
  ]
}

days accepts 1–30. Defaults to 7.


7. List your installs

GET /installs

Returns all installs created with your API key, ordered newest first. Includes id, templateId, templateName, templateSlug, templateVersion, platform, status, and createdAt.


8. Remove an install

DELETE /installs/:installId

Tears down provisioned agents on the platform, deletes all encrypted secrets, and marks the install as cancelled. Returns:

{
  "ok": true,
  "installId": "inst_abc123",
  "platform": "envelope",
  "deletedAgents": 3
}

Workspace documents

Workspace documents accumulate stateful rows across agent runs. If the team you installed declares a workspace block in its definition, the document is created automatically at install time. You can also read, write, and manage documents via these API routes.

All document routes require authentication (Authorization: Bearer <api-key>).

List documents for an install

GET /installs/:installId/documents

Read a document

GET /installs/:installId/documents/:name

Returns the full document: schema, all rows with field values, per-row notes, blocked-by, and last-changed-by.

Append rows

POST /installs/:installId/documents/:name/rows
{ "rows": [{ "company": "Acme Corp", "email-status": "unverified" }] }

Adds new rows. Distinct from updating existing rows — the runtime does not silently upsert.

Edit a row

PATCH /installs/:installId/documents/:name/rows/:rowId
{ "update": { "email": "[email protected]" }, "notes": "Verified via LinkedIn", "blockedBy": null }

notes and blockedBy are always human-owned. Setting blockedBy to null or "" clears the hold and allows the agent to act on the row again.

Delete a row (hard delete)

DELETE /installs/:installId/documents/:name/rows/:rowId

Physically removes the row. Required for GDPR erasure. No soft-delete.

Export

GET /installs/:installId/documents/:name/export?format=csv
GET /installs/:installId/documents/:name/export?format=json

Transition lifecycle state

POST /installs/:installId/documents/:name/lifecycle
{ "state": "archived" }

Valid states: new, active, complete, archived, deleted.

Version history and rollback

GET  /installs/:installId/documents/:name/snapshots
POST /installs/:installId/documents/:name/snapshots/:snapshotId/revert

Every agent write batch creates a named snapshot. Use revert to restore any prior state.


Team memory

Team memory is a persistent document store scoped to each install. Agents write rows to it during runs and read them back at the start of the next run — without any schema declaration in the team definition. See the team memory guide for full details.

All memory routes require session authentication.

Read all memory documents

GET /installs/:installId/memory

Returns every memory document for the install, including all non-complete rows. Useful for inspecting what agents have accumulated across runs.

{
  "installId": "inst_abc123",
  "documents": [
    {
      "id": "doc_...",
      "name": "source-log",
      "columns": ["url", "topic", "quality", "status"],
      "rows": [
        {
          "id": "row_...",
          "status": "active",
          "createdAt": "2026-05-20T09:00:00.000Z",
          "updatedAt": "2026-05-20T09:00:00.000Z",
          "url": "arxiv.org/abs/2405.1234",
          "topic": "inference cost",
          "quality": "high",
          "status": "used"
        }
      ]
    }
  ]
}

Append a row to a document

POST /installs/:installId/memory/:documentName/rows

Creates the document if it doesn't exist, then appends a row. The document name is free-form — agents define it in their prompts (e.g. source-log, ticket-state).

{
  "data": { "url": "arxiv.org/abs/2405.5678", "topic": "retrieval", "quality": "high" },
  "status": "active"
}

status defaults to "active" if omitted. Returns the new row ID and document ID.

Update a row

PATCH /installs/:installId/memory/:documentName/rows/:rowId

Update the status or patch the data of an existing row. The most common use is retiring a row by setting status: "complete" — completed rows are not injected into future runs.

{ "status": "complete" }

Partial data patches are merged into the existing row data — unspecified fields are preserved.

Delete a row

DELETE /installs/:installId/memory/:documentName/rows/:rowId

Hard-deletes the row. No soft-delete. Use for GDPR erasure or correcting bad data.


Error reference

| Status | Meaning | |---|---| | 400 | Invalid request body or missing required field | | 401 | Missing or invalid API key | | 403 | Key does not own this install | | 404 | Install or template not found | | 409 | Install not ready (still provisioning), or already cancelled | | 422 | Missing required secrets or variables before a run | | 502 | Platform-side provisioning or teardown error |