Custom Charts Public API — Dashboard Gadgets (1.0)

This API lets you create, update, and list Custom Charts gadgets on a Jira dashboard programmatically — without going through the dashboard UI.

A common use case is copying gadgets from one Jira site to another: read the gadgets from a dashboard on the source site, then recreate them on the target site. The optional source fields (see below) let you record where each copied gadget originally came from, so you can match them up later.

Base URL

The base URL depends on the data residency region your Custom Charts install is hosted in:

Region Base URL
EU https://eu.custom-charts-jira.amovos-apps.com
US https://us.custom-charts-jira.amovos-apps.com
Default (routed) https://custom-charts-jira.amovos-apps.com

All endpoints are scoped to a single dashboard, under that base URL:

<base-url>/api/custom-charts/1.0/dashboards/{dashboardId}/gadgets

Prerequisites

Personal Access Tokens must be enabled in the app before any of the endpoints below are reachable:

  1. As a Custom Charts admin, open Custom Charts - Settings → Features tab.
  2. Enable the Personal Access Tokens feature.

While the feature is disabled, token issuance is hidden from users and API requests return 404 regardless of any token value.

Authentication

All endpoints require a Personal Access Token issued by Custom Charts, supplied as a Bearer token in the Authorization header:

Authorization: Bearer <token>

Obtaining a token

  1. In Jira, open the personal settings page: <jira>/jira/settings/personal/general.
  2. From the left-hand menu, choose Apps → Custom Charts - Personal Settings.
  3. Generate a new Personal Access Token from that screen and copy the value.

Tokens are scoped to the issuing user — every API call is performed as that user and inherits their Jira permissions on the target dashboard.

Supported gadget types

The API only operates on Custom Charts gadgets. Non-CC gadgets (Jira built-ins, gadgets from other apps) are invisible — read endpoints return 404, write endpoints return 400.

gadgetType value Description
custom-chart-dashboard-item Custom Chart
simple-search-dashboard-item Simple Search
issue-list-dashboard-item Issue List
shared-dashboard-dashboard-item Shared Dashboard

Where a gadget came from: the source fields

When you copy a gadget from another Atlassian site, you can record where it came from using three optional fields: sourceGadgetId, sourceDashboardId, and sourceSiteUrl.

  • All three fields are optional.
  • In POST and PUT, it's all-or-nothing: if you send one, you must send all three. Sending only some returns 400. A blank sourceSiteUrl counts as not sent.
  • In PATCH, you can send any of them; the ones you send are updated and the rest keep their current values.

These fields are stored separately and are not returned by default — set the includeSource query parameter to get them back.

Error model

Every error (except the existence-hiding 404 below) returns a unified body:

{
  "statusCode": 400,
  "errorCode": "VALIDATION_FAILED",
  "message": "gadgetType must be one of the supported types",
  "atlTraceId": "…",
  "details": { }
}

errorCode is a stable, machine-readable category — switch on it rather than parsing message. atlTraceId and details appear only when relevant.

errorCode Typical status Meaning
INVALID_TOKEN 401 Missing/invalid/expired token.
VALIDATION_FAILED 400 Bad input — invalid gadgetType, partial source, non-CC gadget, …
GADGET_NOT_FOUND 404 Dashboard or gadget not found.
SOURCE_CONFLICT 409 Duplicate sourceGadgetId with validateUniqueSource=true.
RATE_LIMITED 429 Too many requests. See Retry-After / X-RateLimit-* headers.
UPSTREAM_JIRA_ERROR upstream / 500 A downstream Jira call failed; status may pass through.
INTERNAL_ERROR 500 Unexpected server error.

When the Personal Access Tokens feature is disabled, the API hides its existence: every request returns 404 with a minimal body { "statusCode": 404, "message": "HTTP 404 Not Found" } (no errorCode).

Gadgets

Manage Custom Charts gadgets on a Jira dashboard.

List gadgets

Returns all Custom Charts gadgets on the dashboard.

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

query Parameters
includeSource
boolean
Default: false

When true, response items include the three source* fields. Adds one property fetch per gadget.

Responses

Response samples

Content type
application/json
{
  • "gadgets": [
    ],
  • "total": 0
}

Create gadget

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

query Parameters
validateUniqueSource
boolean
Default: false

When true and source fields are provided, the API rejects the create with 409 if any existing gadget on the dashboard already carries the same sourceGadgetId. Costs N property fetches.

Request Body schema: application/json
required
gadgetType
required
string (GadgetType)
Enum: "custom-chart-dashboard-item" "simple-search-dashboard-item" "issue-list-dashboard-item" "shared-dashboard-dashboard-item"

One of the four supported Custom Charts gadget types.

object

Optional. When omitted, the gadget is placed at the top-left of the dashboard (column 0, row 0) and Jira reflows the existing gadgets down. When provided, both column and row are required.

