Norvius REST API

Programmatic access to your data, automations, and reports. Available on the Business plan.

Authentication

All API requests require a Bearer token in the Authorization header. Create API keys from your dashboard under Settings → API Keys.

curl https://norvius.com/api/v1/sources \
  -H "Authorization: Bearer nrv_live_your_api_key_here"

Rate Limits

100 requests per minute per API key. Exceeding this limit returns HTTP 429. Rate limit headers are included in every response.

Errors

All errors return a JSON body with a consistent structure:

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key."
  },
  "status": 401
}

Permissions

API keys can be scoped to specific permissions. Each endpoint requires one permission.

read:sourcesread:automationsread:reportsread:accountwrite:automationswrite:webhooksexecute:queryexecute:sqlexecute:trigger

Data Sources

GET/api/v1/sourcesread:sources

List all connected data sources.

Response
{ "sources": [{ "id", "sourceType", "displayName", "status", "lastSyncAt", "createdAt" }] }
GET/api/v1/sources/:idread:sources

Get a data source with its detected schema.

Response
{ "source": { ... }, "schema": [{ "columnName", "detectedType", "sampleValues", "confidence" }] }

Data Queries

POST/api/v1/queryexecute:query

Run a natural language query against your connected data.

Request body
{ "query": "What were total sales last month?", "sourceId": "optional-uuid" }
Response
{ "results": [...], "sql": "SELECT ...", "interpretations": [...] }
POST/api/v1/sqlexecute:sql

Execute a pre-built read-only SQL query directly.

Request body
{ "sql": "SELECT ...", "sourceId": "uuid" }
Response
{ "results": [...], "sql": "...", "rowCount": 42 }

Automations

GET/api/v1/automationsread:automations

List all automations.

Response
{ "automations": [{ "id", "name", "scheduleCron", "status", ... }] }
GET/api/v1/automations/:idread:automations

Get automation details with latest run.

Response
{ "automation": { ... }, "latestRun": { "id", "status", "startedAt", ... } }
POST/api/v1/automationswrite:automations

Create a new automation from SQL and schedule.

Request body
{ "name": "...", "sql": "SELECT ...", "sourceId": "uuid", "scheduleCron": "0 9 * * 1", "timezone": "America/New_York" }
Response
{ "automation": { "id", "name", "status": "active", ... } }
PATCH/api/v1/automations/:idwrite:automations

Update schedule or pause/resume an automation.

Request body
{ "scheduleCron": "0 8 * * *", "status": "paused" }
Response
{ "automation": { ... } }
DELETE/api/v1/automations/:idwrite:automations

Soft-delete an automation.

Response
{ "ok": true }
POST/api/v1/automations/:id/triggerexecute:trigger

Manually trigger an automation run.

Response
{ "run": { "id", "status": "pending", "createdAt" } }

Reports

GET/api/v1/reportsread:reports

List generated reports.

Response
{ "reports": [{ "id", "automationId", "format", "generatedAt", ... }] }
GET/api/v1/reports/:id/downloadread:reports

Get a signed download URL for a report.

Response
{ "downloadUrl": "https://...", "expiresInSeconds": 300 }

Webhooks

GET/api/v1/webhooksread:automations

List webhook configurations.

Response
{ "webhooks": [{ "id", "automationId", "enabled", ... }] }
POST/api/v1/webhookswrite:webhooks

Create a webhook for an automation.

Request body
{ "automationId": "uuid", "url": "https://...", "events": ["run.completed"] }
Response
{ "webhook": { "id", "secret", ... } }
DELETE/api/v1/webhooks/:idwrite:webhooks

Remove a webhook.

Response
{ "ok": true }

Account

GET/api/v1/accountread:account

Get tenant information and usage stats.

Response
{ "account": { "name", "tier", ... }, "usage": { "dataSources", "automations", "teamMembers" } }
GET/api/v1/account/usageread:account

Get AI cost and automation run usage for the current period.

Response
{ "period": { ... }, "ai": { "totalInputTokens", "totalCostUsd" }, "automationRuns": 0 }

Example: Create and trigger an automation

# 1. Create an automation
curl -X POST https://norvius.com/api/v1/automations \
  -H "Authorization: Bearer nrv_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly Sales Report",
    "sql": "SELECT data->>'\''product'\'' as product, SUM((data->>'\''revenue'\''')::numeric) as total FROM data_rows WHERE source_connection_id = $1 GROUP BY 1 ORDER BY 2 DESC",
    "sourceId": "your-source-uuid",
    "scheduleCron": "0 9 * * 1",
    "timezone": "America/New_York"
  }'

# 2. Manually trigger it
curl -X POST https://norvius.com/api/v1/automations/{id}/trigger \
  -H "Authorization: Bearer nrv_live_your_key"

# 3. Check the result
curl https://norvius.com/api/v1/automations/{id} \
  -H "Authorization: Bearer nrv_live_your_key"