Import dashboard from file via API

Good Day

I am trying to import a dashboard exported from the Grafana GUI via a Curl.

The command I am using for import is:

curl -X POST --insecure -H "Authorization: Bearer $apikey" -H "Content-Type: application/json" -d @hi.json

The dashboard json content:

  "annotations": {
    "list": [
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
  "editable": true,
  "gnetId": null,
  "graphTooltip": 0,
  "id": 3371,
  "links": [],
  "panels": [
      "columns": [],
      "datasource": "rt",
      "fontSize": "100%",
      "gridPos": {
        "h": 9,
        "w": 12,
        "x": 0,
        "y": 0
      "id": 2,
      "links": [],
      "pageSize": null,
      "scroll": true,
      "showHeader": true,
      "sort": {
        "col": 0,
        "desc": true
      "styles": [
          "alias": "Time",
          "dateFormat": "YYYY-MM-DD HH:mm:ss",
          "pattern": "Time",
          "type": "date"
          "alias": "",
          "colorMode": null,
          "colors": [
            "rgba(245, 54, 54, 0.9)",
            "rgba(237, 129, 40, 0.89)",
            "rgba(50, 172, 45, 0.97)"
          "decimals": 2,
          "pattern": "/.*/",
          "thresholds": [],
          "type": "number",
          "unit": "short"
      "targets": [
          "alias": "",
          "format": "table",
          "rawSql": "SELECT ticket from `sanlam-gbe`;",
          "refId": "A"
      "title": "Panel Title",
      "transform": "table",
      "type": "table"
  "schemaVersion": 16,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": []
  "time": {
    "from": "now-6h",
    "to": "now"
  "timepicker": {
    "refresh_intervals": [
    "time_options": [
  "timezone": "",
  "title": "dhyata test",
  "uid": "fSXsFG0Wk",
  "version": 2

The import is failing with error:

{"error":"Server Error","message":"Internal Server Error - Check the Grafana server logs for the detailed error message."}

Log file output:

t=2019-10-25T14:01:07+0000 lvl=eror msg="Request error" logger=context userId=0 orgId=8 uname= error="runtime error: invalid memory address or nil pointer dereference" stack="/usr/local/go/src/runtime/panic.go:82 (0x44e220)\n/usr/local/go/src/runtime/signal_unix.go:390 (0x44e04f)\n/go/src/ (0xa58391)\n/go/src/ (0xa58391)\n/go/src/ (0xa58390)\n/go/src/ (0xcc1d84)\n/usr/local/go/src/reflect/value.go:447 (0x492e20)\n/usr/local/go/src/reflect/value.go:308 (0x4928a3)\n/go/src/ (0xa4c3f1)\n/go/src/ (0x1295813)\n/go/src/ (0x12957f1)\n/usr/local/go/src/reflect/value.go:447 (0x492e20)\n/usr/local/go/src/reflect/value.go:308 (0x4928a3)\n/go/src/ (0x8ea1a6)\n/go/src/ (0x8e9a9b)\n/go/src/ (0x12ad5cd)\n/usr/local/go/src/reflect/value.go:447 (0x492e20)\n/usr/local/go/src/reflect/value.go:308 (0x4928a3)\n/go/src/ (0x8ea1a6)\n/go/src/ (0x8e9a9b)\n/go/src/ (0x8eb259)\n/go/src/ (0xbf030e)\n/go/src/ (0xbf0301)\n/usr/local/go/src/reflect/value.go:447 (0x492e20)\n/usr/local/go/src/reflect/value.go:308 (0x4928a3)\n/go/src/ (0x8ea1a6)\n/go/src/ (0x8e9a9b)\n/go/src/ (0x8eb259)\n/go/src/ (0xbefb2c)\n/go/src/ (0xbefb17)\n/usr/local/go/src/reflect/value.go:447 (0x492e20)\n/usr/local/go/src/reflect/value.go:308 (0x4928a3)\n/go/src/ (0x8ea1a6)\n/go/src/ (0x8e9a9b)\n/go/src/ (0x8eb259)\n/go/src/ (0xbefa45)\n/go/src/ (0xbefa33)\n/go/src/ (0x8eb100)\n/go/src/ (0x8e9e60)\n/go/src/ (0x8e9b8a)\n/go/src/ (0x8eb259)\n/go/src/ (0xbecf5b)\n/go/src/ (0xbecf46)\n/usr/local/go/src/reflect/value.go:447 (0x492e20)\n/usr/local/go/src/reflect/value.go:308 (0x4928a3)\n/go/src/ (0x8ea1a6)\n/go/src/ (0x8e9a9b)\n/go/src/ (0x8eb259)\n/go/src/ (0x8fc606)\n/go/src/ (0x8f701d)\n/go/src/ (0x8f02ac)\n/usr/local/go/src/net/http/server.go:2774 (0x6f2ca7)\n/usr/local/go/src/net/http/server.go:1878 (0x6ee990)\n/usr/local/go/src/runtime/asm_amd64.s:1337 (0x468150)\n"

POST data are not OK. Try&debug&improve:

-d "{\"dashboard\":$(cat hi.json)}"
1 Like

Hi, I have done it with Python, I suppose you can adapt with curl. The json code you need to send must have a specific structure. The annotations etc that you get seem like they come from an export in json and that is not the outer structure. For example, use something like:
Here is where you have to include your own structure exported via json from somewhere else
“folderId”: 0,
“overwrite”: true
Be careful about one thing: notice the “id” field you put in your data. If I didn’t set this to null, it would complain about dashboard not found or something like that. If you don’t manage to get it done, please respond, I will try to be more helpful. The point is the structure you are providing is missing some fields and should be included as the dashboard field value, along with some necessary other ones in an outer structure.
Also make sure you have done all that was necessary to create the api key etc. Again let me know if you need more guidance.
btw I also think your url is wrong, the path I used (got it from the doc) is this: /api/dashboards/db, of course I could be wrong and the change in url (using an import function) might mean you don’t need that structure. I may try your approach to see what happens.


Curl script is running but not able to import dashboard, its showing following error
if (!checkBrowserCompatibility()) {
alert(‘Your browser is not fully supported, please try newer version.’);

hi itheodoridis,
can you share the json structure please?
i am facing with the same issue, i exported all of my json files from old instance which is about to archive and now want to import them back to the new grafana instance. i am getting 400 bad request, i cant see if anything wrong except the json file, or maybe the host name.
i tried with even dummy data and still no result.
here is the code i used.

def import_dashboard():
“”" this function will push the dashboards to new instance 110960
#dashboard_import_title = export_dashboard.dashboard_title
grafana_url_post = “
token = “hardcoded token”
headers = {‘Authorization’: f"Bearer {token}“, ‘Content-Type’: ‘application/json’}
#dashboard_json_updated = {“dashboard”:dashboard_json, “folderUid”: “l3KqBxCMz”, “message”: “Made changes to xyz”, “overwrite”: False}
dashboard_json_updated = {
“dashboard”: {
“id”: None,
“uid”: None,
“title”: “Production Overview”,
“tags”: [ “templated” ],
“timezone”: “browser”,
“schemaVersion”: 16,
“version”: 0,
“refresh”: “25s”
“folderId”: 0,
“folderUid”: “l3KqBxCMz”,
“message”: “Made changes to xyz”,
“overwrite”: False
r =‘/dashboards/db’, data=json.dumps(dashboard_json_updated), headers=headers)
#r =‘/dashboards/db’, data=json.dumps(dashboard_json_updated), headers=headers, verify=False)
print(” this is the response “, r)
print(” this is the dashboard_json_updated which printing inside the imort fun", dashboard_json_updated) # this is printing as a list not json dic
if r.status_code == ‘200’:

return "Success"

def get_upload_dashboard(dashboard_json_updated, overwrite=False, message=“Updated by grafanlib”):
dashboard = dashboard_json_updated[“dashboard_json”]
return json.dumps(
“dashboard_json”: dashboard_json_updated,
“overwrite”: overwrite,
“message”: message
}, sort_keys=True, indent=2)

ok. i got it working.
for those who interesting to know what was the issue,
from the code i pasted here, i removed the folderUid’s value and it worked.
you can not post a request with a folderUid unless you get the folderUid from your new instance and hardcoding it. otherwise leave it None and your dashboard will be imported under General folder.
also make sure you have the /api after your host_url or add it inside your

1 Like