Skip to main content
This is the programmatic path for applications. If you want a person to ask questions in chat, connect an AI assistant instead. If you want to author the queries this API runs, see Saved queries.

What it is

The Configview REST API lets your own applications — scripts, CI jobs, internal dashboards, scheduled audits — run your saved queries over HTTP and get JSON back. It reuses the exact same query engine that powers the dashboard, the Slack bot, and the AI connector, so a query behaves identically no matter which surface runs it. Calls are authenticated with a machine-to-machine API key, not a user login. Each key is minted by an admin and scoped to an explicit allowlist of queries — a key can only run the queries you granted it, and nothing else.
REST API (this page)AI connector (MCP)
CallerYour applications / scriptsA person, through Claude / ChatGPT / Gemini
AuthLong-lived API key (Authorization: Bearer …)OAuth 2.1, per-user
ScopeExplicit per-key query allowlistThe curated catalog
Best forAutomation, CI, scheduled jobs, embeddingAd-hoc questions in natural language
Both are read-only — they run saved queries, they don’t write to your systems and can’t run arbitrary SQL.

Base URL

Every Configview customer has a dedicated API at:
https://<your-subdomain>.configview.com/api/v1
Replace <your-subdomain> with whatever your team uses to log into the dashboard. If your dashboard is acme.configview.com, your API base URL is https://acme.configview.com/api/v1.

Authentication

Every request must send an API key as a Bearer token:
Authorization: Bearer cv_live_a1b2c3d4_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keys look like cv_live_<prefix>_<secret>. The <prefix> is a short non-secret identifier shown in the admin UI so you can tell keys apart; the <secret> portion is shown only once, at creation. A request with a missing or invalid key returns 401:
{ "error": "invalid_or_missing_api_key" }
Treat the full key like a password. Configview stores only a hash of it — if you lose it, you can’t recover it, only revoke it and mint a new one. Never commit a key to source control or embed it in client-side code.

Create an API key

API keys are minted from the dashboard by an admin.
1

Open the API Keys page

In the dashboard sidebar, go to Admin → API Keys.
2

Create a key

Click New key and fill in:
  • Name — a label so you can recognize it later (e.g. “CI nightly SOC2 audit”).
  • Allowed queries — search and select the saved queries this key may run. This is deny-by-default: a key with an empty allowlist can run nothing.
  • Rate limit — maximum requests per minute for this key (default 60).
  • Expiry (optional) — number of days until the key automatically stops working. Leave blank for a non-expiring key.
3

Copy the key now

The full cv_live_… key is shown exactly once. Copy it into your secret manager immediately — you won’t be able to see it again. If you lose it, revoke the key and create a new one.
To retire a key, click Revoke on the API Keys page. Revocation takes effect immediately on the next request.

Endpoints

All endpoints are relative to your base URL and require the Authorization header.

List queries

GET /api/v1/queries
Returns the queries this key is allowed to run (not your entire catalog).
{
  "queries": [
    {
      "seed_key": "okta.users_without_mfa",
      "title": "Okta users without MFA",
      "description": "Active Okta users with no enrolled MFA factor.",
      "category": "Identity",
      "labels": ["security", "okta"],
      "parameters": [],
      "max_age_seconds": 3600
    }
  ]
}
max_age_seconds is how long a cached result for that query stays fresh (see Caching). parameters describes any inputs the query accepts.

Get one query

GET /api/v1/queries/{seed_key}
Returns the metadata for a single query. Useful for discovering its parameter schema before running it. Returns 403 query_not_in_scope if the key isn’t allowed to run it, or 404 query_not_found if no such query exists.

Run a query

POST /api/v1/queries/{seed_key}/run
Runs the query and returns the result rows. The request body is optional:
FieldTypeDefaultDescription
paramsobject{}Values for the query’s parameters, keyed by parameter name.
force_livebooleanfalseBypass the cache and run against live data.
Example body:
{
  "params": { "days": 90 },
  "force_live": false
}
Response:
{
  "seed_key": "okta.users_without_mfa",
  "title": "Okta users without MFA",
  "columns": ["email", "status", "created"],
  "rows": [
    ["jane@acme.com", "ACTIVE", "2026-01-04"],
    ["raj@acme.com", "ACTIVE", "2026-02-19"]
  ],
  "row_count": 2,
  "from_cache": true,
  "cache_age_seconds": 142,
  "ran_at": "2026-06-18T14:21:00+00:00"
}
columns and rows are positional — rows[i][j] is the value for columns[j]. When from_cache is false, the response includes run_duration_ms instead of cache_age_seconds and ran_at.

Caching

By default, running a query returns the most recent cached result if it’s still fresh — fast, and easy on your integrations. Each query defines its own freshness window (max_age_seconds).
  • from_cache: true — you got a stored result; cache_age_seconds tells you how old it is.
  • from_cache: false — the cache was empty or stale, so the query ran live.
  • Pass "force_live": true to always run against live data (slower; use it sparingly).

Rate limits

Each key has a per-minute request limit (default 60, set when the key is created). Exceeding it returns 429:
{ "error": "rate_limit_exceeded" }
Back off and retry after the current minute. If you have a legitimate high-volume use case, mint the key with a higher limit or split work across keys.

Errors

All errors return a JSON body with an error field and the appropriate HTTP status.
StatuserrorMeaning
400params_must_be_objectparams was sent but isn’t a JSON object.
400invalid_parametersA parameter value was missing or the wrong type. detail explains.
401invalid_or_missing_api_keyNo Authorization header, or the key is unknown / expired / revoked.
403query_not_in_scopeThe key is valid but not allowed to run this query.
404query_not_foundNo query exists for that seed_key (or it was deprecated).
429rate_limit_exceededPer-minute limit for this key exceeded.
500query_execution_failedThe query ran but errored. detail has the message.

Call it from your application

Set the base URL and key once, then call the endpoints. Store the key in your secret manager or an environment variable — never hard-code it.
# List the queries this key can run
curl -s https://acme.configview.com/api/v1/queries \
  -H "Authorization: Bearer $CONFIGVIEW_API_KEY"

# Run a query with a parameter
curl -s -X POST \
  https://acme.configview.com/api/v1/queries/okta.users_without_mfa/run \
  -H "Authorization: Bearer $CONFIGVIEW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"params": {"days": 90}}'

Security best practices

Scope every key narrowly

Grant a key only the queries it needs. A CI audit key that runs three reports should be allowed exactly those three.

One key per consumer

Use a separate key per application or job. Revoking one then doesn’t disrupt the others, and the activity log attributes runs to the right caller.

Set an expiry

For temporary or contractor access, set an expiry so the key dies on its own even if no one remembers to revoke it.

Rotate by revoke-and-reissue

There’s no in-place rotation. To rotate, mint a new key, switch your app over, then revoke the old one.
Every API call is recorded in the dashboard Activity log, attributed to the key that made it.