---
title: Using the Blob Storage API for notebooks
source: https://docs.newrelic.com/docs/query-your-data/explore-query-data/notebooks/blob-storage-api-for-notebooks
---

The New Relic Notebooks API lets you create, read, update, and delete notebooks programmatically, including their full block content (NRQL queries, text). Notebooks are stored as versioned blobs, which means every save produces a new immutable revision you can retrieve later.

Use this API to:

-   Automate notebook creation from incident templates, runbooks, or CI/CD pipelines
-   Sync notebook content from version control or external authoring tools
-   Build integrations that programmatically populate notebooks during investigations

> #### ⚠️ IMPORTANT
>
> **Notebooks use multiple APIs**
>
> The Notebooks API surface is split between two systems:
>
> -   **Blob Storage API** handles notebook content (blocks, version history)
> -   **NerdGraph** handles entity-level operations (list, rename, tags, organization metadata)
>
>     This separation is by design. The Blob Storage API is optimized for file content transfer and versioning; NerdGraph is optimized for structured entity queries and mutations.

## Prerequisites [#prerequisites]

-   A [New Relic account](https://newrelic.com/signup) with a User API key
-   Your New Relic Organization ID
-   Appropriate [permissions](https://docs.newrelic.com/docs/accounts/accounts-billing/new-relic-one-user-management/user-permissions/) to manage notebooks

## Authentication [#authentication]

All Notebooks API requests require authentication using a New Relic User API key.

**Generate an API key:**

1.  Navigate to [one.newrelic.com](https://one.newrelic.com)
2.  Click on your name in the top-right corner
3.  Select **API Keys**
4.  Create a **User** key (not Browser or License key)

**Include in request headers:**

```shell
Api-Key: NRAK-YOUR-USER-API-KEY
```

> #### 💡 TIP
>
> The Blob Storage API also supports login context, so when calling the API from a UI authenticated as a New Relic user, the `Api-Key` header is not required.

## Base endpoint [#base-endpoint]

```plaintext
https://blob-api.service.newrelic.com/v1/e
```

For EU region accounts, use:

```plaintext
https://blob-api.service.eu.newrelic.com/v1/e
```

## Notebook content operations [#content-operations]

**Create notebook**

Creates a new notebook entity with initial blob content.

### Endpoint [#create-endpoint]

```plaintext
POST /v1/e/organizations/{orgId}/Notebooks
```

### Request parameters [#create-params]

| Parameter         | Location | Data type   | Description                                                      |
| ----------------- | -------- | ----------- | ---------------------------------------------------------------- |
| `orgId`           | Path     | String      | Required. Your New Relic organization ID.                        |
| `Api-Key`         | Header   | String      | Required. Your User API key.                                     |
| `Content-Type`    | Header   | String      | Required. Must be `application/json`.                            |
| `NewRelic-Entity` | Header   | JSON string | Required. JSON object with notebook entity metadata (see below). |
| Request body      | Body     | JSON        | Required. Notebook content in JSON format (version + blocks).    |

### `NewRelic-Entity` header format [#create-entity-header]

| Field  | Data type | Description                                                                |
| ------ | --------- | -------------------------------------------------------------------------- |
| `name` | String    | Required. The notebook name. Must be unique within the organization scope. |

### Notebook body format [#create-body-format]

| Field     | Data type | Description                                                                               |
| --------- | --------- | ----------------------------------------------------------------------------------------- |
| `version` | String    | Schema version of the notebook payload. Use `"1"`.                                        |
| `blocks`  | Array     | Ordered list of notebook blocks (NRQL, text, etc.). Empty array creates a blank notebook. |

### Declarative UI content examples [#create-declarative-ui]

The following examples show how to structure notebook widget content using the declarative UI format.

**Markdown widget**

Use `viz.markdown` to render static text, labels, or threshold legends alongside your charts:

```json
{
  "type": "widget",
  "content": {
    "type": "visualization",
    "id": "viz.markdown",
    "props": {
      "text": "# My dashboard\n\n### Cost thresholds (monthly)\n- $0 – $200 → Good\n- $200 – $500 → Warning\n- $500+ → Critical"
    }
  }
}
```

**Billboard widget with NRQL query**

Use `viz.billboard` to display a single metric value with optional color-coded thresholds:

```json
{
  "type": "widget",
  "props": {
    "title": "Total usage this month"
  },
  "content": {
    "type": "visualization",
    "id": "viz.billboard",
    "props": {
      "nrqlQueries": [
        {
          "query": "FROM Transaction SELECT count(*) SINCE 1 month ago",
          "accountIds": [1234567]
        }
      ],
      "thresholdsWithSeriesOverrides": {
        "thresholds": [
          { "to": 200,              "severity": "success"  },
          { "from": 200, "to": 500, "severity": "warning"  },
          { "from": 500,            "severity": "critical" }
        ]
      },
      "facet": { "showOtherSeries": false },
      "platformOptions": { "ignoreTimeRange": false },
      "chartStyles": { "lineInterpolation": "linear" }
    }
  }
}
```

### Sample request [#create-sample-request]

```bash
curl -X POST \
  https://blob-api.service.newrelic.com/v1/e/organizations/YOUR_ORG_ID/Notebooks \
  -H 'Api-Key: NRAK-YOUR-API-KEY' \
  -H 'Content-Type: application/json' \
  -H 'NewRelic-Entity: {"name": "My awesome notebook"}' \
  -d '{
    "version": "1",
    "blocks": []
  }'
```

### Sample response [#create-sample-response]

```json
{
  "entityGuid": "<YOUR_ENTITY_GUID>",
  "blobId": "<YOUR_BLOB_ID>",
  "blobVersionEntity": {
    "entityGuid": "<YOUR_ENTITY_GUID>",
    "version": 1
  }
}
```

> #### ⚠️ IMPORTANT
>
> Save the `entityGuid` from the response. You'll need it for reading, updating, and deleting the notebook.

**Read notebook content**

Retrieves the latest content of a notebook.

### Endpoint [#read-endpoint]

```plaintext
GET /v1/e/organizations/{orgId}/Notebooks/{entityGuid}
```

### Request parameters [#read-params]

| Parameter    | Location | Data type | Is it required? | Description                     |
| ------------ | -------- | --------- | --------------- | ------------------------------- |
| `orgId`      | Path     | String    | Yes             | Your New Relic organization ID. |
| `entityGuid` | Path     | String    | Yes             | The notebook entity GUID.       |
| `Api-Key`    | Header   | String    | Yes             | Your User API key.              |

### Sample request [#read-sample-request]

```bash
curl -X GET \
  https://blob-api.service.newrelic.com/v1/e/organizations/YOUR_ORG_ID/Notebooks/YOUR_ENTITY_GUID \
  -H 'Api-Key: NRAK-YOUR-API-KEY'
```

### Sample response [#read-sample-response]

```json
{
  "type": "declarative",
  "version": 1,
  "content": [
    {
      "type": "container",
      "props": {
        "layout": "stack"
      },
      "content": [
        {
          "type": "widget",
          "props": {},
          "content": {
            "type": "visualization",
            "id": "viz.billboard",
            "props": {
              "nrqlQueries": [
                {
                  "query": "FROM PageView SELECT count(*) SINCE 3 days ago",
                  "accountIds": [1]
                }
              ]
            }
          }
        }
      ]
    }
  ]
}
```

**Update notebook content**

Creates a new version of an existing notebook by overwriting the content. The previous version is retained for up to 1 day (see [Retrieve previous versions](#retrieve-versions)).

### Endpoint [#update-endpoint]

```plaintext
POST /v1/e/organizations/{orgId}/Notebooks/{entityGuid}
```

### Request parameters [#update-params]

| Parameter      | Location | Data type | Is it required? | Description                     |
| -------------- | -------- | --------- | --------------- | ------------------------------- |
| `orgId`        | Path     | String    | Yes             | Your New Relic organization ID. |
| `entityGuid`   | Path     | String    | Yes             | The notebook entity GUID.       |
| `Api-Key`      | Header   | String    | Yes             | Your User API key.              |
| `Content-Type` | Header   | String    | Yes             | Must be `application/json`.     |
| Request body   | Body     | JSON      | Yes             | Updated notebook content.       |

### Sample request [#update-sample-request]

```bash
curl -X POST \
  https://blob-api.service.newrelic.com/v1/e/organizations/YOUR_ORG_ID/Notebooks/YOUR_ENTITY_GUID \
  -H 'Api-Key: NRAK-YOUR-API-KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "declarative",
    "version": 1,
    "content": [
      {
        "type": "container",
        "props": {
          "layout": "stack"
        },
        "content": [
          {
            "type": "widget",
            "props": {
              "title": ""
            },
            "content": {
              "type": "visualization",
              "id": "viz.billboard",
              "props": {
                "nrqlQueries": [
                  {
                    "query": "FROM PageView SELECT count(*) SINCE 2 days ago",
                    "accountIds": [1]
                  }
                ]
              }
            }
          }
        ]
      }
    ]
  }'
```

### Sample response [#update-sample-response]

```json
{
  "entityGuid": "<YOUR_ENTITY_GUID>",
  "blobId": "<YOUR_BLOB_ID>",
  "blobVersionEntity": {
    "entityGuid": "<YOUR_ENTITY_GUID>",
    "version": 2
  }
}
```

**Delete notebook**

Deletes a notebook and its content.

### Endpoint [#delete-endpoint]

```plaintext
DELETE /v1/e/organizations/{orgId}/Notebooks/{entityGuid}
```

### Request parameters [#delete-params]

| Parameter    | Location | Data type | Is it required? | Description                         |
| ------------ | -------- | --------- | --------------- | ----------------------------------- |
| `orgId`      | Path     | String    | Yes             | Your New Relic organization ID.     |
| `entityGuid` | Path     | String    | Yes             | The notebook entity GUID to delete. |
| `Api-Key`    | Header   | String    | Yes             | Your User API key.                  |

### Sample request [#delete-sample-request]

```bash
curl -X DELETE \
  https://blob-api.service.newrelic.com/v1/e/organizations/YOUR_ORG_ID/Notebooks/YOUR_ENTITY_GUID \
  -H 'Api-Key: NRAK-YOUR-API-KEY'
```

### Sample response [#delete-sample-response]

Returns HTTP 204 No Content on successful deletion.

**Retrieve previous versions**

Notebook versions are retained for **1 day**. To recover a previous revision, first list recent versions via NRQL, then fetch the specific blob.

### Step 1 — List the last 5 versions [#retrieve-list-versions]

Run this NRQL query in the query builder to gather the blob IDs and timestamps for the last 5 changes:

```sql
FROM Entity
SELECT uniques(tuple(updatedAt, content.id))
WHERE id = '<entity guid>'
SINCE 1 day ago
LIMIT 5
```

### Step 2 — Retrieve a specific version [#retrieve-specific-version]

Use the `content.id` from the NRQL result to fetch that version's content:

```bash
curl -X GET \
  https://blob-api.service.newrelic.com/v1/blobs/<content.id> \
  -H 'Api-Key: NRAK-YOUR-API-KEY'
```

## Entity operations (NerdGraph) [#entity-operations]

Entity-level operations such as listing, renaming, and tagging use NerdGraph rather than the Blob Storage API.

### List all notebooks [#list-notebooks]

```graphql
query listAllNotebooks {
  actor {
    entityManagement {
      entitySearch(query: "type='NOTEBOOK'") {
        entities {
          id
          name
        }
      }
    }
  }
}
```

> #### 💡 TIP
>
> Entity creation is fully transactional, so a notebook is immediately available via the API. However, if you list notebooks through the legacy `actor.entitySearch` query, there may be a short propagation delay between creation and the notebook appearing in list results.

### Rename a notebook [#rename-notebook]

```graphql
mutation changeNotebookName {
  entityManagementUpdateNotebook(
    id: "<entity guid>"
    notebookEntity: { name: "<new name>" }
  ) {
    entity {
      name
    }
  }
}
```

### Update notebook tags [#update-tags]

> #### ⚠️ IMPORTANT
>
> Tag updates are a **replace** operation. You must include the complete set of tags, even ones that aren't changing — any tag omitted from the mutation will be removed.

```graphql
mutation updateNotebookTags {
  entityManagementUpdateNotebook(
    id: "<entity guid>"
    notebookEntity: {
      tags: [
        { key: "<key>", values: "<value>" }
        { key: "<key>", values: "<value>" }
      ]
    }
  ) {
    entity {
      name
      tags {
        key
        values
      }
    }
  }
}
```

### Retrieve your organization ID [#get-org-id]

You'll need your organization ID for all Blob Storage API calls:

```graphql
query getOrgId {
  actor {
    organization {
      id
    }
  }
}
```

## Best practices [#best-practices]

-   **Store entity GUIDs:** Save the `entityGuid` returned from create operations. You'll need it for reading, updating, and deleting notebooks.
-   **Validate JSON before upload:** Ensure your notebook payload is valid JSON and conforms to the `version` schema before sending.
-   **Use descriptive names:** Notebook names must be unique within an organization, so choose names that clearly indicate purpose (for example, `prod-checkout-investigation` rather than `notebook-1`).
-   **Include all tags on update:** Tag updates replace the full tag set. Always read existing tags before mutating.
-   **Recover quickly:** Version history is retained for only 1 day. If you need long-term history, archive notebook content to your own storage on every update.
-   **Secure your API key:** Never expose your User API key in client-side code or public repositories.
-   **Check HTTP status codes:** The API returns 2xx for successful operations, 404 for not found, and other status codes for errors.

## Common error responses [#error-responses]

| Status code                  | Description                                                                                                                          | Solution                                                                                            |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
| `400 Bad Request`            | Invalid request parameters, malformed JSON in body or `NewRelic-Entity` header, or notebook name already exists in this organization | Verify request format, header values, and that the notebook name is unique within your organization |
| `401 Unauthorized`           | Missing or invalid API key                                                                                                           | Check that your User API key is valid and included in the `Api-Key` header                          |
| `404 Not Found`              | Notebook or version not found                                                                                                        | Verify the entity GUID is correct                                                                   |
| `415 Unsupported Media Type` | Incorrect `Content-Type` header                                                                                                      | Use `Content-Type: application/json`                                                                |

## Additional resources [#additional-resources]

-   [Notebooks overview](https://docs.newrelic.com/docs/query-your-data/explore-query-data/notebooks/introduction-notebooks) — How to use Notebooks in the New Relic UI
-   [Introduction to NerdGraph](https://docs.newrelic.com/docs/apis/nerdgraph/get-started/introduction-new-relic-nerdgraph) — GraphQL API reference
-   [Blob Storage API for agent configurations](https://docs.newrelic.com/docs/apis/intro-apis/blob-storage-api) — Sister API used by Fleet Control
-   [New Relic API keys](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys) — Key types and management
