# BI dashboards API reference

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

BI dashboards: Power BI, Tableau and signed-in web page connections and views. This group has 14 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.

## BI dashboards: Power BI, Tableau and signed-in web page connections and views

### GET /api/bi-connections

**List BIConnections**

Lists the project's BI connections, oldest first, 200 to a page; pass next_cursor back as cursor for the next. A secret is never returned: secret shows whether it is set and its last 4 characters.


Operation: listBIConnections.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| cursor | query | optional | next_cursor of the previous page. |
| limit | query | optional |  |

#### Request template

~~~sh
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-connections'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | One page of connections. | BIConnectionList (application/json); headers: Cache-Control |
| 400 | invalid_request, including a malformed cursor. | 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 /api/bi-connections

**Create BIConnection**

Adds a connection to a BI system the project owns. For Grafana: its address (http or https on a public host, with an optional path prefix) and a service-account token with the Viewer role. The token is sealed and never returned.

Grafana renders dashboards for screens through its Image Renderer plugin or remote rendering service, so the customer installs one; run POST /api/bi-connections/{id}/test to check. For Power BI (kind powerbi): config.tenant_id and config.client_id of a Microsoft Entra app registration and its client secret value as secret.

A Power BI admin must turn on the Developer settings Embed content in apps and Service principals can call Fabric public APIs for the app (admin portal, Tenant settings), the app must be a Member or Admin of each workspace it shows, and reports need an Embedded, Fabric or Premium capacity for production use.

For Tableau (kind tableau): config.url (the https address of Tableau Server, or of your Tableau Cloud pod such as https://10ay.online.tableau.com), config.site (the site content URL, empty for the default site), config.client_id and config.secret_id of a connected app with direct trust, config.username (the Tableau user the screens views are shown as) and the secret value as secret.

Add the answer embed_origin to the connected app domain allowlist and enable the secret. Anyone holding a screen ticket can embed any view that user can see, so use a user that sees only screen dashboards. Tableau Cloud, or Tableau Server 2023.3 or later.

For a signed-in web page (kind web): the service account of a site that shows its dashboard behind a sign-in. config.login_mode is auto (config.login_url, config.username and the password as secret: the renderer opens the sign-in page and fills the form), steps (config.login_url and config.steps, a script of goto, fill, click, press, wait_for and wait_ms steps whose values may hold {{username}}, {{password}} and {{otp}}) or none (no sign-in: the connection shows pages with the cookies you give it). totp_secret is the base32 key, or the otpauth:// address, of the account's authenticator app: the server computes the one-time code (RFC 6238) and sends the renderer only the code. cookies is a cookie jar exported from a signed-in browser, for a site whose sign-in cannot be scripted (single sign-on that approves on a phone, a device check); the server keeps the jar and renews it from the cookies each capture returns, so a sign-in is rare.

The password, the seed and the cookies are sealed and never returned. Use a read-only service account. The password is typed only into config.login_url and the goto steps, so moving those to another origin needs secret again. After five refused sign-ins in a row the connection stops signing in until its credentials change.

A server with no page renderer answers bi_web_unavailable. Appends bi_connection.created. An exact retry with the same Idempotency-Key returns this same answer.


Operation: createBIConnection.

- Authentication: projectBearer OR dashboardSession
- Request body: BIConnectionWrite

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| name | required | string | minLength: 1 maxLength: 80 |
| kind | required | string | Allowed: "grafana", "powerbi", "tableau", "web" |
| config | required | BIConnectionConfig |  |
| secret | optional | string | Required except for web, and for a Power BI connection that names connection_id. The service-account token (Grafana), the app's client secret value (Power BI), the connected app's secret value (Tableau) or the service account's password (web: required by login_mode auto, not used by none). Sealed on arrival; the CLI reads it from a file or stdin, never an argument. minLength: 1 maxLength: 4096 |
| totp_secret | optional | string | Web: the base32 key of the account's authenticator app (16 to 128 characters, spaces allowed), or its otpauth://totp address, which may set the algorithm (SHA1, SHA256, SHA512), the digits (6 to 8) and the period. Sealed; only the computed code leaves the server. maxLength: 1024 |
| cookies | optional | array | Web: a cookie jar exported from a signed-in browser. Sealed; renewed from every capture. |

#### Request template

~~~sh
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/bi-connections'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 201 | Created. | BIConnection (application/json); headers: ETag, Cache-Control |
| 400 | invalid_request, including an address that is not a public Internet host. | Problem (application/problem+json) |
| 402 | feature_not_in_plan — the project's plan does not include BI dashboards; required_plan names the plan that does. | Problem (application/problem+json) |
| 409 | idempotency_mismatch, or bi_web_unavailable for a web connection on a server with no page renderer. | 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) |