color
string

Jira-defined color name.

title
string
sourceGadgetId
integer <int64>

Send together with the other two source fields, or not at all.

sourceDashboardId
integer <int64>

Send together with the other two source fields, or not at all.

sourceSiteUrl
string

Send together with the other two source fields, or not at all. Must not be blank when set.

required
object (Configuration)

Gadget-type-specific configuration.

The same shape is used on read and write: the configuration returned by the GET endpoints is what you send back on create/update, so a gadget can be round-tripped (read from one dashboard, recreated on another) as-is. The one exception is write-only fields such as configuration.accessCode, which are accepted on write but never returned on read.

configuration.id is a string identifying the gadget within its dashboard. Conditions:

  • Required and non-empty on create and full update (PUT).

  • On PATCH it may be omitted (the stored value is kept), but must not be set to a blank value.

  • Must be unique among all gadgets on the same dashboard. The API does not enforce this — keeping it unique is the caller's responsibility.

Why uniqueness matters: a shared-dashboard-dashboard-item gadget lists its member gadgets by their id values in its own configuration.gadgets array, so a duplicate id makes that reference ambiguous and breaks shared-dashboard resolution for the dashboard.

Responses

Request samples

Content type
application/json
{
  • "gadgetType": "custom-chart-dashboard-item",
  • "position": {
    },
  • "color": "green",
  • "title": "Issues by status",
  • "sourceGadgetId": 1234,
  • "sourceDashboardId": 5678,
  • "configuration": { }
}

Response samples

Content type
application/json
{
  • "gadgetId": 42765,
  • "dashboardId": 12733,
  • "gadgetType": "custom-chart-dashboard-item",
  • "column": 0,
  • "row": 0,
  • "color": "green",
  • "title": "Issues by status",
  • "sourceGadgetId": 1234,
  • "sourceDashboardId": 5678,
  • "configuration": { }
}

Get gadget by ID

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

gadgetId
required
integer <int64>

Dashboard-item ID assigned by Jira when the gadget is added.

query Parameters
includeSource
boolean
Default: false

When true, response includes the three source* fields.

Responses

Response samples

Content type
application/json
{
  • "gadgetId": 42765,
  • "dashboardId": 12733,
  • "gadgetType": "custom-chart-dashboard-item",
  • "column": 0,
  • "row": 0,
  • "color": "green",
  • "title": "Issues by status",
  • "sourceGadgetId": 1234,
  • "sourceDashboardId": 5678,
  • "configuration": { }
}

Replace gadget

Replaces the gadget's configuration and (optionally) the source fields. Does not change position, color or title. If you don't send the source fields, their current values are kept.

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

gadgetId
required
integer <int64>

Dashboard-item ID assigned by Jira when the gadget is added.

Request Body schema: application/json
required
gadgetType
string (GadgetType)
Enum: "custom-chart-dashboard-item" "simple-search-dashboard-item" "issue-list-dashboard-item" "shared-dashboard-dashboard-item"

One of the four supported Custom Charts gadget types.

object (Configuration)

Gadget-type-specific configuration.

The same shape is used on read and write: the configuration returned by the GET endpoints is what you send back on create/update, so a gadget can be round-tripped (read from one dashboard, recreated on another) as-is. The one exception is write-only fields such as configuration.accessCode, which are accepted on write but never returned on read.

configuration.id is a string identifying the gadget within its dashboard. Conditions:

  • Required and non-empty on create and full update (PUT).

  • On PATCH it may be omitted (the stored value is kept), but must not be set to a blank value.

  • Must be unique among all gadgets on the same dashboard. The API does not enforce this — keeping it unique is the caller's responsibility.

Why uniqueness matters: a shared-dashboard-dashboard-item gadget lists its member gadgets by their id values in its own configuration.gadgets array, so a duplicate id makes that reference ambiguous and breaks shared-dashboard resolution for the dashboard.

sourceGadgetId
integer <int64>
sourceDashboardId
integer <int64>
sourceSiteUrl
string

Must be non-blank when set.

Responses

Request samples

Content type
application/json
{
  • "gadgetType": "custom-chart-dashboard-item",
  • "configuration": {
    }
}

Response samples

Content type
application/json
{
  • "gadgetId": 42765,
  • "dashboardId": 12733,
  • "gadgetType": "custom-chart-dashboard-item",
  • "column": 0,
  • "row": 0,
  • "color": "green",
  • "title": "Issues by status",
  • "sourceGadgetId": 1234,
  • "sourceDashboardId": 5678,
  • "configuration": { }
}

Patch gadget

Partial update — all fields are optional. At least one of gadgetType or configuration must be present. See the schema notes for merge semantics. Unlike POST/PUT, PATCH does not return the updated gadget.

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

gadgetId
required
integer <int64>

