# Get Spot Source: https://docs.framen.com/api-reference/ad-delivery/get-spot GET https://api.framen.com/v3/vendor/{org_token}/1/rt_ad/{screen_id} Request a single creative for a single playout on a specific screen. ## Get Spot Request a single creative for a single playout on a specific screen. Returns content (news or ad) along with a proof-of-play URL. This is part of the **Vendor Default API** for real-time ad serving, separate from the SMAPI CRUD endpoints. **Need a test campaign?** To set up a test campaign for your screens, contact [support@framen.com](mailto:support@framen.com) with one or multiple `screen_id` you want to test with. Your organization token (e.g., `Org_4KmTqZnWpLx`). The unique identifier of the screen requesting content. ### Response The response `data` object contains: | Field | Type | Description | | ----------- | ------- | -------------------------------------- | | `requestId` | string | Unique ID for this request | | `billable` | boolean | Whether this playout is billable | | `newsFirst` | boolean | Whether news should play before the ad | The `data` object also contains two nested content objects: **`news`** and **`ad`**. Both share the same schema: | Field | Type | Description | | ---------- | ------- | -------------------------------- | | `id` | string | Content item ID | | `title` | string | Content title | | `mimeType` | string | e.g., `text/html`, `video/mp4` | | `height` | integer | Pixel height | | `width` | integer | Pixel width | | `duration` | integer | Duration in **milliseconds** | | `url` | string | URL to fetch/render the content | | `pop` | string | Proof-of-play callback URL (GET) | The `news` object additionally contains: | Field | Type | Description | | ---------- | ------ | ----------------------------------- | | `newsType` | string | News category (e.g., `WELT_WISSEN`) | ### Request Cycle Flow 1. Player sends ad-request -> receives ad-response (containing news + ad + pop URLs). 2. Player pre-caches content. 3. Player plays the content. 4. Player fires the proof-of-play GET request. **Must happen within 1 hour** of the original request. 5. Repeat for next spot. ### Example Request ```bash theme={null} curl -X GET https://api.framen.com/v3/vendor/Org_4KmTqZnWpLx/1/rt_ad/Scr_xYz789 ``` # Proof of Play Source: https://docs.framen.com/api-reference/ad-delivery/proof-of-play Confirm that content has been displayed on a screen. ## Proof of Play The `pop` field returned in the [Get Spot](/api-reference/ad-delivery/get-spot) response is a GET URL that **must be called exactly once** after the content has been displayed. It confirms playback to FRAMEN. ### Rules * A proof-of-play URL can only be registered **once**. Subsequent calls will be ignored. * The proof-of-play request **must happen within 1 hour** of the original ad request. * If the GET request fails (network error, timeout, 5xx), retry up to 3 times with exponential backoff (e.g., 1s, 2s, 4s). Retries are safe because the server deduplicates by spot ID. ### Example After displaying the content from a Get Spot response, fire the proof-of-play URL: ```bash theme={null} curl -X GET "https://api.framen.com/pop/5Kv88XyDCkWHf4DTHeS63BmAmMjWatjZRYcWN1cWq3rm" ``` ### Proof-of-Play Dashboard Use the [Proof-of-Play Dashboard](https://metabase.framen.io/public/question/dcb346a7-1bef-48e1-9db8-1bdda0b35ff1) to monitor proof-of-play rates for your screens. Filter by `org_token` and `screen_id` to view hourly request counts, response counts, PoP counts, and PoP rates. # Authentication Source: https://docs.framen.com/api-reference/authentication How to authenticate with the Screen Manager API. All API requests require your **organization token** (`org_token`) as a path parameter. There are no additional headers or API keys required. ## Getting your token 1. Go to [dashboard.framen.com/account/orgs](https://dashboard.framen.com/account/orgs) 2. Copy your **Org ID** from the organization settings page Your token will look like this: ``` Org_4KmTqZnWpLx ``` ## Using the token Include your organization token as a path parameter in all API requests: ```bash theme={null} curl -X GET "https://api.framen.com/vendor/Org_4KmTqZnWpLx/locations" ``` For a POST request to create a location: ```bash theme={null} curl -X POST "https://api.framen.com/vendor/Org_4KmTqZnWpLx/locations" \ -H "Content-Type: application/json" \ -d '{ "name": "Downtown Mall", "latitude": 40.7128, "longitude": -74.0060, "venue_type_id": "205" }' ``` Keep your organization token confidential. Treat it like a password and do not commit it to version control or share it publicly. If your token is compromised, contact [support@framen.com](mailto:support@framen.com) immediately. # Approve a creative Source: https://docs.framen.com/api-reference/creative-approvals/approve POST https://api.framen.com/vendor/{org_token}/cars/{car_id}/approve Approve a Creative Approval Request. ## Approve a creative Approve a Creative Approval Request, making the creative eligible for delivery on your screens. Once approved, the creative becomes available for active campaign scheduling. Your organization token (e.g., `Org_4KmTqZnWpLx`). The CAR identifier (e.g., `car_Xy7Kp2mN9qR4`). ### Request Body No request body is required. The approval action is performed based on the path parameters alone. ### Response Returns the updated CAR object with status changed to `approved` and the `updated_at` timestamp reflecting the approval action. ### Example Request ```bash theme={null} curl -X POST "https://api.framen.com/vendor/Org_4KmTqZnWpLx/cars/car_Xy7Kp2mN9qR4/approve" \ -H "Content-Type: application/json" ``` # Get a creative Source: https://docs.framen.com/api-reference/creative-approvals/get GET https://api.framen.com/vendor/{org_token}/cars/{car_id} Retrieve a single CAR by ID. Retrieve a single Creative Approval Request by its ID. Use this to fetch detailed information about a specific creative submission. Your organization token (e.g., `Org_4KmTqZnWpLx`). The CAR identifier (e.g., `car_Xy7Kp2mN9qR4`). ### Response Returns a single CAR object with complete details including the creative asset information, current status, and timestamp. | Field | Type | Description | | ------------------- | -------------- | -------------------------------------------------------------------------------------------------- | | `car_id` | string | Unique CAR identifier | | `status` | string | Current status: `pending`, `approved`, or `rejected` | | `advertiser_name` | string | Name of the advertiser | | `cities` | array | Array of targeted city names | | `countries` | array | Array of targeted country codes | | `item` | object | Creative asset object (see [Overview](/api-reference/creative-approvals/overview) for full schema) | | `rejection_reasons` | array \| null | Rejection reasons if rejected, otherwise null | | `custom_message` | string \| null | Custom rejection message if provided | | `created_on` | string | ISO 8601 creation timestamp | ### Example Request ```bash theme={null} curl -X GET "https://api.framen.com/vendor/Org_4KmTqZnWpLx/cars/car_Xy7Kp2mN9qR4" ``` ### Example Response ```json theme={null} { "car_id": "car_Xy7Kp2mN9qR4", "status": "pending", "advertiser_name": "Acme Corporation", "cities": ["Berlin", "Munich"], "countries": ["DEU"], "item": { "url": "https://assets.example.com/creatives/acme-summer-2026.mp4", "title": "Acme Summer Campaign", "width": 1920, "height": 1080, "duration": 15, "mimeType": "video/mp4", "size": 2456789, "md5": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" }, "rejection_reasons": null, "custom_message": null, "created_on": "2026-03-28T14:30:00Z" } ``` ### Error Responses | Status | Description | | ------ | --------------------------------- | | 404 | CAR not found or invalid `car_id` | # Get all active creatives Source: https://docs.framen.com/api-reference/creative-approvals/list-active GET https://api.framen.com/vendor/{org_token}/cars_active List active Creative Approval Requests forecasted for delivery. ## Get all active creatives Retrieve a list of all active Creative Approval Requests that are forecasted to deliver to your screens soon. These are approved CARs from campaigns with active schedules. ### Purpose This endpoint returns creatives that are actively scheduled or about to run on your screen network. Use this to: * **Pre-cache assets**: Download and cache creative media files before delivery * **Prepare infrastructure**: Validate asset quality and availability ahead of ad delivery * **Monitor campaigns**: Track which approved creatives are actively scheduled * **Optimize delivery**: Ensure creative assets are available locally for fast playback Your organization token (e.g., `Org_4KmTqZnWpLx`). ### Response Returns an array of approved CAR objects with active campaigns. All creatives in this response have status `approved`. ### Example Request ```bash theme={null} curl -X GET "https://api.framen.com/vendor/Org_4KmTqZnWpLx/cars_active" ``` # Get all creatives Source: https://docs.framen.com/api-reference/creative-approvals/list-all GET https://api.framen.com/vendor/{org_token}/cars List all Creative Approval Requests in your organization. ## Get all creatives Retrieve a list of all Creative Approval Requests for your organization. This includes creatives with all statuses: pending, approved, and rejected. Your organization token (e.g., `Org_4KmTqZnWpLx`). ### Response Returns an array of CAR objects. Each object contains the complete creative details, current status, and relevant timestamps. ### Response Schema Array of objects with the following properties: | Field | Type | Description | | ------------------- | -------------- | ------------------------------------------------------------------- | | `id` | string | Unique CAR identifier | | `status` | string | Current status: `pending`, `approved`, or `rejected` | | `advertiser_name` | string | Name of the advertiser | | `item` | object | Creative asset object with url, width, height, duration, mime\_type | | `rejection_reasons` | array \| null | Rejection reasons if rejected, otherwise null | | `custom_message` | string \| null | Custom rejection message if provided | | `created_at` | string | ISO 8601 creation timestamp | | `updated_at` | string | ISO 8601 last modified timestamp | ### Example Request ```bash theme={null} curl -X GET "https://api.framen.com/vendor/Org_4KmTqZnWpLx/cars" ``` # Overview Source: https://docs.framen.com/api-reference/creative-approvals/overview Review and manage Creative Approval Requests (CARs) for your organization. ## What are Creative Approval Requests (CARs)? Creative Approval Requests are a critical part of your screen network management workflow. When advertisers want to run their creatives on your screens, they submit a CAR containing the creative asset (image or video), advertiser information, and targeting details. As a screen network operator, you review these submissions and decide whether to approve or reject them based on your content standards and business requirements. ## CAR Lifecycle 1. **Pending**: A new CAR arrives in your queue with status `pending`. The advertiser has submitted a creative for review. 2. **Review**: You examine the creative asset, advertiser information, and targeting details. 3. **Decision**: You either approve the creative to make it eligible for delivery, or reject it with specific reasons. 4. **Active**: Approved creatives with active campaigns become candidates for ad delivery on your screens. ## CAR Object A Creative Approval Request contains the following properties: | Field | Type | Description | | ------------------- | -------------- | ----------------------------------------------------------- | | `car_id` | string | Unique CAR identifier (e.g., `car_Xy7Kp2mN9qR4`) | | `status` | string | Current status: `pending`, `approved`, or `rejected` | | `advertiser_name` | string | Name of the advertiser submitting the creative | | `cities` | array | Array of city names targeted by this campaign | | `countries` | array | Array of country codes targeted by this campaign | | `item` | object | The creative asset object (see below) | | `rejection_reasons` | array \| null | Array of rejection reason codes if rejected, otherwise null | | `custom_message` | string \| null | Custom message provided during rejection, if applicable | | `created_on` | string | ISO 8601 timestamp when CAR was created | ### Item Sub-Object The `item` object contains details about the media asset: | Field | Type | Description | | ---------- | ------- | -------------------------------------------------------- | | `url` | string | URL to the creative media file (image or video) | | `title` | string | Creative asset name | | `width` | integer | Width of the creative in pixels | | `height` | integer | Height of the creative in pixels | | `duration` | integer | Duration in seconds (0 for static images) | | `mimeType` | string | MIME type of the asset (e.g., `video/mp4`, `image/jpeg`) | | `size` | integer | File size in bytes | | `md5` | string | MD5 hash of the creative file | ## Example CAR Object ```json theme={null} { "car_id": "car_Xy7Kp2mN9qR4", "status": "pending", "advertiser_name": "Acme Corporation", "cities": ["Berlin", "Munich"], "countries": ["DEU"], "item": { "url": "https://assets.example.com/creatives/acme-summer-2026.mp4", "title": "Acme Summer Campaign", "width": 1920, "height": 1080, "duration": 15, "mimeType": "video/mp4", "size": 2456789, "md5": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" }, "rejection_reasons": null, "custom_message": null, "created_on": "2026-03-28T14:30:00Z" } ``` ## Active Creatives The `cars_active` endpoint returns a filtered list of approved CARs whose campaigns are forecasted to deliver to your screens soon. This is useful for **pre-caching creative assets** to your content delivery infrastructure before ads are scheduled to run. Use this endpoint periodically to: * Download and cache video/image assets locally * Validate creative quality before delivery * Prepare your screens for upcoming ad campaigns * Monitor active advertising campaigns in your network ## Next Steps Explore the Creative Approval Requests API endpoints: * [List all creatives](/api-reference/creative-approvals/list-all) * [List active creatives](/api-reference/creative-approvals/list-active) * [Get a creative](/api-reference/creative-approvals/get) * [Approve a creative](/api-reference/creative-approvals/approve) * [Reject a creative](/api-reference/creative-approvals/reject) # Reject a Creative Source: https://docs.framen.com/api-reference/creative-approvals/reject POST https://api.framen.com/vendor/{org_token}/cars/{car_id}/reject Reject a creative approval request (CAR) with one or more rejection reasons. ## Reject a Creative Reject a creative approval request (CAR) with one or more rejection reasons. Once rejected, the advertiser is notified and can submit a revised creative. Your organization token (e.g., `Org_4KmTqZnWpLx`). [Find it here](https://dashboard.framen.com/account/orgs). The unique identifier of the creative approval request (e.g., `car_Xy7Kp2mN9qR4`). Array of one or more rejection reason codes. Valid values: `ADVERTISER`, `INAPPROPRIATE`, `FILTER`, `CUSTOM`. A custom rejection message. **Required** when `CUSTOM` is included in `rejection_reasons`. ### Rejection Reasons | Code | Description | | --------------- | ------------------------------------------------------- | | `ADVERTISER` | The advertiser is not approved to run on your network | | `INAPPROPRIATE` | The creative content is inappropriate for your venues | | `FILTER` | The creative does not meet your content filter criteria | | `CUSTOM` | Custom reason -- requires a `custom_message` | ### Example Request ```bash theme={null} curl -X POST "https://api.framen.com/vendor/Org_4KmTqZnWpLx/cars/car_Xy7Kp2mN9qR4/reject" -H "Content-Type: application/json" \ -d '{ "rejection_reasons": ["INAPPROPRIATE", "CUSTOM"], "custom_message": "Creative contains content not suitable for family-oriented venues" }' ``` ### Example Response ```json theme={null} { "id": "car_Xy7Kp2mN9qR4", "status": "rejected", "advertiser_name": "Acme Corporation", "campaign_name": "Summer Sale 2026", "rejection_reasons": ["INAPPROPRIATE", "CUSTOM"], "custom_message": "Creative contains content not suitable for family-oriented venues", "created_at": "2026-03-28T14:30:00Z", "updated_at": "2026-03-28T16:20:15Z" } ``` ## Error Responses | Status | Error | Description | | ------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | 400 | Bad Request | CAR is already approved or rejected; cannot reject an already-decided creative. Also returned if rejection\_reasons is missing or invalid. | | 401 | Unauthorized | Invalid or missing org\_token | | 404 | Not Found | CAR not found; invalid car\_id or organization does not own this CAR | | 422 | Unprocessable Entity | CUSTOM is in rejection\_reasons but custom\_message is missing or empty | | 429 | Too Many Requests | Rate limit exceeded; retry after delay | | 500 | Internal Server Error | Server error; please try again later | # Opening Hours (opening_168) Source: https://docs.framen.com/api-reference/data-formats/opening-168 Weekly opening-hours array used when creating or updating a location. The `opening_168` field is a JSON array of **168 integers** (one per hour of the week, starting Monday 00:00) that tells the FRAMEN platform when a location is open. Each element is either **`1`** (open) or **`0`** (closed). ## Structure | Index | Day | Hour | | ----- | ------- | ----- | | 0 | Monday | 00:00 | | 1 | Monday | 01:00 | | ... | ... | ... | | 23 | Monday | 23:00 | | 24 | Tuesday | 00:00 | | ... | ... | ... | | 167 | Sunday | 23:00 | ## Example A location open Monday to Friday, 08:00 -- 20:00: ```json theme={null} [ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] ``` The array must always contain exactly 168 elements. Passing fewer or more will result in a validation error. # Daily Visitors (visitors_7) Source: https://docs.framen.com/api-reference/data-formats/visitors-7 Weekly expected-visitors array used when creating or updating a location. The `visitors_7` field is a JSON array of **7 integers** — one per day of the week, starting with Monday — representing the expected number of daily visitors at a location. ## Structure | Index | Day | | ----- | --------- | | 0 | Monday | | 1 | Tuesday | | 2 | Wednesday | | 3 | Thursday | | 4 | Friday | | 5 | Saturday | | 6 | Sunday | ## Example A café that expects roughly 200 visitors on weekdays, 350 on Saturdays, and 150 on Sundays: ```json theme={null} [200, 200, 200, 200, 200, 350, 150] ``` The array must always contain exactly 7 elements. Passing fewer or more will result in a validation error. # Introduction Source: https://docs.framen.com/api-reference/introduction Welcome to the FRAMEN Screen Manager API ## Overview The FRAMEN Screen Manager API lets you programmatically manage your digital signage network. Use it to register physical locations, configure screens, control ad delivery, and manage creative approvals. ### Base URL ``` https://api.framen.com ``` ### What you can do * **Locations** — Create and manage physical venues where screens are installed * **Screens** — Register and configure individual displays within locations * **Venue Types** — Browse the classification system for your locations * **Ad Delivery** — Request ad creatives for real-time playback on screens * **Creatives** — Review and approve or reject creative assets before they go live ## Getting started 1. **Get your organization token** — See [Authentication](/api-reference/authentication) for how to find your `org_token` 2. **Create a location** — Register your first physical venue via [Create a location](/api-reference/locations/create) 3. **Add a screen** — Attach a screen to the location via [Create a screen](/api-reference/screens/create) 4. **Go live** — Once your location is approved, request ads via [Get Spot](/api-reference/ad-delivery/get-spot) All API requests use your `org_token` as a path parameter. There are no additional headers or parameters required. # Create a Location Source: https://docs.framen.com/api-reference/locations/create POST https://api.framen.com/vendor/{org_token}/locations Register a new physical location in your organization. ## Create a Location Register a new physical location in your organization. The location will initially be created with a `DRAFT` status and must be approved before screens can be deployed. Locations go through an approval process: `DRAFT -> REVIEW -> APPROVED`. Providing all "required for Review" fields automatically moves the status to `REVIEW`. FRAMEN then performs the approval. Your organization token (e.g., `Org_4KmTqZnWpLx`). Your unique identifier for this location. If not provided, one will be assigned automatically. Display name of the location. Must be a **level 2** venue type ID from the [Venue Types](/api-reference/venue-types/list) endpoint. Required for Review. Latitude coordinate (WGS84, range: -90 to 90). Required for Review. Longitude coordinate (WGS84, range: -180 to 180). Required for Review. Hourly opening schedule for one week (168 booleans). Index 0 = Monday 00:00. Required for Review. Daily visitor counts, Monday through Sunday. Required for Review. Whether the location is archived. Default: `false`. Contact email for the location. Contact phone number for the location. ### Example Request ```bash theme={null} curl -X POST https://api.framen.com/vendor/{org_token}/locations \ -H "Content-Type: application/json" \ -d '{ "location_id": "Loc_MyCustomId123", "title": "Berlin Hauptbahnhof", "venue_type_id": "205", "lat": 52.5251, "long": 13.3694, "opening_168": [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false], "visitors_7": [500, 600, 700, 800, 900, 1000, 400] }' ``` # Get a Location Source: https://docs.framen.com/api-reference/locations/get GET https://api.framen.com/vendor/{org_token}/locations/{location_id} Retrieve a single location by its ID. ## Get a Location Retrieve a single location by its ID. Your organization token (e.g., `Org_4KmTqZnWpLx`). The unique identifier of the location to retrieve. ### Response Returns the Location object with all fields populated. ### Example Request ```bash theme={null} curl -X GET https://api.framen.com/vendor/Org_4KmTqZnWpLx/locations/Loc_f9FxuWDTfzy ``` ### Example Response ```json theme={null} { "location_id": "Loc_f9FxuWDTfzy", "title": "Downtown Plaza - Main Entrance", "status": "APPROVED", "available_for_ads": true, "venue_type_id": "205", "lat": 40.7128, "long": -74.006, "opening_168": [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false], "visitors_7": [500, 600, 700, 800, 900, 1000, 400], "archived": false, "timezone": "America/New_York", "country": "USA", "region": "New York", "city": "New York", "zip": "10001", "address": "123 Main Street, New York, NY 10001", "email": "contact@example.com", "phone": "+1-555-0100" } ``` # List Locations Source: https://docs.framen.com/api-reference/locations/list GET https://api.framen.com/vendor/{org_token}/locations Retrieve all locations in your organization. ## List Locations Retrieve all locations in your organization. Your organization token (e.g., `Org_4KmTqZnWpLx`). ### Response Returns an array of Location objects. ### Example Request ```bash theme={null} curl -X GET https://api.framen.com/vendor/Org_4KmTqZnWpLx/locations ``` # Overview Source: https://docs.framen.com/api-reference/locations/overview Location object definition and approval workflow. Locations are the containers for your screens. Each location represents a physical place (mall, airport, gym, office building, etc.) where one or more screens are installed. Locations hold geo-coordinates, opening hours, and visitor estimates. They go through an approval workflow before they can receive ads. You must create a location before you can add screens to it. Screens inherit their geographic context from their parent location. ## The Location object | Field | Type | Description | | ------------------- | ------------- | --------------------------------------------------------------------------------------------------------- | | `location_id` | string | Unique identifier assigned by the system | | `title` | string | Human-readable location name | | `status` | string | Approval status: `DRAFT`, `REVIEW`, or `APPROVED` | | `available_for_ads` | boolean | Whether ads can be delivered to screens at this location | | `venue_type_id` | string | Level 2 venue type ID (see [Venue Types](/api-reference/venue-types/list)) | | `lat` | float | Latitude (-90 to 90) | | `long` | float | Longitude (-180 to 180) | | `opening_168` | boolean\[168] | Hourly open/closed schedule (see [Opening 168](/api-reference/data-formats/opening-168)) | | `visitors_7` | int\[7] | Daily visitor estimates, Monday through Sunday (see [Visitors 7](/api-reference/data-formats/visitors-7)) | | `archived` | boolean | Whether the location is hidden from the dashboard | | `timezone` | string | IANA timezone, auto-derived from coordinates (e.g., `Europe/Berlin`) | | `country` | string | ISO 3166-1 alpha-3 country code, auto-derived | | `region` | string | Region or state name, auto-derived | | `city` | string | City name, auto-derived | | `zip` | string | Postal code, auto-derived | | `address` | string | Street address, auto-derived | | `email` | string | Contact email for this location | | `phone` | string | Contact phone for this location | The fields `timezone`, `country`, `region`, `city`, `zip`, and `address` are **read-only**. They are automatically derived from `lat` and `long`. Do not include them in create or update requests. ## Approval workflow Locations go through a three-stage approval process: ``` DRAFT -> REVIEW -> APPROVED ``` | Status | Trigger | What it means | | ---------- | ----------------------------------- | ------------------------------------------------------------- | | `DRAFT` | Created without all required fields | Location is incomplete. Cannot receive ads. | | `REVIEW` | All required fields provided | Awaiting review. Cannot receive ads yet. | | `APPROVED` | Location is approved | Eligible for ad delivery. `available_for_ads` can now be set. | **Fields required for REVIEW status**: `title`, `venue_type_id`, `lat`, `long`, `opening_168`, `visitors_7`. When all of these fields are present on creation, the location skips `DRAFT` and goes directly to `REVIEW`. Updating `venue_type_id`, `lat`, or `long` on an `APPROVED` location **resets its status to `REVIEW`**. This may temporarily disrupt ad delivery to screens at that location. ## Archiving vs. disabling ads There are two ways to take a location out of active use: | Action | Effect | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | `"archived": true` | Hides the location from the dashboard. Screens remain but are effectively inactive. | | `"available_for_ads": false` | Location becomes invisible to the Ads Manager for **new** campaign targeting. Already running campaigns **continue delivering**. | To immediately stop all ad delivery at a location, set `available_for_ads: false` on each individual [screen](/api-reference/screens/overview). # Update a Location Source: https://docs.framen.com/api-reference/locations/update POST https://api.framen.com/vendor/{org_token}/locations/{location_id} Update an existing location's details. ## Update a Location Update an existing location's details. All body parameters are optional -- only include the fields you want to change. Your organization token (e.g., `Org_4KmTqZnWpLx`). The unique identifier of the location to update. Display name of the location. Must be a **level 2** venue type ID from the [Venue Types](/api-reference/venue-types/list) endpoint. Latitude coordinate (WGS84, range: -90 to 90). Longitude coordinate (WGS84, range: -180 to 180). Hourly opening schedule for one week (168 booleans). Index 0 = Monday 00:00. Daily visitor counts, Monday through Sunday. Location status. Can only be changed via `DRAFT -> REVIEW`. You cannot set it to `APPROVED` yourself. Whether the location is available for ad campaigns. Cannot be set while status is `DRAFT` or `REVIEW`. Whether the location is archived. Contact email for the location. Contact phone number for the location. If the location status is `APPROVED` and you update `venue_type_id`, `lat`, or `long`, the status will revert to `REVIEW` and must be re-approved by FRAMEN. Campaign delivery may be affected. ### Example Request ```bash theme={null} curl -X POST https://api.framen.com/vendor/Org_4KmTqZnWpLx/locations/Loc_f9FxuWDTfzy \ -H "Content-Type: application/json" \ -d '{ "title": "Berlin Hauptbahnhof - West Wing", "visitors_7": [600, 700, 800, 900, 1000, 1100, 500] }' ``` # Create a Screen Source: https://docs.framen.com/api-reference/screens/create POST https://api.framen.com/vendor/{org_token}/screens Register a new screen device at a location. ## Create a Screen Register a new screen device at a location. Each screen belongs to exactly one Location. Your organization token (e.g., `Org_4KmTqZnWpLx`). Your unique identifier for this screen. Display name of the screen. Must be the same as or a child of the parent Location's `venue_type_id`. Use values from the [Venue Types](/api-reference/venue-types/list) endpoint. Must reference an existing Location. Pixel width of the screen (e.g., `1920`). Pixel height of the screen (e.g., `1080`). Loop duration in seconds. Whether the screen is archived. Default: `false`. When `true`, the screen disappears from the Dashboard UI. Whether the screen is available for ad campaigns. Default: `true`. Number of physical screens this entry represents. Estimated weekly impressions. ### Example Request ```bash theme={null} curl -X POST https://api.framen.com/vendor/Org_4KmTqZnWpLx/screens \ -H "Content-Type: application/json" \ -d '{ "screen_id": "Scr_xYz789", "title": "Lobby Display A", "venue_type_id": "205", "location_id": "Loc_f9FxuWDTfzy", "width": 1920, "height": 1080, "loop_duration": 60 }' ``` # Get a Screen Source: https://docs.framen.com/api-reference/screens/get GET https://api.framen.com/vendor/{org_token}/screens/{screen_id} Retrieve a single screen by its ID. ## Get a Screen Retrieve a single screen by its ID. Your organization token (e.g., `Org_4KmTqZnWpLx`). The unique identifier of the screen to retrieve. ### Response Returns the Screen object with all fields populated. ### Example Request ```bash theme={null} curl -X GET https://api.framen.com/vendor/Org_4KmTqZnWpLx/screens/Scr_xYz789 ``` ### Example Response ```json theme={null} { "screen_id": "Scr_xYz789", "title": "Lobby Display A", "venue_type_id": "205", "location_id": "Loc_f9FxuWDTfzy", "width": 1920, "height": 1080, "loop_duration": 60, "archived": false, "available_for_ads": true, "amount": 1, "imps_weekly": 5000 } ``` # List Screens Source: https://docs.framen.com/api-reference/screens/list GET https://api.framen.com/vendor/{org_token}/screens Retrieve all screens in your organization. ## List Screens Retrieve all screens in your organization. Your organization token (e.g., `Org_4KmTqZnWpLx`). ### Response Returns an array of Screen objects. ### Example Request ```bash theme={null} curl -X GET https://api.framen.com/vendor/Org_4KmTqZnWpLx/screens ``` # Overview Source: https://docs.framen.com/api-reference/screens/overview Manage individual display devices within your locations. ## Screens Screens represent individual display devices deployed within a location. Each screen displays advertisements in a continuous loop and is identified by its unique configuration, including resolution and loop timing parameters. ### Key Concepts * **Screen**: A physical or virtual display device that plays a sequence of ads * **Location**: Parent location containing one or more screens * **Loop Duration**: The total time (in seconds) for one complete rotation through all queued advertisements * **Venue Type**: Classification that must match or be compatible with the parent location's venue type * **Resolution**: Pixel dimensions (width x height) of the display Before creating screens, you must first create a location. Each screen belongs to exactly one location and inherits the location's organizational context. ### Screen Object The Screen object contains all configuration and metadata for a display device: | Field | Type | Description | | ------------------- | ------- | ---------------------------------------------------------------------------------------------------------- | | `screen_id` | string | Unique identifier for the screen (client-generated, UUID format) | | `title` | string | Human-readable label for the screen (e.g., "Main Lobby Display") | | `venue_type_id` | string | Venue type classification (e.g., `"205"` for Malls); must match or be a child of the location's venue type | | `location_id` | string | ID of the parent location | | `width` | integer | Pixel width of the display resolution | | `height` | integer | Pixel height of the display resolution | | `loop_duration` | integer | Duration in seconds for one complete advertisement loop | | `archived` | boolean | Whether hidden from Dashboard. Default: `false` | | `available_for_ads` | boolean | Whether the screen accepts ad campaigns. Default: `true` | | `amount` | integer | Number of physical screens this entry represents | | `imps_weekly` | integer | Estimated weekly impressions | ### Example Screen Object ```json theme={null} { "screen_id": "d3c8dbb6-c21b-4b26-8f35-d73260c95fa1", "title": "Main Lobby Display", "venue_type_id": "602", "location_id": "Loc_f9FxuWDTfzy", "width": 1920, "height": 1080, "loop_duration": 120, "archived": false, "available_for_ads": true, "amount": 1, "imps_weekly": 12503 } ``` ### Common Use Cases * **Create a Screen**: Add a new display device to your location with specific resolution and timing parameters * **Retrieve Screen Details**: Look up configuration and metadata for a specific screen * **Update Screen Settings**: Modify display name, loop duration, or venue classification * **List Organization Screens**: View all screens deployed across your organization * **Manage Ad Content**: Use the screen ID to request and manage advertisements for that specific display ### Requirements * Parent location must exist before creating screens * Screen `venue_type_id` must be compatible with the location's venue type hierarchy * Resolution values (width/height) must be positive integers * Loop duration must be a positive integer representing seconds * The client generates the `screen_id` (UUID format). Sending a duplicate returns an error. # Update a Screen Source: https://docs.framen.com/api-reference/screens/update POST https://api.framen.com/vendor/{org_token}/screens/{screen_id} Update an existing screen's details. ## Update a Screen Update an existing screen's details. All body parameters are optional -- only include the fields you want to change. Your organization token (e.g., `Org_4KmTqZnWpLx`). The unique identifier of the screen to update. Display name of the screen. Must be the same as or a child of the parent Location's `venue_type_id`. Must reference an existing Location. Pixel width of the screen. Pixel height of the screen. Loop duration in seconds. Whether the screen is archived. Whether the screen is available for ad campaigns. Number of physical screens this entry represents. Estimated weekly impressions. Changing `location_id` will set the Location's status to `REVIEW`, even if it was previously `APPROVED`. ### Example Request ```bash theme={null} curl -X POST https://api.framen.com/vendor/Org_4KmTqZnWpLx/screens/Scr_xYz789 \ -H "Content-Type: application/json" \ -d '{ "title": "Lobby Display A - Updated", "width": 3840, "height": 2160 }' ``` # List Venue Types Source: https://docs.framen.com/api-reference/venue-types/list GET https://api.framen.com/vendor/{org_token}/venue_types Retrieve all available venue types. ## List Venue Types Retrieve all available venue types. Venue types classify locations and screens into a **3-level hierarchy**: * **Level 1** -- Category (not selectable, e.g., "Retail") * **Level 2** -- Venue type (selectable, e.g., "Grocery") * **Level 3** -- Sub-venue type (selectable, e.g., "Shop Entrance (Grocery)") The `id` values returned here are used as `venue_type_id` in both the Screens and Locations endpoints. **Constraint:** Locations must use a level 2 `venue_type_id`. Screens must use a `venue_type_id` that is either the same as their parent Location's (level 2) or one of its children (level 3). Your organization token (e.g., `Org_4KmTqZnWpLx`). ### Response Returns an array of venue type objects. | Field | Type | Description | | ------------- | -------------- | ---------------------------------------------------------------- | | `label` | string | Display name (e.g., "Grocery") | | `id` | string | Venue type ID (used as `venue_type_id` in Screens and Locations) | | `parent_id` | string \| null | ID of the parent venue type. `null` for level 1 | | `level` | integer | `1` = category, `2` = venue type, `3` = sub-venue type | | `selectable` | boolean | Whether this type can be assigned to a Location or Screen | | `description` | string \| null | Human-readable description of the venue type | ### Example Request ```bash theme={null} curl -X GET https://api.framen.com/vendor/Org_4KmTqZnWpLx/venue_types ``` ### Example Response ```json theme={null} [ { "label": "Retail", "id": "2", "parent_id": null, "level": 1, "selectable": false, "description": "These dynamic screens are strategically placed in key locations throughout shopping centers, malls, and retail districts." }, { "label": "Grocery", "id": "203", "parent_id": "2", "level": 2, "selectable": true, "description": "Digital signage is dispersed throughout supermarkets, you'll often find screens in direct view of shoppers, above cash points, at the entrance/exit, within the shelves, in the aisles and on the walls." }, { "label": "Shop Entrance (Grocery)", "id": "20301", "parent_id": "203", "level": 3, "selectable": true, "description": "As shoppers enter the supermarket, there'll usually be medium to large sized screens close to the entrance, so consumers have a prominent view of ads." }, { "label": "Check Out (Grocery)", "id": "20302", "parent_id": "203", "level": 3, "selectable": true, "description": "The till areas are where consumers pay for their purchases, and here you'll find display monitors close to the bagging area or above the self-service check out points." } ] ``` # Overview Source: https://docs.framen.com/api-reference/venue-types/overview Understand the three-level venue type taxonomy for classifying locations and screens. ## Venue Type Taxonomy Venue types form a three-level hierarchical tree used for ad targeting and location classification within the FRAMEN Screen Manager API. This taxonomy allows precise targeting of ad campaigns based on where screens are physically located and their specific placement within a venue. ### Hierarchy Structure The venue type system is organized into three distinct levels: ``` Level 1: Category (not selectable) Level 2: Location type (assign to Locations) Level 3: Screen placement (assign to Screens) ``` * **Level 1 (Category)**: Non-selectable organizational groups that serve as the top-level categorization. Examples include "Transit", "Retail", and "Hospitality". * **Level 2 (Location type)**: Venue types assigned directly to Locations. These describe the general type of physical venue (e.g., "Airport", "Shopping Mall", "Hotel"). * **Level 3 (Screen placement)**: Venue types assigned to Screens. These describe the specific placement or zone within a location (e.g., "Arrival Hall", "Food Court", "Lobby"). ### Assignment Rules Different entity types can be assigned venue types at different levels according to these rules: | Entity | Allowed levels | Rule | | -------- | -------------- | ---------------------------------------------------------------------------- | | Location | Level 2 only | Pick the venue type that best describes the physical place | | Screen | Level 2 or 3 | Must be the same as the location's type (level 2) or a child of it (level 3) | ### Parent-Child Constraint A critical validation rule ensures data integrity: **a screen's venue type must be related to its parent location's venue type via the `parent_id` field**. This means: * If a Location is assigned venue type "Airport" (Level 2), its Screens can be assigned either "Airport" (Level 2) or children like "Arrival Hall" or "Departure Lounge" (Level 3, parent\_id = "Airport"). * Cross-branch assignments are invalid. A Screen in a "Hotel" Location cannot be assigned a venue type under the "Airport" branch. ### Venue Type Object Definition Each venue type object contains the following fields: * **id** (string): Unique identifier for the venue type * **name** (string): Display name of the venue type * **level** (integer): The hierarchical level (1, 2, or 3) * **parent\_id** (string or null): The ID of the parent venue type; null for Level 1 categories ### Python Validation Logic Here's an example of how to validate venue type assignments in Python: ```python theme={null} def validate_screen_venue_type(location_venue_type, screen_venue_type, venue_types_map): """ Validate that a screen's venue type is compatible with its location's venue type. Args: location_venue_type: The venue type object assigned to the location screen_venue_type: The venue type object to be assigned to the screen venue_types_map: A dict mapping venue_type_id -> venue_type_object Returns: bool: True if valid, False otherwise """ # Location must be Level 2 if location_venue_type['level'] != 2: return False # Screen must be Level 2 or 3 if screen_venue_type['level'] not in [2, 3]: return False # If screen is Level 2, must match location if screen_venue_type['level'] == 2: return screen_venue_type['id'] == location_venue_type['id'] # If screen is Level 3, must be a child of location if screen_venue_type['level'] == 3: return screen_venue_type['parent_id'] == location_venue_type['id'] return False ``` ### Why Venue Types Matter Venue types are critical to the FRAMEN system because they directly impact: * **Ad Targeting**: Advertisers use venue types to specify where their campaigns should run, ensuring ads reach the right audience in the right context. * **Fill Rate**: Proper classification increases the likelihood that available inventory matches advertiser targeting criteria, improving fill rates and reducing unsold ad slots. * **Revenue Optimization**: Accurate venue type assignment enables better matching between supply and demand, maximizing revenue per screen. * **Campaign Performance**: Misclassified venues can result in poor audience targeting, wasted impressions, and advertiser dissatisfaction. Always ensure that locations and screens are assigned the appropriate venue types according to their physical characteristics and purpose within the broader venue hierarchy.