### GET /api/bi-connections/{id}

**Get BIConnection**

One connection, with its last test.


Operation: getBIConnection.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |

#### Request template

~~~sh
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-connections/RESOURCE_ID'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | One connection. | BIConnection (application/json); headers: ETag, Cache-Control |
| 404 | not_found. | 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) |

### PATCH /api/bi-connections/{id}

**Update BIConnection**

Changes a connection's name, address, organization or secret (a sent secret replaces it; an omitted one is kept). Moving a Grafana or Tableau connection to another origin (scheme, host or port) needs the secret in the same request, answered invalid_request at secret otherwise: the stored secret is only sent to the address it was saved for.

A changed address or secret clears last_test and retires every render cached for its views. Appends bi_connection.updated. If-Match guards the revision.


Operation: updateBIConnection.

- Authentication: projectBearer OR dashboardSession
- Request body: BIConnectionPatch

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| If-Match | header | optional | Optional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict. |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| name | optional | string | minLength: 1 maxLength: 80 |
| config | optional | BIConnectionConfig |  |
| secret | optional | string | Replaces the stored secret. On a web connection an empty string removes the password. maxLength: 4096 |
| totp_secret | optional | string | Web: replaces the TOTP secret; an empty string removes it. maxLength: 1024 |
| cookies | optional | array | Web: replaces the cookie jar; an empty list removes it. |

#### Request template

~~~sh
curl --request PATCH --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/bi-connections/RESOURCE_ID'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | The updated connection. | BIConnection (application/json); headers: ETag, Cache-Control |
| 400 | invalid_request. | Problem (application/problem+json) |
| 402 | feature_not_in_plan — the project's plan does not include BI dashboards; required_plan names the plan that does. A change that only replaces the secret (and the Tableau secret_id that goes with it) is always allowed, so a connection whose token expired stays current. | Problem (application/problem+json) |
| 412 | revision_conflict. | 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) |

### DELETE /api/bi-connections/{id}

**Delete BIConnection**

Deletes a connection that no view uses; while views use it the answer is resource_conflict naming their ids. Appends bi_connection.deleted. If-Match guards the revision.


Operation: deleteBIConnection.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| If-Match | header | optional | Optional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict. |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request template

~~~sh
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-connections/RESOURCE_ID'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 204 | Deleted. | no body |
| 409 | resource_conflict, views use the connection. | Problem (application/problem+json) |
| 412 | revision_conflict. | 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 /api/bi-connections/{id}/test

**Test BIConnection**

Calls the BI system with the connection's secret and stores the answer as last_test. For Grafana the checks are token (GET /api/search accepts it) and image_renderer (the plugin is listed; a missing plugin is a warning because a remote rendering service does not show as one).

It does not judge per-dashboard permissions, data-source health or the reachability of a remote renderer: test a view to render for real. A refusal from Grafana is a failed check, not an error.

For Power BI the checks are token (Microsoft Entra accepts the app) and workspaces (the app can list workspaces; it counts them and none fails the check, naming the workspace access step). It does not judge capacity, row-level security or access to any one report: test a view, which generates a real embed token.

