Workspace API
Accounts
Save and annotate the global accounts you care about. Search returns only the ones you have saved to your workspace.
You save global Parcel accounts to your workspace and annotate them with your own data. Workspace account search returns only the accounts you have saved, not the full global dataset. To start tracking a new account, find it via the Data API and then upsert it by domain or id.
The Workspace API requires the Pro plan. Non-Pro requests receive a 403 forbidden response.
Fields you set
These fields are written by your team via the upsert endpoint.
| Field | Type | Notes |
|---|---|---|
icp_tier | string | null | Your ICP classification for this account. One of tier_1, tier_2, tier_3, disqualified, or null (unset). Setting this field schedules an Atlas recompute. |
workspace_status | string | null | Your workflow state for this account (for example, "active", "churned"). Any string value or null. |
notes | string | null | Free-text notes for your team. Explicit null clears the value. |
tags | string[] | Arbitrary labels. Full-replace on every write (sending ["boston"] replaces the entire tag set). |
Fields Parcel computes (read-only)
These fields are computed by Parcel based on market signals. You cannot set them directly.
| Field | Type | Notes |
|---|---|---|
atlas_score | integer | null | Atlas activity score, 0 to 100. Higher scores indicate more recent and more significant pipeline activity. null until enough signal data is available. |
atlas_trend | string | null | Direction of recent Atlas score movement: "up", "down", or "flat". null until a trend can be established. |
Setting icp_tier on an account schedules a fresh Atlas recompute so that your tier assignment is reflected in a subsequent atlas_score.
Filters
Default sort: updated_at desc
| Filter key | Type | Notes |
|---|---|---|
icp_tier | field | One of tier_1, tier_2, tier_3, disqualified. Array value = OR. |
workspace_status | field | Your workflow status string. Exact match. |
tags | field | Tag value. Array value = OR. |
name | field | Organization name. Supports fuzzy match. |
city | field | City name. exact_match: false (default) = fuzzy. |
state | field | State code, for example "MA". |
account_type | field | Matches against account_types[]. Array value = OR. |
Sort keys: updated_at, atlas_score, name, created_at
Range keys: atlas_score
icp_tier and account_type are enum-backed: a value outside the allowed set returns 400 (not zero rows), and they do not accept exact_match since a closed vocabulary is always exact. See Errors.
Relational filters
Use relational filters to match accounts based on properties of their related records.
| Key | Inner filter fields |
|---|---|
has_project | stage, primary_use, city, name, residential_units (range) |
without_project | stage, primary_use, city, name, residential_units (range) |
has_signal | signal_type, filed_at (range) |
without_signal | signal_type, filed_at (range) |
has_contact | title, name |
without_contact | title, name |
Each without_* key takes the same inner fields as its has_* twin, but matches your saved accounts with NO related record satisfying the inner criteria (NOT EXISTS) instead of at least one. See Filtering for the semantics.
Includes
Valid include keys for GET /workspace/accounts/{id}: projects, contacts, signals.
Example: GET /workspace/accounts/<id>?include=projects&include=signals
Search example
The query below finds your tier 1 accounts that have a permit_filed signal in the last 90 days, sorted by Atlas score descending.
curl -X POST https://api.parcelengineering.com/api/v1/workspace/accounts/search \ -H "Authorization: Bearer pcl_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "filters": { "icp_tier": { "value": "tier_1" }, "has_signal": { "signal_type": { "value": "permit_filed" }, "filed_at": { "gte": "2026-03-31" } } }, "sort": { "field": "atlas_score", "order": "desc" }, "limit": 25 }'const response = await fetch( 'https://api.parcelengineering.com/api/v1/workspace/accounts/search', { method: 'POST', headers: { 'Authorization': 'Bearer pcl_your_api_key', 'Content-Type': 'application/json', }, body: JSON.stringify({ filters: { icp_tier: { value: 'tier_1' }, has_signal: { signal_type: { value: 'permit_filed' }, filed_at: { gte: '2026-03-31' }, }, }, sort: { field: 'atlas_score', order: 'desc' }, limit: 25, }), });
const { data, metadata } = await response.json();{ "data": [ { "id": "8a1f3c2e-0001-4b7d-9e5a-000000000001", "name": "Acme Development Group", "account_types": ["developer"], "domains": ["acmedev.com"], "website": "https://acmedev.com", "icp_tier": "tier_1", "workspace_status": "active", "notes": "Met at BuildBoston 2025", "tags": ["boston", "developer"], "atlas_score": 87, "atlas_trend": "up" } ], "metadata": { "total": 4, "total_is_capped": false, "credits": 4 }}The data array is trimmed to one record above. A page returning 4 accounts costs 4 credits (1 per row returned).