> For the complete documentation index, see [llms.txt](https://docs.qubitro.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.qubitro.com/developers/blues-notehub.md).

# Blues Notehub

## Rename Notehub devices by module IMEI (batch)

> Renames Qubitro devices by matching each supplied Notehub module IMEI against the device's stored Notehub id (metadata.note\_device). Intended to sync device names from an external source (e.g. an Airtable "IMEI -> title" table) without a human editing each device.\
> \
> \*\*Matching:\*\*\
> \- Pass the bare IMEI (e.g. \`868531063306018\`); the \`dev:\` prefix Notehub uses is applied automatically.\
> \- Matching is scoped to the authenticated customer (your API key), across all of your projects. If the key is restricted to a single project, only devices in that project are considered.\
> \
> \*\*Behaviour:\*\*\
> \- The endpoint never creates devices. A device only exists after Notehub delivers its first packet, so IMEIs whose device has not been created yet return \`not\_found\` — re-run the sync later and they will be picked up. This makes the endpoint safe to call on a schedule.\
> \- Devices already carrying the requested name and the requested metadata are reported \`unchanged\` and are not rewritten.\
> \- \`metadata\`, when provided, replaces the device's existing custom metadata (same semantics as PUT device update).\
> \- Sending the same IMEI more than once in a batch is allowed; the last entry wins, and every entry is reported against the device's state as it was before the batch began.\
> \- A batch is capped at 1000 devices. Split larger fleets across sequential requests; there is no cross-request state, so any split is safe.\
> \
> \*\*Per-item status:\*\* \`renamed\`, \`unchanged\`, \`not\_found\`, \`ambiguous\` (more than one device matched the IMEI), \`invalid\` (missing imei/name), or \`error\`. Treat this set as open — handle unrecognised values gracefully, because new statuses may be introduced.\
> \
> \*\*Identifying devices:\*\* every result that resolved to a device — \`renamed\`, \`unchanged\` and \`error\` — carries \`device\_id\`, \`project\_id\` and \`device\_url\` (a direct link to the device in your portal, using your own domain if you are white-labelled). An \`ambiguous\` result lists each candidate under \`matches\`. \`not\_found\` and \`invalid\` carry no identifiers because no device exists to identify. This means a single request is enough to sync names and collect links; no follow-up lookups are required.\
> \- \`device\_url\` opens the device's own page in the portal. It is not a link to a Dashboard: dashboards are a separate resource, and a device may have several or none.\
> \- \`device\_url\` is a best-effort convenience. It may be absent if the link cannot be resolved, and it may redirect if portal routing changes, so treat its absence as "no link available" rather than as information about the device. \`device\_id\` and \`project\_id\` are always present for a matched device.\
> \
> \*\*Dry run:\*\* send \`"dry\_run": true\` to get the full per-device report without writing anything. Statuses and counters are identical to a real run, so a dry run is an exact rehearsal of the matching and classification a real run performs — \`renamed\` means "would be attempted". It does not prove the write itself would succeed, so \`error\` never appears in a dry run. The response always echoes \`dry\_run\`; check it before trusting a report, because a misspelled flag is simply ignored and the run is real.\
> \
> \*\*Stability:\*\* this endpoint is supported and safe to build automations against. Changes will be additive — new fields may appear, but existing fields, status values and semantics will not change or be removed without advance notice to affected customers. \`matched\_device\_ids\` is deprecated in favour of \`matches\` and will continue to be returned.

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"device.renameRequestBody":{"type":"object","properties":{"devices":{"description":"Batch of IMEI -> name mappings (1..1000)","type":"array","items":{"$ref":"#/components/schemas/device.renameItem"}},"dry_run":{"description":"Report what would happen without writing anything","type":"boolean"}}},"device.renameItem":{"type":"object","properties":{"imei":{"description":"Notehub module IMEI (bare, e.g. 868531063306018). The \"dev:\" prefix is added automatically when matching.","type":"string"},"metadata":{"description":"Optional custom metadata to set (replaces existing custom metadata for the device)","type":"object","additionalProperties":{}},"name":{"description":"New device name/title","type":"string"}}},"main.Response":{"type":"object","properties":{"action":{"description":"Action that was performed","type":"string"},"data":{"description":"Response payload (shape varies by endpoint)"},"message":{"description":"Human-readable message (often empty on success)","type":"string"},"status":{"description":"HTTP status code","type":"integer"},"success":{"description":"Operation completed successfully","type":"boolean"}}},"device.renameSummary":{"type":"object","properties":{"ambiguous":{"type":"integer"},"dry_run":{"description":"True when nothing was written","type":"boolean"},"errors":{"type":"integer"},"invalid":{"type":"integer"},"not_found":{"type":"integer"},"renamed":{"type":"integer"},"requested":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/device.renameResult"}},"unchanged":{"type":"integer"}}},"device.renameResult":{"type":"object","properties":{"device_id":{"description":"Matched Qubitro device id (when exactly one match)","type":"string"},"device_url":{"description":"Direct link to the matched device in the portal","type":"string"},"imei":{"type":"string"},"matched_device_ids":{"description":"Deprecated: use matches[].device_id. Retained for backwards compatibility.","type":"array","items":{"type":"string"}},"matches":{"description":"Every match when status == \"ambiguous\"","type":"array","items":{"$ref":"#/components/schemas/device.renameMatch"}},"message":{"description":"Human-readable detail for non-success statuses","type":"string"},"name":{"description":"Requested name (applied when status == \"renamed\")","type":"string"},"project_id":{"description":"Project the matched device belongs to","type":"string"},"status":{"description":"renamed | unchanged | not_found | ambiguous | invalid | error","type":"string"}}},"device.renameMatch":{"type":"object","properties":{"current_name":{"description":"The device's existing name","type":"string"},"device_id":{"description":"Qubitro device id","type":"string"},"device_url":{"description":"Direct link to the device in the portal","type":"string"},"project_id":{"description":"Project the device belongs to","type":"string"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/devices/rename-by-imei":{"post":{"description":"Renames Qubitro devices by matching each supplied Notehub module IMEI against the device's stored Notehub id (metadata.note_device). Intended to sync device names from an external source (e.g. an Airtable \"IMEI -> title\" table) without a human editing each device.\n\n**Matching:**\n- Pass the bare IMEI (e.g. `868531063306018`); the `dev:` prefix Notehub uses is applied automatically.\n- Matching is scoped to the authenticated customer (your API key), across all of your projects. If the key is restricted to a single project, only devices in that project are considered.\n\n**Behaviour:**\n- The endpoint never creates devices. A device only exists after Notehub delivers its first packet, so IMEIs whose device has not been created yet return `not_found` — re-run the sync later and they will be picked up. This makes the endpoint safe to call on a schedule.\n- Devices already carrying the requested name and the requested metadata are reported `unchanged` and are not rewritten.\n- `metadata`, when provided, replaces the device's existing custom metadata (same semantics as PUT device update).\n- Sending the same IMEI more than once in a batch is allowed; the last entry wins, and every entry is reported against the device's state as it was before the batch began.\n- A batch is capped at 1000 devices. Split larger fleets across sequential requests; there is no cross-request state, so any split is safe.\n\n**Per-item status:** `renamed`, `unchanged`, `not_found`, `ambiguous` (more than one device matched the IMEI), `invalid` (missing imei/name), or `error`. Treat this set as open — handle unrecognised values gracefully, because new statuses may be introduced.\n\n**Identifying devices:** every result that resolved to a device — `renamed`, `unchanged` and `error` — carries `device_id`, `project_id` and `device_url` (a direct link to the device in your portal, using your own domain if you are white-labelled). An `ambiguous` result lists each candidate under `matches`. `not_found` and `invalid` carry no identifiers because no device exists to identify. This means a single request is enough to sync names and collect links; no follow-up lookups are required.\n- `device_url` opens the device's own page in the portal. It is not a link to a Dashboard: dashboards are a separate resource, and a device may have several or none.\n- `device_url` is a best-effort convenience. It may be absent if the link cannot be resolved, and it may redirect if portal routing changes, so treat its absence as \"no link available\" rather than as information about the device. `device_id` and `project_id` are always present for a matched device.\n\n**Dry run:** send `\"dry_run\": true` to get the full per-device report without writing anything. Statuses and counters are identical to a real run, so a dry run is an exact rehearsal of the matching and classification a real run performs — `renamed` means \"would be attempted\". It does not prove the write itself would succeed, so `error` never appears in a dry run. The response always echoes `dry_run`; check it before trusting a report, because a misspelled flag is simply ignored and the run is real.\n\n**Stability:** this endpoint is supported and safe to build automations against. Changes will be additive — new fields may appear, but existing fields, status values and semantics will not change or be removed without advance notice to affected customers. `matched_device_ids` is deprecated in favour of `matches` and will continue to be returned.","tags":["Blues Notehub"],"summary":"Rename Notehub devices by module IMEI (batch)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/device.renameRequestBody"}}},"description":"Batch of IMEI -> name mappings (1..1000), optionally with dry_run","required":true},"responses":{"200":{"description":"Per-item rename report","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/main.Response"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/device.renameSummary"}}}]}}}},"400":{"description":"Invalid request body - devices array empty or exceeds 1000","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"403":{"description":"Forbidden - API key missing 'update' scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```

## Get device environment variables from Blues Notehub

> Retrieves environment variables for a Blues Notehub device. This endpoint proxies the request to the Blues Notehub API using your organization's stored Notehub PAT credential.\
> \
> \*\*Prerequisites:\*\*\
> \- Device must be a Blues Notehub device (source\_type: "notehub")\
> \- Organization must have a Notehub PAT credential configured in External Credentials\
> \- API key must have "read" scope permission\
> \
> \*\*How it works:\*\*\
> 1\. Validates your Qubitro API key and extracts your organization\
> 2\. Looks up the Notehub PAT credential stored in your organization's external credentials\
> 3\. Fetches the device to get its Notehub device UID\
> 4\. Proxies the request to Blues Notehub API\
> 5\. Returns the environment variables from Notehub

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"main.Response":{"type":"object","properties":{"action":{"description":"Action that was performed","type":"string"},"data":{"description":"Response payload (shape varies by endpoint)"},"message":{"description":"Human-readable message (often empty on success)","type":"string"},"status":{"description":"HTTP status code","type":"integer"},"success":{"description":"Operation completed successfully","type":"boolean"}}},"blues.environmentVariablesResponseBody":{"type":"object","properties":{"environment_variables":{"description":"Key-value pairs of environment variables","type":"object","additionalProperties":{"type":"string"}}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/blues/environment-variables":{"get":{"description":"Retrieves environment variables for a Blues Notehub device. This endpoint proxies the request to the Blues Notehub API using your organization's stored Notehub PAT credential.\n\n**Prerequisites:**\n- Device must be a Blues Notehub device (source_type: \"notehub\")\n- Organization must have a Notehub PAT credential configured in External Credentials\n- API key must have \"read\" scope permission\n\n**How it works:**\n1. Validates your Qubitro API key and extracts your organization\n2. Looks up the Notehub PAT credential stored in your organization's external credentials\n3. Fetches the device to get its Notehub device UID\n4. Proxies the request to Blues Notehub API\n5. Returns the environment variables from Notehub","tags":["Blues Notehub"],"summary":"Get device environment variables from Blues Notehub","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID (UUID format)","name":"device_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Environment variables retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/main.Response"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/blues.environmentVariablesResponseBody"}}}]}}}},"400":{"description":"Device is not a Blues Notehub device","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"424":{"description":"Notehub PAT credential not configured for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"502":{"description":"Blues Notehub API returned an error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```

## Set device environment variables in Blues Notehub

> Sets environment variables for a Blues Notehub device. This endpoint proxies the request to the Blues Notehub API using your organization's stored Notehub PAT credential.\
> \
> \*\*Prerequisites:\*\*\
> \- Device must be a Blues Notehub device (source\_type: "notehub")\
> \- Organization must have a Notehub PAT credential configured in External Credentials\
> \- API key must have "update" scope permission\
> \- Notehub PAT must have at least "developer" role permissions\
> \
> \*\*How it works:\*\*\
> 1\. Validates your Qubitro API key and extracts your organization\
> 2\. Looks up the Notehub PAT credential stored in your organization's external credentials\
> 3\. Fetches the device to get its Notehub device UID\
> 4\. Proxies the request to Blues Notehub API to set the environment variables\
> 5\. Returns success if the variables were set\
> \
> \*\*Note:\*\* Environment variables set via this endpoint will be synchronized to the Notecard device on its next sync with Notehub.

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"blues.setEnvironmentVariablesRequestBody":{"type":"object","properties":{"environment_variables":{"description":"Key-value pairs of environment variables to set","type":"object","additionalProperties":{"type":"string"}}}},"main.SuccessResponse":{"type":"object","properties":{"action":{"description":"Action that was performed","type":"string"},"message":{"description":"Human-readable success message","type":"string"},"status":{"description":"HTTP status code","type":"integer"},"success":{"description":"Operation completed successfully","type":"boolean"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/blues/environment-variables":{"put":{"description":"Sets environment variables for a Blues Notehub device. This endpoint proxies the request to the Blues Notehub API using your organization's stored Notehub PAT credential.\n\n**Prerequisites:**\n- Device must be a Blues Notehub device (source_type: \"notehub\")\n- Organization must have a Notehub PAT credential configured in External Credentials\n- API key must have \"update\" scope permission\n- Notehub PAT must have at least \"developer\" role permissions\n\n**How it works:**\n1. Validates your Qubitro API key and extracts your organization\n2. Looks up the Notehub PAT credential stored in your organization's external credentials\n3. Fetches the device to get its Notehub device UID\n4. Proxies the request to Blues Notehub API to set the environment variables\n5. Returns success if the variables were set\n\n**Note:** Environment variables set via this endpoint will be synchronized to the Notecard device on its next sync with Notehub.","tags":["Blues Notehub"],"summary":"Set device environment variables in Blues Notehub","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID (UUID format)","name":"device_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/blues.setEnvironmentVariablesRequestBody"}}},"description":"Environment variables to set","required":true},"responses":{"200":{"description":"Environment variables set successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.SuccessResponse"}}}},"400":{"description":"Invalid request body or device is not a Blues Notehub device","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"424":{"description":"Notehub PAT credential not configured for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"502":{"description":"Blues Notehub API returned an error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.qubitro.com/developers/blues-notehub.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
