API-first analytics: building on top of your BI platform
Most teams only use their BI tool through the browser. With an API you can generate reports on a schedule, refresh dashboards when new data lands and pull numbers into the tools people already use. Here is what that looks like, with working examples.
Most people use their BI tool the way it was designed to be used: open a dashboard, read it, maybe ask a question. That covers the daily work. But some jobs are better done by a script: producing the same report every Monday for twelve regional managers, refreshing a dashboard the moment a nightly data load finishes, or showing one number from the BI tool inside an internal admin page.
That is what "API-first analytics" means in practice. Anything you do repeatedly in the interface, you should be able to do with an HTTP request, so the repetition can be automated. This guide covers the useful patterns and shows how they work with the clariBI REST API.
What a BI API is good for
- Recurring reports that follow the same template and go to the same people.
- Orchestration: telling the BI tool that new data has arrived, instead of waiting for its schedule.
- Reading results into other systems: goal progress in a team wiki, report links in a ticketing tool.
- Bulk work: the same action across many dashboards or sources.
It is not a replacement for the interface. Exploring data, building a new dashboard and reading a chart are still easier in the browser.
The clariBI REST API at a glance
The documented API lives at https://claribi.com/api/v1/, with an interactive OpenAPI reference at /api/v1/docs/. It is available on the Professional and Enterprise plans (the API and developers page summarizes it). It covers:
- Reports: list, fetch, generate from a template, download as PDF, turn a public link on or off, delete.
- Dashboards: list, fetch with widgets, create, update, delete, refresh, public link.
- Data sources: list, fetch, start a sync. Sources are connected in the app, not through the API.
- Goals: list, fetch, read progress against target and milestones.
- Forecasts: create and configure, list runs, read results and accuracy history.
- Usage: your organization's usage counters.
The endpoint reference lists every method with the scope it needs.
Authentication
Create a key in Settings > Developer > API Keys. Each key has scopes (for example reports:read, reports:generate, dashboards:refresh) and an expiry of 30 days, 90 days, a year or never. The full key is shown once; clariBI stores only a hash. Send it as a bearer token:
Authorization: Bearer claribi_your_key_here
The API keys article covers scopes, expiry and how to replace a key without downtime.
Rate limits
| Plan | General requests | Generation requests (reports, dashboard refresh, forecast runs) |
|---|---|---|
| Professional | 1,000 per hour, 20,000 per day | 100 per hour, 500 per day |
| Enterprise | 5,000 per hour, 100,000 per day | 500 per hour, 2,000 per day |
Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. On a 429, wait until the reset time. Generating reports through the API uses AI credits, just as it does in the app.
Pattern 1: automated report delivery
This is usually the first integration worth building, because it replaces manual work every week.
A pipeline has four stages:
- Trigger: a cron job or your scheduler.
- Generate:
POST /reports/generate/with a template ID and the data sources to analyse. - Fetch: download the PDF from the returned
download_url. - Deliver: send it wherever your team reads things, such as a Slack channel or a shared drive.
A minimal Python version:
import os
import requests
BASE = "https://claribi.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['CLARIBI_API_KEY']}"}
resp = requests.post(
f"{BASE}/reports/generate/",
headers=HEADERS,
json={
"template_id": os.environ["WEEKLY_TEMPLATE_ID"],
"data_source_ids": [os.environ["STRIPE_SOURCE_ID"]],
"output_format": "pdf",
},
timeout=180,
)
resp.raise_for_status()
report = resp.json()
pdf = requests.get(f"{BASE}/reports/{report['report_id']}/download/",
headers=HEADERS, timeout=60)
pdf.raise_for_status()
with open("weekly-report.pdf", "wb") as f:
f.write(pdf.content)
The generate call waits until the report is ready, which can take a minute, so give it a generous timeout. If the organization is out of AI credits it returns 402 with the balance and estimated cost.
If all you need is "generate this report every Monday and email it to these people", you do not need code. Scheduled reports in the app do exactly that on Professional and Enterprise. Use the API when you need a destination the scheduler does not support, or logic around it, such as sending a report only to the regions whose numbers changed.
Pattern 2: refresh after your data loads
clariBI syncs most sources when their data is older than the sync interval (a day for most sources) and something needs it. If you run your own nightly load into PostgreSQL, you do not have to wait for that. Add two calls to the end of the load job:
POST /data-sources/{id}/sync/to pull the new rows.POST /dashboards/{id}/refresh/for the dashboards that people open first thing in the morning.
Refreshing an AI-generated dashboard re-runs its analysis and uses credits, so refresh the ones people read, not all of them.
Pattern 3: numbers in the tools people already use
Some numbers belong where the work happens. A few examples that the API supports:
- Post goal progress (
GET /goals/{id}/progress/: current value, target, percentage and milestones) to a team channel each Friday. - Add a link to the latest weekly report to a recurring meeting note.
- Read forecast results into a planning spreadsheet.
No outgoing webhooks: poll instead
clariBI does not send outgoing webhooks. To react to changes, poll on a schedule: check a report's status, compare a goal's progress with the last value you stored, and act when it changes. Polling every 15 minutes is well inside the rate limits.
Data can come in the other way: a Zapier webhook data source gives you a URL that a Zap can post rows to. The automation guide shows both directions.
Embedding
clariBI does not have an embedded analytics product. Public links (Professional and Enterprise) open a dashboard or report in a browser for people without an account, but they are not a component you place inside your own app. If embedding charts in a customer-facing product is the main goal, a tool built for embedded analytics is the better choice. Our comparison of self-service BI and embedded analytics covers that decision.
Working with AI assistants instead of scripts
If the "integration" you have in mind is really "I want to ask about my dashboards from Claude, Cursor or ChatGPT", look at the clariBI MCP server instead of the REST API. It exposes tools such as listing dashboards, running an analysis and generating a report to AI clients, and it is available from the Trial plan up. MCP keys and REST API keys are separate.
Security habits for API integrations
- One key per integration, so you can revoke one without breaking others.
- Minimum scopes. A script that reads reports needs
reports:read, notreports:delete. - Set an expiry for anything temporary.
- Keep keys on the server, in environment variables or a secrets manager. Never in browser code, a mobile app or version control.
- Handle errors deliberately. Retry
429and5xxwith backoff; alert a person on repeated401or403, which usually mean an expired key or a missing scope. - Replace keys on a schedule and immediately when someone who had one leaves.
A first project
Pick a report someone assembles by hand every week, one that takes an hour or two and always has the same shape.
- Find or create the report template in clariBI that answers the same questions.
- Create an API key with
reports:readandreports:generate. - Write the script above, pointed at that template and the right data sources.
- Run it alongside the manual report for two weeks and compare the numbers.
- When they agree, schedule the script and retire the manual version.
That one script teaches you authentication, rate limits and error handling on a job with a clear payoff, which makes the next integration much quicker.