Dashboard-item ID assigned by Jira when the gadget is added.

Request Body schema: application/json
required
gadgetType
string (GadgetType)
Enum: "custom-chart-dashboard-item" "simple-search-dashboard-item" "issue-list-dashboard-item" "shared-dashboard-dashboard-item"

One of the four supported Custom Charts gadget types.

object (Configuration)

Gadget-type-specific configuration.

The same shape is used on read and write: the configuration returned by the GET endpoints is what you send back on create/update, so a gadget can be round-tripped (read from one dashboard, recreated on another) as-is. The one exception is write-only fields such as configuration.accessCode, which are accepted on write but never returned on read.

configuration.id is a string identifying the gadget within its dashboard. Conditions:

  • Required and non-empty on create and full update (PUT).

  • On PATCH it may be omitted (the stored value is kept), but must not be set to a blank value.

  • Must be unique among all gadgets on the same dashboard. The API does not enforce this — keeping it unique is the caller's responsibility.

Why uniqueness matters: a shared-dashboard-dashboard-item gadget lists its member gadgets by their id values in its own configuration.gadgets array, so a duplicate id makes that reference ambiguous and breaks shared-dashboard resolution for the dashboard.

sourceGadgetId
integer <int64>
sourceDashboardId
integer <int64>
sourceSiteUrl
string

Must be non-blank when set.

Responses

Request samples

Content type
application/json
{
  • "gadgetType": "custom-chart-dashboard-item",
  • "configuration": {
    }
}

Response samples

Content type
application/json
{
  • "success": true
}

Delete gadget

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

gadgetId
required
integer <int64>

Dashboard-item ID assigned by Jira when the gadget is added.

Responses

Response samples

Content type
application/json
{
  • "statusCode": 400,
  • "errorCode": "VALIDATION_FAILED",
  • "message": "gadgetType must be one of the supported types"
}

Get gadget by source-gadget ID

Looks up a gadget on the dashboard whose stored sourceGadgetId matches the path parameter. Always includes the source fields in the response. Performance note: This endpoint fetches the "source" property for every Custom Charts gadget on the dashboard (N round-trips).

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

sourceGadgetId
required
integer <int64>

The gadget's ID on the site it was copied from.

Responses

Response samples

Content type
application/json
{
  • "gadgetId": 42765,
  • "dashboardId": 12733,
  • "gadgetType": "custom-chart-dashboard-item",
  • "column": 0,
  • "row": 0,
  • "color": "green",
  • "title": "Issues by status",
  • "sourceGadgetId": 1234,
  • "sourceDashboardId": 5678,
  • "configuration": { }
}

Patch gadget by source-gadget ID

Same semantics as PATCH /gadgets/{gadgetId}, but the target gadget is found by the stored sourceGadgetId instead of its Jira gadget id.

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

sourceGadgetId
required
integer <int64>

The gadget's ID on the site it was copied from.

Request Body schema: application/json
required
gadgetType
string (GadgetType)
Enum: "custom-chart-dashboard-item" "simple-search-dashboard-item" "issue-list-dashboard-item" "shared-dashboard-dashboard-item"

One of the four supported Custom Charts gadget types.

object (Configuration)

Gadget-type-specific configuration.

The same shape is used on read and write: the configuration returned by the GET endpoints is what you send back on create/update, so a gadget can be round-tripped (read from one dashboard, recreated on another) as-is. The one exception is write-only fields such as configuration.accessCode, which are accepted on write but never returned on read.

configuration.id is a string identifying the gadget within its dashboard. Conditions:

  • Required and non-empty on create and full update (PUT).

  • On PATCH it may be omitted (the stored value is kept), but must not be set to a blank value.

  • Must be unique among all gadgets on the same dashboard. The API does not enforce this — keeping it unique is the caller's responsibility.

Why uniqueness matters: a shared-dashboard-dashboard-item gadget lists its member gadgets by their id values in its own configuration.gadgets array, so a duplicate id makes that reference ambiguous and breaks shared-dashboard resolution for the dashboard.

sourceGadgetId
integer <int64>
sourceDashboardId
integer <int64>
sourceSiteUrl
string

Must be non-blank when set.

Responses

Request samples

Content type
application/json
{
  • "gadgetType": "custom-chart-dashboard-item",
  • "configuration": {
    }
}

Response samples

Content type
application/json
{
  • "success": true
}

Delete gadget by source-gadget ID

Authorizations:
bearerAuth
path Parameters
dashboardId
required
integer <int64>

Jira dashboard ID.

sourceGadgetId
required
integer <int64>

The gadget's ID on the site it was copied from.

Responses

Response samples

Content type
application/json
{
  • "statusCode": 400,
  • "errorCode": "VALIDATION_FAILED",
  • "message": "gadgetType must be one of the supported types"
}