Skip to main content
PUT
Create or update a report by publicId
Idempotent create-or-update (“upsert”) of a report keyed by its portable publicId — the stable identity for managing dashboards as code (CI/CD pipelines re-applying the same definition against any environment). If a report with this publicId exists in the deployment, it is updated with the fields you send (same semantics as PUT /reports/:reportId); otherwise a new report is created with this publicId. Re-applying the same request is a no-op. The publicId must be a 12-character alphanumeric id ([0-9A-Za-z]); mint one client-side when authoring the definition. This endpoint returns 409 for three different reasons, distinguished by the response body’s code — handle them differently:
  • No code — the publicId already belongs to a report in a different deployment. Because publicId is unique across the account, it is rejected rather than silently updating across deployments (reported regardless of whether you have access to that report). This is permanent: retrying will not help; use a different publicId.
  • code: "upsert_branch_changed" — whether this request creates or updates is decided, and access-checked, before it is applied; another writer changed that in between (created or deleted the report with this publicId). The request was rejected rather than applied under the wrong permission check. This is transient: retry the request. It only happens when two writers target the same publicId concurrently, e.g. two pipeline runs applying the same bundle at once.
  • code: "ambiguous_legacy_id" — the id given is one of the ids synthesized for reports that predate stable ids (see below), and it matches more than one of them, so it cannot identify a single report. Nothing was changed. This is permanent, and the fix is different from the case above: assign the report you mean a publicId of your own with PUT /deployments/{deploymentId}/reports/{reportId}, then key on that.
Reports created before stable ids do not store a publicId; the API synthesizes one for them from the report’s internal id. Those synthesized ids are not unique — several reports can share one, and in practice most do. This endpoint resolves such an id only when it is unambiguous, adopting it as the report’s real publicId at that point; otherwise it returns the ambiguous_legacy_id conflict above. For anything you intend to manage as code, do not rely on a synthesized id: give the report a publicId you chose. PUT /deployments/{deploymentId}/reports/{reportId} accepts publicId for exactly this, on any report that does not have one yet (it is write-once — a report’s existing publicId cannot be changed, since clients may already have stored it). source is create-only: it is recorded when the report is first created and ignored on subsequent updates (it describes where the report originated, not its current definition). Access: updating requires edit access to the existing report; creating requires the same access as POST /reports.

Authorizations

Authorization
string
header
required

Token authentication. Send Authorization: Bearer <YOUR_TOKEN>.

Path Parameters

deploymentId
number
required
publicId
string
required

Body

application/json

CreateReportInput

endResultCell
string | null
externalWorkbookId
string | null
folderId
integer | null
jsonQuery
string | null
meta
object | null
name
string | null
pivotItems
object | null
publicId
string | null
Required string length: 12
Pattern: ^[0-9A-Za-z]+$
resultLocation
string | null
source
enum<string> | null
Available options:
GOOGLE_SHEETS,
EXCEL,
PLAYGROUND,
D3
sqlQuery
string | null
title
string | null
workbookId
integer | null

Response

200 - application/json
createdAt
required
deploymentId
integer
required
id
integer
required
name
string
required
publicId
string
required
Required string length: 12
Pattern: ^[0-9A-Za-z]+$
refreshedByUser
object
required
type
enum<string>
required
Available options:
FOLDER,
WORKBOOK,
REPORT
updatedAt
required
user
object
required
userId
integer
required
canEdit
boolean | null
canManage
boolean | null
createdBy
integer
description
string | null
endResultCell
string | null
externalWorkbookId
string | null
externalWorkbookPlacements
object[] | null
folderId
integer | null
folderPath
object[]
jsonQuery
string | null
meta
object | null
pivotItems
object | null
refreshedBy
integer | null
resultLocation
string | null
rolesWithAccess
object[] | null
source
enum<string> | null
Available options:
GOOGLE_SHEETS,
EXCEL,
PLAYGROUND,
D3
sqlQuery
string | null
title
string | null
version
integer | null
workbookId
integer | null