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 example vcaJDVDYWSSMHAXVEFYW1DVD2PPFD). It is assigned at creation and is stable for the life of the asset. All CRUD and measurement endpoints key off asset_id.
  • viewshed_id: a Motionworks-issued String. It is minted only when the asset reaches final_measured. Before that state, viewshed_id is 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:

FieldTypeMeaning
anchorObjectLatitude/longitude point for the face (the reference anchor used for viewshed construction)
classificationStringRoadside or Place-Based (immutable after creation)
face_orientationFloatDirection of the face in degrees (0 = north, 180 = south)
face_heightFloatHeight of the face in inches
face_widthFloatWidth of the face in inches
digitalBooleanWhether 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:

  1. 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.
  2. Classification immutability: classification cannot 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


Did this page help you?