Viewcast On Demand asset lifecycle
Recipes for creating, listing, summarizing, reading, refining, and archiving Viewcast On Demand assets, with identifier semantics and the customer object shape.
This page covers the CRUD lifecycle of a Viewcast On Demand asset: create, list, filter, summarize, read, refine, and archive. For the credit costs associated with each operation, see Purchase flow and credits. For the measurement queue and poll contract, see Measurements.
All endpoints are on the v2 base https://api2.mworks.com. The base per-endpoint cost is 1 credit (viewcast_asset_crud); measurement purchases carry additional credits. Full request and response schemas are in the Viewcast API reference.
Identifier semantics
Every asset carries two identifiers with distinct issuance rules:
asset_id: a Supabase-issued String (for examplevcaJDVDYWSSMHAXVEFYW1DVD2PPFD). It is assigned at creation and is stable for the life of the asset. All CRUD and measurement endpoints key offasset_id.viewshed_id: a Motionworks-issued String. It is minted only when the asset reachesfinal_measured. Before that state,viewshed_idis absent. Once minted, it makes the asset joinable to the broader Viewcast inventory surface (including Viewcast Profiles).
This split exists because an asset in draft or draft_measured state is not yet a published viewshed. The viewshed_id is the join key to the published inventory world.
The customer object
The create request includes a customer object describing the display being measured. The shape includes:
| Field | Type | Meaning |
|---|---|---|
anchor | Object | Latitude/longitude point for the face (the reference anchor used for viewshed construction) |
classification | String | Roadside or Place-Based (immutable after creation) |
face_orientation | Float | Direction of the face in degrees (0 = north, 180 = south) |
face_height | Float | Height of the face in inches |
face_width | Float | Width of the face in inches |
digital | Boolean | Whether the face is a digital display |
The anchor and display attributes can be refined after creation (subject to the 100 m guardrail below). The classification field is immutable: once set at creation, a PATCH that changes it returns 400.
Create an asset
POST /v2/viewcast/assets
Creation is asynchronous. The endpoint returns 202 Accepted and requires an Idempotency-Key header. Supply a unique key (a UUID is recommended) so that a network retry does not create a duplicate asset.
curl -X POST https://api2.mworks.com/v2/viewcast/assets \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $UUID" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"anchor": { "lat": 34.0901, "lng": -118.3839 },
"classification": "Roadside",
"face_orientation": 180.0,
"face_height": 120.0,
"face_width": 240.0,
"digital": false
}
}'Response (202):
{
"asset_id": "vcaJDVDYWSSMHAXVEFYW1DVD2PPFD",
"state": "draft",
"row_version": 1
}Idempotency replay: if you replay the same Idempotency-Key, the API returns the original 2xx result with the same asset_id. The duplicate-face check (409) is recomputed deterministically on each call, so a genuine duplicate is still rejected; a safe retry of the same request returns the cached success.
List and filter assets
GET /v2/viewcast/assets
Supports filtering by state and classification. Returns a paginated list of assets.
curl https://api2.mworks.com/v2/viewcast/assets?state=draft \
-H "Authorization: Bearer $TOKEN"Common query parameters include state (draft, draft_measured, final_measured) and classification (Roadside, Place-Based). Verified filters: state and classification both correctly narrow the result set (confirmed in E2E testing, MA-99, 2026-08-30).
Summary counts
GET /v2/viewcast/assets/summary
Returns aggregate counts of assets by state. Useful for dashboards and for confirming that create and archive operations moved counts as expected. Verified: summary counts track create and archive operations in real time (MA-99).
Read a single asset
GET /v2/viewcast/assets/{asset_id}
Returns the full asset record, including current state, display attributes, row_version, and (if present) the viewshed_id.
curl https://api2.mworks.com/v2/viewcast/assets/vcaJDVDYWSSMHAXVEFYW1DVD2PPFD \
-H "Authorization: Bearer $TOKEN"Refine an asset
PATCH /v2/viewcast/assets/{asset_id}
You can update the anchor location and display attributes while the asset is in draft state (and before a final measurement is purchased). Two guardrails apply:
- 100 m anchor-move limit: the new anchor must be within 100 m (haversine distance) of the existing anchor. A PATCH that moves the anchor farther returns 400.
- Classification immutability:
classificationcannot be changed after creation. A PATCH that attempts to change it returns 400.
The PATCH uses optimistic concurrency via row_version: include the current row_version in the request. If the asset was modified by another caller since your last read, the PATCH returns 409 (stale version).
curl -X PATCH https://api2.mworks.com/v2/viewcast/assets/$ASSET_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"row_version": 1,
"customer": {
"anchor": { "lat": 34.0902, "lng": -118.3840 },
"face_height": 130.0
}
}'Response (200): the updated asset record with an incremented row_version.
Verified (MA-99): a PATCH within 100 m returns 200; a PATCH that changes classification returns 400; a PATCH that toggles publication state while in draft returns 400.
Archive an asset
DELETE /v2/viewcast/assets/{asset_id}
Archives the asset. After deletion, a GET on the same asset_id returns 404. The archive is reflected immediately in summary counts.
curl -X DELETE https://api2.mworks.com/v2/viewcast/assets/$ASSET_ID \
-H "Authorization: Bearer $TOKEN"Response: 204 No Content. A subsequent GET returns 404.
Verified (MA-99): DELETE returns 204 and an immediate GET returns 404; summary counts decrement accordingly.
What to read next
Updated about 3 hours ago
