# Website demos API reference

> Canonical HTML: https://screenrig.ai/docs/api/website-demos
> Source SHA-256: e0c997a2ab813502f0d99a41d2ed1d3d6b26dbaf1a3d7e514c1cce0278ff8422

Website demo requests and bookings. This group has 7 operations, each with its authentication, parameters, request body fields, request template and responses. The [API overview](https://screenrig.ai/docs/api.md) covers services, authentication, requests and retries, problem codes and versioning.

Replace uppercase placeholders. Save a schema-valid JSON body in request.json when required. Cookie examples use a local cookie jar from an authenticated session.

## Website demo requests and bookings

### POST /website/demo-requests

**Submit Website Demo Request**

Same-origin anonymous website intake. Saves the request and independent delivery jobs before classification. Idempotency-Key is an independently random private retry UUID, retained only in browser memory. It is not the public flow_id. Matching retries set the same HttpOnly screenrig_demo cookie and return the saved request without another submission.

Requests and responses are excluded from payload logging. Country does not select a timezone. No project or dashboard login is created.


Operation: submitWebsiteDemoRequest.

- Authentication: none
- Request body: DemoRequestInput

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| Origin | header | required | Same-origin browser request; configured stage origin is accepted on stage. |
| Idempotency-Key | header | required |  |
| f | query | optional | Nonsecret funnel attempt ID, identical to body flow_id. |
| src | query | optional | Allowlisted source, identical to body source. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| email | required | string | maxLength: 254 format: "email" |
| country | required | string | ISO 3166-1 country code; retained separately from timezone. pattern: "^[A-Z]{2}$" |
| screen_range | required | string | Allowed: "1_10", "11_50", "51_250", "251_plus", "unknown" |
| organization | required | string | Allowed: "small_mid", "large_corporation", "agency_network" |
| budget | required | string | Self-reported annual signage budget in USD. Allowed: "under_2995", "2995_19994", "19995_plus", "unknown" |
| timezone | required | string | IANA timezone, or empty when browser detection is unavailable; scheduling requires explicit timezone. maxLength: 100 |
| source | required | DemoSource | Allowed: "home_hero", "home_paid_plans", "pricing_plus", "pricing_education", "pricing_premium", "pricing_enterprise", "resellers", "direct" |
| flow_id | required | string | Random nonsecret analytics attempt ID, never authorization. pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" |

#### Request template

~~~sh
curl --request POST --cookie-jar cookies.txt --header 'Origin: https://screenrig.ai' --header 'Idempotency-Key: REQUEST_ID' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/website/demo-requests'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 201 | Request durably saved. Sets private demo session cookie. | DemoResult (application/json) |
| 200 | Matching idempotent replay of the saved request. | DemoResult (application/json) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |

### GET /website/demo-request

**Get Website Demo Request**

Cookie-bound saved request. A request ID or public flow ID does not grant access. No-store.


Operation: getWebsiteDemoRequest.

- Authentication: demoSession
- Request body: none

#### Request template

~~~sh
curl --request GET --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/website/demo-request'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | Saved demo request and booking state. | DemoResult (application/json) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |

### GET /website/demo-calendar

**Get Website Demo Calendar**

Private calendar download for this browser's confirmed booking. Rechecks the saved event; no request ID or public flow ID grants access. No-store.


Operation: getWebsiteDemoCalendar.

- Authentication: demoSession
- Request body: none

#### Request template

~~~sh
curl --request GET --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/website/demo-calendar'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | Importable calendar event with stable identity and confirmed times. | string (text/calendar) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |

### GET /website/demo-slots

**Get Website Demo Slots**

Up to four real available 30-minute slots, varied across dates and times when possible, in the visitor's editable IANA timezone. Private slot IDs are returned in the JSON body and never sent in URL queries. Unconfigured calendar or no reasonable timezone overlap returns an empty list.


Operation: getWebsiteDemoSlots.

- Authentication: demoSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| timezone | query | required |  |
| refresh | query | optional | Offer alternatives to the previous cookie-bound batch. |

#### Request template

~~~sh
curl --request GET --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/website/demo-slots?timezone=TIMEZONE'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | Real available slots or an empty list. | DemoSlots (application/json) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |

### POST /website/demo-bookings

**Book Website Demo**

Rechecks a cookie-bound slot, atomically reserves host buffer cells and creates a stable event in the configured local or Google calendar. Confirmation requires the real event and saved booking. Ambiguous provider failures remain pending for durable reconciliation, without a second event or false booked page.


Operation: bookWebsiteDemo.

- Authentication: demoSession
- Request body: object

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| Origin | header | required | Same-origin browser request; configured stage origin is accepted on stage. |
| f | query | optional | Nonsecret funnel attempt ID, identical to the saved flow_id. |
| src | query | optional | Saved allowlisted source. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| slot_id | required | string | Empty only for replay of an already confirmed cookie-bound booking. pattern: "^([A-Za-z0-9_-]{20,128})?$" |
| timezone | required | string | maxLength: 100 |

#### Request template

~~~sh
curl --request POST --cookie cookies.txt --cookie-jar cookies.txt --header 'Origin: https://screenrig.ai' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/website/demo-bookings'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 201 | Calendar event and booking confirmed and saved. | DemoResult (application/json) |
| 200 | Already confirmed booking replay. | DemoResult (application/json) |
| 202 | Booking pending provider reconciliation; excluded from confirmed booking analytics. | DemoResult (application/json) |
| 409 | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |

### POST /website/demo-review

**Request Website Demo Review**

Flags the existing on-demand request for team review without another questionnaire. Late classifier replies cannot reverse this choice.


Operation: requestWebsiteDemoReview.

- Authentication: demoSession
- Request body: object

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| Origin | header | required | Same-origin browser request; configured stage origin is accepted on stage. |

#### Request template

~~~sh
curl --request POST --cookie cookies.txt --cookie-jar cookies.txt --header 'Origin: https://screenrig.ai' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/website/demo-review'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | Current saved request with review requested. | DemoResult (application/json) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |

### POST /website/demo-session

**Exchange Website Demo Invitation**

Exchanges an emailed seven-day booking invitation for a browser-only HttpOnly demo session. The website removes its invite fragment before any request and sends the token only in this private POST body, never in a URL, redirect, analytics marker or log. Multiple browser sessions may access the same invitation-bound request.


Operation: exchangeWebsiteDemoInvitation.

- Authentication: none
- Request body: object

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| Origin | header | required | Same-origin browser request; configured stage origin is accepted on stage. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| token | required | string | pattern: "^[A-Za-z0-9_-]{20,128}$" |

#### Request template

~~~sh
curl --request POST --cookie-jar cookies.txt --header 'Origin: https://screenrig.ai' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/website/demo-session'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | Cookie set and saved demo request returned. | DemoResult (application/json) |
| default | Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value. | Problem (application/problem+json) |


## Sitemap

See the [public documentation sitemap](https://screenrig.ai/sitemap.md).
