# Motionworks AI - Extended API Reference > Complete endpoint reference for AI agents and LLM tool integrations. > Version: 2.0.0 | Updated: 2026-04-19 | Viewcast Profiles section corrected to the v2 surface 2026-09-05 (MA-150) ## Authentication All authenticated endpoints require an `X-API-Key` header. Obtain a sandbox key via POST /signup (no auth required). ## Base URL https://api2.mworks.com/v2 ## Rate Limits | Tier | Requests/min | Credits/month | Annual Cost | |--------------|-------------|---------------|----------------| | Sandbox | 10 | 1,000 | Free | | Professional | 100 | 50,000 | $12,000/yr | | Enterprise | 500 | 200,000 | $72,000/yr | | Strategic | 1,000 | Unlimited | Custom | Rate limit headers returned on every response: - X-RateLimit-Limit: requests allowed per minute - X-RateLimit-Remaining: requests remaining in window - X-RateLimit-Reset: epoch seconds until window resets - X-Credits-Remaining: credits remaining in billing period --- ## Endpoints ### Viewcast Profiles (v2) #### GET /v2/viewcast/profiles/{display_id} Credit cost: 1 (licensed read; the caller's org must own a measurement for the display) operationId: viewcast_profiles_get Returns the Viewcast Profile (viewshed profile) for a final_measured display asset. Path parameters: - display_id (string, required): Motionworks-issued display identifier (`dsp` + Crockford base32), minted at final publication Response: data is a ViewcastProfileView envelope; meta carries request_id and credit fields. Error contract: - 403 FEATURE_NOT_LICENSED: the caller's org owns no measurement for this display. Returned for known and unknown display_ids alike (no enumeration split). No charge. - 404: the org owns the display but profile data is not yet available (the data-service leg is being wired). No charge. Purchasing a measurement (when the org does not yet own one): #### POST /v2/viewcast/measurements/purchase/{type} Credit cost: state-conditional on asset status: 150 credits (draft), 300 credits (final), or 300 credits (direct). The 150/300 figure is the all-in total charged for the call; it includes the endpoint's 1-credit base (the handler charges the remaining 149/299 delta). - type: draft (150 cr when the asset is in state draft; queues a draft run, 202 + poll) - type: final (300 cr when the asset is in state draft_measured; queues the owned-asset final transition, 202 + poll) - type: direct (300 cr; synchronous 200, buys a measurement directly from a display_id and auto-adds the face to the caller's org) Poll a queued run with GET /v2/viewcast/measurements/{asset_id} (1 credit). Full machine-readable reference: https://www.mworks.com/docs/api/viewcast/ ### Markets #### GET /markets Credit cost: 1 List all DMA markets with profile counts. Query parameters: - include_metrics (boolean, optional): Include aggregated market metrics (default: false) Response: - data (array): Array of market objects with id, name, profile_count #### GET /markets/{id} Credit cost: 1 Market detail with aggregated metrics. Path parameters: - id (string, required): DMA market ID Response: - id (string): Market identifier - name (string): Market name - profile_count (integer): Number of measured profiles - metrics (object): Aggregated OTS, circulation, and LTS totals - media_type_breakdown (object): Profile counts by media type ### Audience Segments #### GET /segments Credit cost: 1 List available audience segments. Response: - data (array): Array of segment objects with id, name, description, category #### GET /segments/{id} Credit cost: 1 Segment detail. Path parameters: - id (string, required): Segment ID Response: - id (string): Segment identifier - name (string): Segment name - description (string): Segment description - category (string): Segment category - universe_size (integer): Estimated population in segment ### Account Management #### POST /signup Credit cost: 0 (no auth required) Create a new sandbox account. Request body (JSON): - email (string, required): Account email - company (string, required): Company name - use_case (string, optional): Intended use case description Response: - account_id (string): New account ID - api_key (string): Sandbox API key - tier (string): "sandbox" - message (string): Verification email sent notice #### POST /signup/verify Credit cost: 0 Verify email address. Request body (JSON): - token (string, required): Verification token from email #### GET /keys Credit cost: 0 List API keys for the authenticated account. #### POST /keys Credit cost: 0 Create a new API key. Request body (JSON): - name (string, required): Key label - scopes (array, optional): Permission scopes (default: ["read"]) #### POST /keys/{id}/rotate Credit cost: 0 Rotate an API key. Returns new key; old key valid for 24 hours. #### DELETE /keys/{id} Credit cost: 0 Revoke an API key immediately. ### Billing #### GET /billing/usage Credit cost: 0 Credit usage for current billing period. Response: - period_start (string): Billing period start - period_end (string): Billing period end - credits_used (integer): Credits consumed - credits_limit (integer): Credit allowance - usage_by_endpoint (object): Breakdown by endpoint #### GET /billing/credits Credit cost: 0 Current credit balance. Response: - credits_remaining (integer): Credits left in period - credits_limit (integer): Total credit allowance - resets_at (string): Next reset timestamp #### POST /billing/upgrade Credit cost: 0 Request tier upgrade. Request body (JSON): - tier (string, required): "sandbox", "professional", "enterprise", or "strategic" - billing_email (string, optional): Billing contact ### Health #### GET /health Credit cost: 0 (no auth required) API health status. Response: - status (string): "healthy" or "degraded" - version (string): API version - timestamp (string): Current server time #### GET /health/data Credit cost: 0 (no auth required) Data freshness information. Response: - latest_period (string): Most recent measurement period - profiles_updated (integer): Profiles updated in latest refresh - next_refresh (string): Expected next data refresh date - coverage.markets (integer): Number of markets covered - coverage.profiles (integer): Total measured profiles --- ## Error Codes | Code | Meaning | Retry? | |------|----------------------------|--------| | 400 | Bad request / invalid params | No | | 401 | Missing or invalid API key | No | | 403 | Insufficient permissions | No | | 404 | Resource not found | No | | 409 | Conflict (duplicate signup) | No | | 422 | Validation error | No | | 429 | Rate limit exceeded | Yes (after X-RateLimit-Reset) | | 500 | Internal server error | Yes (with backoff) | | 503 | Service unavailable | Yes (with backoff) | Error response format: ```json { "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded. Retry after 32 seconds.", "retry_after": 32 } } ``` --- ## Agent Best Practices 1. Check credits before expensive calls: Call GET /billing/credits before batch or high-credit operations. Avoid burning credits on calls that will fail at the limit. 2. Purchase once, read at base cost: a measurement purchase via POST /v2/viewcast/measurements/purchase/{type} unlocks repeat reads of the profile at GET /v2/viewcast/profiles/{display_id} for 1 credit each. 3. Filter server-side: Use query parameters (market_id, media_type, bbox, min_ots) rather than fetching broad result sets and filtering client-side. 4. Cache market and segment lists: GET /markets and GET /segments change infrequently. Cache these responses for the duration of a session. 5. Check data freshness: Call GET /health/data to verify the latest measurement period before running analysis on time-sensitive queries. 6. Handle rate limits gracefully: On 429 responses, wait the duration specified in retry_after before retrying. Do not retry immediately. --- ## MCP Tool Summary The Motionworks MCP server exposes the following tools for agent integration: - viewcast_profiles_get: Retrieve the viewshed profile for an owned display (1 credit) - list_markets: List DMA markets (1 credit) - get_market: Market detail (1 credit) - list_segments: List audience segments (1 credit) - get_segment: Segment detail (1 credit) - check_credits: Current credit balance (0 credits) - check_data_freshness: Data freshness status (0 credits) MCP server config: https://api2.mworks.com/.well-known/mcp.json --- ## Measurement Framework Motionworks uses a three-tier measurement methodology: 1. Circulation: Total persons passing within the viewable area of an OOH unit. 2. Opportunity-to-See (OTS): Subset of circulation with geometric line-of-sight to the face, adjusted for speed, dwell, and approach angle. 3. Likelihood-to-See (LTS): Modeled probability of actual visual engagement, incorporating attention factors, clutter, and environmental context. All measurements are reported at both face-level and spot-level granularity. --- ## Links - Summary: https://mworks.com/llms.txt - MCP config: https://api2.mworks.com/.well-known/mcp.json - OpenAPI spec: https://api2.mworks.com/openapi.json - Pricing: https://mworks.com/cx/pricing/calculator/ - Website: https://mworks.com