For Tableau the check is signin: Tableau accepts a content-read JWT signed with the connected app secret for the connection user, and the server signs out again. It does not judge the domain allowlist, which only a screen loading a view proves, or the permissions on any view: test a view, which looks the view up as the user.


Operation: testBIConnection.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request template

~~~sh
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-connections/RESOURCE_ID/test'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | The checks. | BITestReport (application/json); headers: Cache-Control |
| 404 | not_found. | 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) |

### GET /api/bi-connections/{id}/browse

**Browse BIConnection**

Lists what the connection's token can show. Grafana: its dashboards (query searches titles; next_cursor pages), or with dashboard set that dashboard's panels (rows flattened) under dashboard.

Power BI: the workspaces the app can see (id, name; query keeps names containing it), or with workspace set that workspace's reports (id, name, embed_url) under workspace.

Tableau: the views the connection user can see (path as Workbook/View, name), 100 per page read; query keeps views whose name or path contains it, reading up to ten pages to find them, and next_cursor is the next page to read. A web connection lists nothing.


Operation: browseBIConnection.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| query | query | optional |  |
| dashboard | query | optional | A dashboard uid; lists its panels. |
| workspace | query | optional | A Power BI workspace id; lists its reports. |
| cursor | query | optional | next_cursor of the previous page. |

#### Request template

~~~sh
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-connections/RESOURCE_ID/browse'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | Dashboards or panels. | BIBrowse (application/json); headers: Cache-Control |
| 409 | bi_upstream_refused, the BI system refused the connection credentials or permissions. | Problem (application/problem+json) |
| 500 | bi_upstream_unavailable. | 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) |

### GET /api/bi-views

**List BIViews**

Lists the project's BI views, oldest first, 200 to a page; pass next_cursor back as cursor for the next. Each carries embed_url, the address an iframe primitive shows (content_fit fill); it is null where this server has no embed host.


Operation: listBIViews.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| cursor | query | optional | next_cursor of the previous page. |
| limit | query | optional |  |

#### Request template

~~~sh
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-views'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | One page of views. | BIViewList (application/json); headers: Cache-Control |
| 400 | invalid_request, including a malformed cursor. | 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 /api/bi-views

**Create BIView**

Adds a view of a connection's Grafana dashboard or one panel of it (url: a /d/{uid}/... address on the connection's host, or target), or of a Grafana public dashboard link (kind grafana and target.public_url, no connection).

Put the answer's embed_url in an iframe primitive: the server renders the dashboard as a PNG through Grafana's /render API, refreshed every refresh_s (30 to 86400, default 300) and shared by every screen of the same size; the screen never talks to Grafana. A public dashboard plays live from Grafana, which must allow embedding.

The embed page shows only a ticket the screen's manifest carries, so a view plays only on the screens of its own project.

For Power BI (kind powerbi): a report of a workspace the connection's app is a member of (url: an app.powerbi.com /groups/{workspace}/reports/{report} address, or target with workspace_id and report_id), with pages to show and rotate_s to rotate through them (pages listing two or more, or rotate_all_pages, need rotate_s of 10 to 3600; one report page needs none), and refresh_s of 0 (no refresh) or 60 to 86400 (default 300).

