> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cube.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Export a dashboard as PNG or PDF

Submit a render of a published dashboard. Identify it with either `dashboardId` (numeric) or `dashboardPublicId` (string) — supply exactly one; it must belong to this deployment, otherwise `404` is returned.

Returns as soon as the job is accepted, because a render waits for every widget to finish querying. Poll `GET /dashboard-exports/{jobId}` until `status` is `completed`, then fetch the file from `GET /dashboard-exports/{jobId}/download`. The job and its file are dropped at `expiresAt` (5 minutes) — download before then or submit again.

Pass `filters`, `timeGrains` and `memberSwitchers` to render the board with specific control values, exactly as a scheduled notification does; omit them to render its saved defaults.

By default the dashboard renders under the calling user's own security context, so the file shows what that user would see. Requires **manage** access to the dashboard's workbook — the same permission the console's own "Download as PNG / PDF" actions require, because a whole-dashboard render is a bulk data export.

To export on someone else's behalf, pass `renderAs`: the queries behind the image then run under that user's security context instead of yours. **Requires the caller to be a tenant administrator.** Name a console user by `userId` or `email` (`type: USER`), or an embed user by `embedTenantName` + `externalId` (`type: EMBED_USER`). A deactivated console user is not a valid subject and returns `404`; an email is matched case-insensitively.

