Workspace API
Official Skill Installs
Install, re-pin, or deactivate an official skill with POST /workspace/skills/install and /uninstall.
Both routes below cost 0 credits, require skills:write, and require the Idempotency-Key header (1-200 characters). Pass workspace_id as a query parameter when authenticating with a user JWT; API keys infer it. Each also has a batch sibling at POST /workspace/skills/<verb>/batch, accepting 1-100 items with a per-item idempotencyKey — see Batch Writes.
The Workspace API requires the Pro plan. A request from a non-Pro workspace or a non-member receives 403 forbidden.
Both return the same installation-shaped receipt (skillId and lifecycle are null; installationId identifies the row):
{ "skillId": null, "installationId": "8a1f3c2e-0001-4b7d-9e5a-000000000012", "draftVersion": null, "publishedRevisionId": null, "lifecycle": null, "changed": true}Install an Official Skill
POST https://api.parcelengineering.com/api/v1/workspace/skills/installInstalls an official skill release into this workspace, or re-pins an existing installation. Install has ensure-state semantics: installing official skill X at release B while X is active at release A updates the one row rather than leaving it on A.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
officialSkillId | string | Yes | The official skill to install. |
releaseId | string | No | Release to install or re-pin to. Omitted keeps an existing installation as is, or installs latest. |
audience | personal | workspace | Yes | Personal installs it for you; Workspace for everyone. |
visibility.installable must be exactly true. An absent visibility object or an absent installable flag means not installable (403 forbidden / official_not_installable). A skill-scope runtime block refuses install even while the source is not_populated. Production currently returns 404 official_source_not_populated.
Re-pin arms:
| Existing row | releaseId | Result |
|---|---|---|
| None | any | Insert. changed: true. |
| Active, same release | omitted or equal | No-op. changed: false. |
| Active, different release | a different id | Re-pin after assertInstallable. Bumps version and restamps installer fields. changed: true. Same installationId. |
Install takes no expectedVersion. Two concurrent re-pins naming different releases are last-write-wins. Run pins are untouched: a conversation stays on the bundle it loaded. An uninstall holding the pre-re-pin expectedVersion is refused as stale.
Example
curl -X POST https://api.parcelengineering.com/api/v1/workspace/skills/install \ -H "Authorization: Bearer pcl_your_api_key" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: install-skill-001" \ -d '{ "officialSkillId": "8a1f3c2e-0001-4b7d-9e5a-000000000020", "audience": "workspace" }'const response = await fetch( 'https://api.parcelengineering.com/api/v1/workspace/skills/install', { method: 'POST', headers: { 'Authorization': 'Bearer pcl_your_api_key', 'Content-Type': 'application/json', 'Idempotency-Key': 'install-skill-001', }, body: JSON.stringify({ officialSkillId: '8a1f3c2e-0001-4b7d-9e5a-000000000020', audience: 'workspace', }), });
const { data, metadata } = await response.json();Uninstall an Official Skill
POST https://api.parcelengineering.com/api/v1/workspace/skills/uninstallDeactivates an official skill installation. Uninstall is exempt from skill-scope runtime blocks so a block cannot strand an existing installation. A Spec run that already pinned the official release can still read those bytes for the rest of the run.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
installationId | string | Yes | The installation to deactivate. |
expectedVersion | integer | Yes | Installation version you last read. A mismatch is 409 revision_conflict / stale_version. A re-pin bumps this version, so an uninstall holding the pre-re-pin value is refused as stale. |
Example
curl -X POST https://api.parcelengineering.com/api/v1/workspace/skills/uninstall \ -H "Authorization: Bearer pcl_your_api_key" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: uninstall-skill-001" \ -d '{ "installationId": "8a1f3c2e-0001-4b7d-9e5a-000000000012", "expectedVersion": 1 }'const response = await fetch( 'https://api.parcelengineering.com/api/v1/workspace/skills/uninstall', { method: 'POST', headers: { 'Authorization': 'Bearer pcl_your_api_key', 'Content-Type': 'application/json', 'Idempotency-Key': 'uninstall-skill-001', }, body: JSON.stringify({ installationId: '8a1f3c2e-0001-4b7d-9e5a-000000000012', expectedVersion: 1, }), });
const { data, metadata } = await response.json();