The page asks the server for a short-lived view-only embed token (GenerateToken, App owns data) and renews it before it expires; the screen never holds the client secret. A Power BI Publish to web link is a view without a connection (kind powerbi, target.public_url https://app.powerbi.com/view?r=...), framed as it is.

For Tableau (kind tableau): a view of the connection site (url: an address copied from Tableau, such as https://HOST/t/SITE/views/WORKBOOK/VIEW or Tableau Cloud https://HOST/#/site/SITE/views/WORKBOOK/VIEW, or Workbook/View; or target.view), optionally with target.rotate_sheets and rotate_s of 10 to 3600 to turn the workbook published sheets (rotate_s and rotate_sheets go together; rotate_sheets may be given as the whole target beside url), and refresh_s of 0 (no refresh) or 60 to 86400 (default 300).

The page asks the server for a five minute JWT with only the embed scope, signed with the connected app secret, and builds the Embedding API v3 tableau-viz from the Tableau host; the screen never holds the secret.

A Tableau Public viz is a view without a connection (kind tableau, target.public_url, rebuilt as https://public.tableau.com/views/WORKBOOK/VIEW) and takes rotate_sheets too. For a web page (kind web): a page of the web connection's site (url: an https address on a public host, with no target).

The browser on the edge opens it signed in, waits for the element wait_for when set and wait_ms milliseconds (up to 10000), and draws clip, a CSS selector, when set, else the whole page.

The image is drawn every refresh_s (60 to 86400, default 300) and shared by every screen of the same size, and only while a screen shows the view; when a capture fails the last image stays on glass. Set wait_for to an element that exists only when the page is signed in, so a sign-in page is never shown. Appends bi_view.created.


Operation: createBIView.

- Authentication: projectBearer OR dashboardSession
- Request body: BIViewWrite

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| connection_id | optional | string |  |
| kind | optional | string | Required without a connection_id; otherwise it must match the connection. Allowed: "grafana", "powerbi", "tableau", "web" |
| name | required | string | minLength: 1 maxLength: 80 |
| url | optional | string | A /d/{uid}/... dashboard address on the connection's host. The server reads orgId, viewPanel (N or panel-N) or panelId, from, to, var-* and theme from it. Tableau: a view address on the connection's host (/views/W/V, /t/SITE/views/W/V, #/site/SITE/views/W/V) or Workbook/View. Web: the page's https address on a public host. maxLength: 2048 |
| target | optional | BITarget | What a view shows. Grafana with a connection: dashboard_uid (and optionally one panel). Power BI with a connection: workspace_id and report_id, with pages or rotate_all_pages. Tableau with a connection: view (Workbook/View), with rotate_sheets. Web with a connection: url. Without a connection: only public_url (and rotate_sheets for Tableau). |
| refresh_s | optional | integer | Grafana 30 to 86400; Power BI and Tableau 0 or 60 to 86400; web 60 to 86400. default: 300 minimum: 0 maximum: 86400 |
| rotate_s | optional | integer | Power BI and Tableau: 0 or 10 to 3600; required for a target that rotates pages or sheets. default: 0 minimum: 0 maximum: 3600 |
| fit | optional | string | Allowed: "contain", "cover", "fill" default: "contain" |
| wait_for | optional | string | Web: a CSS selector of an element that shows when the page is ready, and only when it is signed in. maxLength: 512 |
| wait_ms | optional | integer | Web: milliseconds to wait after the page is ready. minimum: 0 maximum: 10000 |
| clip | optional | string | Web: a CSS selector of the part of the page to draw. maxLength: 512 |

#### Request template

~~~sh
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/bi-views'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 201 | Created. | BIView (application/json); headers: ETag, Cache-Control |
| 400 | invalid_request, including a url that is not a dashboard address of the connection. | Problem (application/problem+json) |
| 402 | feature_not_in_plan — the project's plan does not include BI dashboards; required_plan names the plan that does. | Problem (application/problem+json) |
| 404 | not_found, the connection is not in this project. | Problem (application/problem+json) |
| 409 | idempotency_mismatch. | 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) |

### GET /api/bi-views/{id}

**Get BIView**

One view, with embed_url and how it last fared on glass (status).


Operation: getBIView.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |

#### Request template

~~~sh
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-views/RESOURCE_ID'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | One view. | BIView (application/json); headers: ETag, Cache-Control |
| 404 | not_found. | 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) |

### PATCH /api/bi-views/{id}

**Update BIView**

Changes a view's name, target (url or target replaces the whole target), cadence or fit. A new target clears status, and every render cached for the old one is retired. A view keeps its connection and kind. Appends bi_view.updated. If-Match guards the revision.


Operation: updateBIView.

- Authentication: projectBearer OR dashboardSession
- Request body: BIViewPatch

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| If-Match | header | optional | Optional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict. |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request body fields

| Field | Required? | Type | Description |
| --- | --- | --- | --- |
| name | optional | string | minLength: 1 maxLength: 80 |
| url | optional | string | maxLength: 2048 |
| target | optional | BITarget | What a view shows. Grafana with a connection: dashboard_uid (and optionally one panel). Power BI with a connection: workspace_id and report_id, with pages or rotate_all_pages. Tableau with a connection: view (Workbook/View), with rotate_sheets. Web with a connection: url. Without a connection: only public_url (and rotate_sheets for Tableau). |
| refresh_s | optional | integer | minimum: 0 maximum: 86400 |
| rotate_s | optional | integer | minimum: 0 maximum: 3600 |
| fit | optional | string | Allowed: "contain", "cover", "fill" |
| wait_for | optional | string | Web: an empty string removes it. maxLength: 512 |
| wait_ms | optional | integer | Web: 0 removes it. minimum: 0 maximum: 10000 |
| clip | optional | string | Web: an empty string removes it. maxLength: 512 |

#### Request template

~~~sh
curl --request PATCH --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/bi-views/RESOURCE_ID'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | The updated view. | BIView (application/json); headers: ETag, Cache-Control |
| 400 | invalid_request. | Problem (application/problem+json) |
| 402 | feature_not_in_plan — the project's plan does not include BI dashboards; required_plan names the plan that does. | Problem (application/problem+json) |
| 412 | revision_conflict. | 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) |

### DELETE /api/bi-views/{id}

**Delete BIView**

Deletes a view. A screen that still shows its embed_url answers not_found on glass until its playlist changes. Appends bi_view.deleted. If-Match guards the revision.


Operation: deleteBIView.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| If-Match | header | optional | Optional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict. |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request template

~~~sh
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-views/RESOURCE_ID'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 204 | Deleted. | no body |
| 412 | revision_conflict. | 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 /api/bi-views/{id}/test

**Test BIView**

Renders a connection view for real (1920x1080, outside the shared cache and without touching status), or fetches a public dashboard link and checks that its page may be framed by the view's embed host (allow_embedding in Grafana). It does not judge what the picture shows. A Grafana failure is a failed check, not an error.

A Power BI connection view generates a real embed token for its report (checks report and embed_token); it does not judge the pages it names, capacity or what the report shows, and a dataset with row-level security is refused by Power BI with its own message, shown in the check. A Power BI public link is fetched and its framing headers read.

A Tableau connection view signs in as the connection user and looks the view up (checks signin and view); it does not judge the domain allowlist, the embed permission or what the view shows. A Tableau Public view asks Tableau Public whether the workbook exists and does not judge the view name.


Operation: testBIView.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| Idempotency-Key | header | optional | Omit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically. |

#### Request template

~~~sh
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-views/RESOURCE_ID/test'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | The checks. | BIViewTest (application/json); headers: Cache-Control |
| 404 | not_found. | 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) |

### GET /api/bi-views/{id}/image

**Get BIView Image**

Draws a Grafana or web view now as a PNG (a Power BI or Tableau view answers not_found), outside the shared cache, so a test shows exactly what Grafana or the browser renders at that size. The embed page itself uses the shared render.


Operation: getBIViewImage.

- Authentication: projectBearer OR dashboardSession
- Request body: none

#### Parameters

| Name | Send in | Required? | Description |
| --- | --- | --- | --- |
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| id | path | required |  |
| width | query | optional |  |
| height | query | optional |  |

#### Request template

~~~sh
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/bi-views/RESOURCE_ID/image'
~~~

#### Responses

| Status | Meaning | Body and headers |
| --- | --- | --- |
| 200 | The rendered PNG. | string (image/png); headers: Cache-Control |
| 409 | bi_upstream_refused, the BI system refused the connection credentials or permissions. | Problem (application/problem+json) |
| 500 | bi_upstream_unavailable, including a Grafana without an image renderer. | 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) |


## Sitemap

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