Update a saved query
curl -X PATCH 'https://api.justcrawl.io/api/v1/bi/saved-queries/$SAVED_QUERY_ID' \ -H 'Authorization: Bearer $JUSTCRAWL_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"description":null}'Partial update. Any field you omit is left unchanged; at least one must be present or the
call returns 400 invalid_body.
description and chartConfig distinguish omission from clearing: sending null
explicitly clears the field, while leaving the key out keeps the current value.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”At least one property is required.
object
Send null to clear; omit to keep.
Send null to clear; omit to keep.
object
Responses
Section titled “Responses”Updated
object
A saved BI query. Returned by the single-row routes (get, create, patch, and the share mint/revoke pair). List rows drop shareToken and add isShared plus scheduleCount instead.
object
Public raw SQL. Null for structured definitions and all agent-scoped rows.
Read-only structured preview, or protected scoped-SQL preview. Never submit this to reconstruct scope.
192-bit bearer capability granting unauthenticated read of this query’s results via /api/v1/share/sql/{token} — outside authentication and outside the BI feature flag. Never log it, never persist it outside your own secret store, and never include it in an agent transcript. Revoked via DELETE /api/v1/bi/saved-queries/{id}/share — a working route that, like this mint endpoint, is deliberately withheld from this contract rather than dashboard-only. Single-row responses only; the list route returns isShared instead.
object
Example
{ "savedQuery": { "contentKind": "sql", "scopeKind": "org", "sqlDialect": "postgres", "chartConfig": { "type": "bar" } }}Empty body (invalid_body) or a rejected field (invalid_name, invalid_sql, invalid_description)
object
object
Stable, machine-readable error code. Match on this, not on message.
Customer-safe description. Never raw exception or driver text, with one deliberate exception: a syntax_error (SQLSTATE 42601) passes the database’s own message through verbatim, because it describes SQL the caller wrote themselves and names nothing they could not already see — see the root CLAUDE.md §Error reporting for the full carve-out.
Reference page for this code. Codes shared with the rest of the API have their own page; the BI-local vocabulary points at the single BI errors page that tabulates all of them.
Correlation id. Identical to the X-Request-ID response header — quote either one to support.
object
Example
{ "error": { "code": "invalid_body" }}Missing or invalid authentication token
object
Example
{ "error": "Missing or invalid authentication token"}Access to the BI surface itself is refused. no_org and feature_disabled fire on every BI route from the mount guard, before any handler runs — feature_disabled is the first response most new integrations see, because the SQL console is entitled per organization. Permission and verified-email gates use insufficient_permissions and email_not_verified; rls_denied and kill_switched come from the engine. This response never describes resource-level authorization: an id you do not own returns 404, not 403.
object
object
Stable, machine-readable error code. Match on this, not on message.
Customer-safe description. Never raw exception or driver text, with one deliberate exception: a syntax_error (SQLSTATE 42601) passes the database’s own message through verbatim, because it describes SQL the caller wrote themselves and names nothing they could not already see — see the root CLAUDE.md §Error reporting for the full carve-out.
Reference page for this code. Codes shared with the rest of the API have their own page; the BI-local vocabulary points at the single BI errors page that tabulates all of them.
Correlation id. Identical to the X-Request-ID response header — quote either one to support.
object
Example
{ "error": { "code": "feature_disabled", "message": "SQL console is not enabled for this organization", "docs_url": "https://docs.justcrawl.io/guides/errors/bi", "request_id": "req_9f3a1c7e2b40" }}Not found, or not owned by your organization. The two are deliberately indistinguishable so cross-tenant existence cannot be probed
Error envelope returned by every /api/v1/bi/* handler error. Unlike the rest of the API — where the structured shape is opt-in via the application/vnd.justcrawl.v1+json media type — a BI handler always emits it, and all four fields are always present. The one exception: 401s from missing or invalid auth are rejected by shared middleware before any BI handler runs, so they carry the flat { "error": "<message>" } shape (Error schema) instead — see the Unauthorized response on each operation.
object
object
Stable, machine-readable error code. Match on this, not on message.
Customer-safe description. Never raw exception or driver text, with one deliberate exception: a syntax_error (SQLSTATE 42601) passes the database’s own message through verbatim, because it describes SQL the caller wrote themselves and names nothing they could not already see — see the root CLAUDE.md §Error reporting for the full carve-out.
Reference page for this code. Codes shared with the rest of the API have their own page; the BI-local vocabulary points at the single BI errors page that tabulates all of them.
Correlation id. Identical to the X-Request-ID response header — quote either one to support.
Example
{ "error": { "code": "not_found", "message": "Query not found", "docs_url": "https://docs.justcrawl.io/guides/errors/not_found", "request_id": "req_9f3a1c7e2b40" }}The new name is already taken in this organization (saved_query_name_taken)
object
object
Stable, machine-readable error code. Match on this, not on message.
Customer-safe description. Never raw exception or driver text, with one deliberate exception: a syntax_error (SQLSTATE 42601) passes the database’s own message through verbatim, because it describes SQL the caller wrote themselves and names nothing they could not already see — see the root CLAUDE.md §Error reporting for the full carve-out.
Reference page for this code. Codes shared with the rest of the API have their own page; the BI-local vocabulary points at the single BI errors page that tabulates all of them.
Correlation id. Identical to the X-Request-ID response header — quote either one to support.
object
Example
{ "error": { "code": "saved_query_name_taken" }}The chartConfig field is present but malformed (invalid_chart_config)
Error envelope returned by every /api/v1/bi/* handler error. Unlike the rest of the API — where the structured shape is opt-in via the application/vnd.justcrawl.v1+json media type — a BI handler always emits it, and all four fields are always present. The one exception: 401s from missing or invalid auth are rejected by shared middleware before any BI handler runs, so they carry the flat { "error": "<message>" } shape (Error schema) instead — see the Unauthorized response on each operation.
object
object
Stable, machine-readable error code. Match on this, not on message.
Customer-safe description. Never raw exception or driver text, with one deliberate exception: a syntax_error (SQLSTATE 42601) passes the database’s own message through verbatim, because it describes SQL the caller wrote themselves and names nothing they could not already see — see the root CLAUDE.md §Error reporting for the full carve-out.
Reference page for this code. Codes shared with the rest of the API have their own page; the BI-local vocabulary points at the single BI errors page that tabulates all of them.
Correlation id. Identical to the X-Request-ID response header — quote either one to support.
Examplegenerated
{ "error": { "code": "example", "message": "example", "docs_url": "https://example.com", "request_id": "example" }}Unexpected server error. Full detail goes to the logs and PostHog $exception capture, never the response
Error envelope returned by every /api/v1/bi/* handler error. Unlike the rest of the API — where the structured shape is opt-in via the application/vnd.justcrawl.v1+json media type — a BI handler always emits it, and all four fields are always present. The one exception: 401s from missing or invalid auth are rejected by shared middleware before any BI handler runs, so they carry the flat { "error": "<message>" } shape (Error schema) instead — see the Unauthorized response on each operation.
object
object
Stable, machine-readable error code. Match on this, not on message.
Customer-safe description. Never raw exception or driver text, with one deliberate exception: a syntax_error (SQLSTATE 42601) passes the database’s own message through verbatim, because it describes SQL the caller wrote themselves and names nothing they could not already see — see the root CLAUDE.md §Error reporting for the full carve-out.
Reference page for this code. Codes shared with the rest of the API have their own page; the BI-local vocabulary points at the single BI errors page that tabulates all of them.
Correlation id. Identical to the X-Request-ID response header — quote either one to support.
Example
{ "error": { "code": "internal_error", "message": "Failed to list queries", "docs_url": "https://docs.justcrawl.io/guides/errors/internal_error", "request_id": "req_9f3a1c7e2b40" }}