Workspace API
Upsert View
Create or update shared workspace Views with POST /workspace/views/upsert and /upsert/batch.
POST https://api.parcelengineering.com/api/v1/workspace/views/upsertPOST https://api.parcelengineering.com/api/v1/workspace/views/upsert/batchCreates a new shared View or updates an existing one. dataset and view_type are immutable after create. Dynamic definitions use the web filter FilterState grammar — not SearchRequest. See Workspace Views.
Upsert costs 0 credits. Requires workspace:write.
The Workspace API requires the Pro plan. A request from a non-Pro workspace or a non-member receives 403 forbidden.
Create body
Provide name, dataset, view_type, and definition. Optional presentation. For a Static single create only, optional initial_record_ids (1–100 UUIDs) seeds membership in the same transaction:
- Zero valid IDs: nothing is created (
400 no_valid_records). - One or more valid IDs: the View and valid memberships are created together; invalid IDs appear in per-item
results.
initial_record_ids is not accepted on /upsert/batch. To seed more than 100 records, create with the first 100 and call Add View Records.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Trimmed, non-empty; case-insensitively unique per workspace + dataset. |
dataset | account | contact | project | Yes | Immutable. |
view_type | dynamic | static | Yes | Immutable. |
definition | object | Yes | Dynamic: { version: 1, q, fields }. Static: { version: 1 }. |
presentation | object | No | TanStack sorting / column visibility. |
initial_record_ids | string[] (UUID) | No | Static single create only. Max 100. |
Update body
| Field | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Existing View. |
expected_revision | integer ≥ 1 | Yes | Optimistic concurrency. Mismatch → 409 view_conflict. |
name | string | No | Rename. |
definition | object | No | Must match the View’s type/dataset. |
presentation | object | No | Replace presentation. |
Sending dataset or view_type on update is rejected.
Batch
POST /workspace/views/upsert/batch takes { "inputs": [ ... ] } with 1–100 create or update items (no initial_record_ids). Results are ordered; one failure never aborts the rest. See Batch Writes.
Example
curl -X POST https://api.parcelengineering.com/api/v1/workspace/views/upsert \ -H "Authorization: Bearer pcl_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "name": "Tier 1 architects", "dataset": "account", "view_type": "dynamic", "definition": { "version": 1, "q": "architect", "fields": { "account_type": ["architect"], "icp_tier": ["tier_1"], "atlas_score": { "min": "60" } } } }'const response = await fetch( 'https://api.parcelengineering.com/api/v1/workspace/views/upsert', { method: 'POST', headers: { 'Authorization': 'Bearer pcl_your_api_key', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Tier 1 architects', dataset: 'account', view_type: 'dynamic', definition: { version: 1, q: 'architect', fields: { account_type: ['architect'], icp_tier: ['tier_1'], atlas_score: { min: '60' }, }, }, }), });
const { data, metadata } = await response.json();Response
{ "data": { "view": { "id": "a1b2c3d4-0001-4e8d-bf6a-000000000001", "workspace_id": "w1e2f3a4-0001-4b7c-9e5d-000000000001", "dataset": "account", "view_type": "dynamic", "name": "Tier 1 architects", "definition": { "version": 1, "q": "architect", "fields": { "account_type": ["architect"], "icp_tier": ["tier_1"], "atlas_score": { "min": "60" } } }, "presentation": { "version": 1, "sorting": [], "column_visibility": {} }, "revision": 1, "created_by": null, "updated_by": null, "created_at": "2026-07-01T12:00:00.000Z", "updated_at": "2026-07-01T12:00:00.000Z" } }, "metadata": { "credits": 0 }}Static create with initial_record_ids also returns data.results (per-ID membership outcomes) and metadata.succeeded / metadata.failed.
Errors
| Code | Status | When |
|---|---|---|
invalid_view_definition | 400 | Bad definition (including nested SearchRequest). |
view_name_conflict | 409 | Case-insensitive name already used for that dataset. |
view_conflict | 409 | expected_revision mismatch. |
view_not_found | 404 | Update target missing. |
no_valid_records | 400 | Static seed had zero valid IDs. |