An embed subject is provisioned if it does not exist yet, and `groups`, `userAttributes` and `securityContext` apply to **this render only** — they are carried on the render's own session and are NOT written to the user's stored context, so exporting for someone never changes what their live embedded sessions see. (Use the embed-tenant users API to change a user's stored context.) An embed subject additionally requires the dashboard's workbook to be shared with that embed tenant, otherwise `403` is returned.

Returns `403` when the workspace has data downloads restricted — including for an on-behalf-of export, which deliberately does **not** bypass that setting the way a built-in scheduled notification does — and `429` when there are already too many exports in flight for the identity being rendered as.


## OpenAPI

````yaml /api-reference/api.yaml post /api/v1/deployments/{deploymentId}/dashboard-exports
openapi: 3.1.0
info:
  title: Cube Platform API
  version: 1.0.0
  description: >-
    Programmatically manage Cube: deployments and everything scoped to them

    (environments, folders, reports, workbooks, notifications, workspace, and
    agents),

    plus account-level users, groups, policies, embedding, and AI settings.
    Data-model

    authoring, dev mode, branches, and uploads live under /build/api/v1 — same
    host and

    token, routed to the build pods.
servers:
  - url: https://{tenant}.cubecloud.dev
    description: Your tenant host. Replace the whole host if you use a custom domain.
    variables:
      tenant:
        default: your-tenant
        description: Your Cube tenant subdomain
security:
  - bearerAuth: []
tags:
  - name: Deployments
  - name: Deployment Creation
  - name: Environments
  - name: Env Variables
  - name: Regions
  - name: Data Model
  - name: Data Model Uploads
  - name: GitHub
  - name: GitHub Connection
  - name: dbt Sync
  - name: Folders
  - name: Reports
  - name: Workbooks
  - name: Notifications
  - name: Workspace
  - name: Users
  - name: Users Admin
  - name: User Attributes
  - name: User Attribute Values
  - name: Tenant Settings
  - name: OAuth Integrations
  - name: User OAuth Tokens
  - name: OIDC Token Configs
  - name: App Theme
  - name: Embed
  - name: Embed Tenants
  - name: Dashboard Embed Access
  - name: Usage Analytics
  - name: OpenAPI Spec
  - name: Dashboard Exports
paths:
  /api/v1/deployments/{deploymentId}/dashboard-exports:
    post:
      tags:
        - Dashboard Exports
      summary: Export a dashboard as PNG or PDF
      operationId: startExport
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the dashboard.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartDashboardExportInput'
        description: StartDashboardExportInput
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DashboardExportJobResponse'
          description: ''
components:
  schemas:
    StartDashboardExportInput:
      properties:
        dashboardId:
          oneOf:
            - type: integer
            - type: 'null'
          description: >-
            Numeric id of the dashboard to export. Provide either this or
            `dashboardPublicId`, not both.
        dashboardPublicId:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Public id of the dashboard to export. Provide either this or
            `dashboardId`, not both.
        filters:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardFilterInput'
              type: array
            - type: 'null'
          description: >-
            Dimension filters applied to the dashboard while it renders. Same
            shape the scheduled-notification API uses.
        format:
          $ref: '#/components/schemas/StartDashboardExportInputFormat'
        memberSwitchers:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardMemberSwitcherInput'
              type: array
            - type: 'null'
          description: Field-switcher selections applied to the dashboard while it renders.
        renderAs:
          oneOf:
            - $ref: '#/components/schemas/ExportSubjectInput'
            - type: 'null'
          description: >-
            Render the dashboard as this user instead of the caller — the
            queries behind the image run under THEIR security context. Requires
            the caller to be a tenant admin. Omit to render as the API key's own
            user.
        timeGrains:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardTimeGrainInput'
              type: array
            - type: 'null'
          description: Time-grain overrides applied to the dashboard while it renders.
      required:
        - format
      type: object
    DashboardExportJobResponse:
      properties:
        expiresAt:
          description: >-
            When the job (and its rendered file) is evicted from the renderer
            cache. Download before this, or submit a new export.
          format: date-time
          type: string
        jobId:
          description: Job id to poll for status and to download the finished file with.
          type: string
      required:
        - jobId
        - expiresAt
      type: object
    DashboardFilterInput:
      properties:
        caseSensitive:
          oneOf:
            - {}
            - type: 'null'
          description: 'For string filters: whether matching is case-sensitive'
        endInclusive:
          oneOf:
            - {}
            - type: 'null'
          description: 'For between filters: whether the end bound is inclusive'
        member:
          description: Dimension path, e.g. "Orders.status"
          pattern: .+\..+
          type: string
        operator:
          oneOf:
            - $ref: '#/components/schemas/DashboardFilterInputOperator'
            - type: 'null'
        startInclusive:
          oneOf:
            - {}
            - type: 'null'
          description: 'For between filters: whether the start bound is inclusive'
        value:
          oneOf:
            - oneOf:
                - type: string
                - type: number
                - type: boolean
                - type: array
                  items: {}
            - type: 'null'
          description: >-
            Filter value. Omit for is_null / is_not_null / is_empty /
            is_not_empty; provide a 2-element [start, end] array for between.
      required:
        - member
      type: object
    StartDashboardExportInputFormat:
      enum:
        - png
        - pdf
      type: string
    DashboardMemberSwitcherInput:
      properties:
        member:
          description: Path of the member the control replaces, e.g. "Orders.status"
          pattern: .+\..+
          type: string
        selected:
          description: >-
            Name of the member to show in its place, e.g. "city" (no view
            prefix)
          type: string
      required:
        - member
        - selected
      type: object
    ExportSubjectInput:
      properties:
        email:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Main user email (for type=USER; provide this OR userId). For
            type=EMBED_USER it is the email recorded on the provisioned embed
            user, and the externalId is used when it is omitted.
        embedTenantName:
          oneOf:
            - type: string
            - type: 'null'
          description: Embed tenant name (for type=EMBED_USER)
        externalId:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Embed user external id (for type=EMBED_USER). The user is
            provisioned if it does not exist yet.
        groups:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
          description: >-
            Embed user groups (type=EMBED_USER). Must reference groups that
            already exist; drives what the rendered dashboard is allowed to
            show.
        securityContext:
          oneOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          description: >-
            Security context applied to the embed user before rendering
            (type=EMBED_USER) — the same object a generate-session call takes.
            Row-level rules in the data model see exactly this.
        type:
          $ref: '#/components/schemas/ExportSubjectInputType'
        userAttributes:
          oneOf:
            - items:
                $ref: '#/components/schemas/UserAttributeInput'
              type: array
            - type: 'null'
          description: >-
            Embed user attribute values (type=EMBED_USER). Names must reference
            attribute definitions that already exist.
        userId:
          oneOf:
            - type: integer
            - type: 'null'
          description: Main user id (for type=USER; provide this OR email)
      required:
        - type
      type: object
    DashboardTimeGrainInput:
      properties:
        grain:
          description: Granularity, e.g. "day", "week", "month"
          type: string
        member:
          description: Time dimension path, e.g. "Orders.created_at"
          pattern: .+\..+
          type: string
      required:
        - member
        - grain
      type: object
    DashboardFilterInputOperator:
      enum:
        - equals
        - not_equals
        - greater_than
        - greater_than_or_equal
        - less_than
        - less_than_or_equal
        - contains
        - not_contains
        - starts_with
        - not_starts_with
        - ends_with
        - not_ends_with
        - is_null
        - is_not_null
        - is_empty
        - is_not_empty
        - between
        - custom
      type: string
    ExportSubjectInputType:
      enum:
        - USER
        - EMBED_USER
      type: string
    UserAttributeInput:
      properties:
        name:
          type: string
        value:
          oneOf:
            - oneOf:
                - type: string
                - type: number
                - type: boolean
                - items:
                    type: string
                  type: array
                - type: array
                  items:
                    type: number
            - type: 'null'
      required:
        - name
      type: object
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Token authentication. Send `Authorization: Bearer <YOUR_TOKEN>`.'

````