API & integrations
Turn any report query into a data endpoint, push it to a webhook or another API, and let your own AI key help you write and chart the query. Endpoint, API POST and webhook reports are Premium. Building reports and connecting your own AI key is free.
Overview
Everything starts in Reports → New, where you choose the type. The first block of the report is the data source: its SQL (and optional Python) runs on our side and returns rows. What happens with the rows depends on the type:
| Type | What it does | Direction |
|---|---|---|
| API GET | Serves the rows at a public URL that you choose, optionally protected by a key. | Others read from us |
| API POST | Sends the rows to a URL of yours (POST, PUT or PATCH) when you press Send. | We call you |
| Webhook | The same as API POST, written for webhook receivers (Slack-style, Zapier, n8n, your own service). | We call you |
In the editor each type has Preview (see the rows without sending anything) and, for outgoing calls, Test send, which posts the real payload to an echo service (httpbin.org) so you can see exactly what a receiver would get.
API GET: publish a query
Create an API GET report, set an Endpoint path (letters, digits, - and _, up to 80 characters) and save. The URL is then:
GET https://cryptobi.se/reports/endpoints/<path>
Authentication (set per endpoint; the key is sent in a header only, never in the URL):
| Setting | How the caller sends it |
|---|---|
| None | Nothing. Anyone with the URL can read the rows: use it for data that is fine to publish. |
| API key | X-Api-Key: <key> (the header name is yours to choose) |
| Bearer | Authorization: Bearer <token> |
Formats (response_format): json_array (default: [{"symbol": "AAPL", "price": 231.4}, ...]),
json_object ({"data": [...]}, with a key name of your choice) and csv.
curl -H "X-Api-Key: YOUR_KEY" https://cryptobi.se/reports/endpoints/my-stock-data curl -H "Authorization: Bearer YOUR_TOKEN" https://cryptobi.se/reports/endpoints/my-stock-data
| Status | Meaning |
|---|---|
| 200 | The rows. |
| 401 | Missing or wrong key or token. |
| 403 | The owner no longer has Premium. |
| 404 | No endpoint with that path. |
| 429 | Too many requests (300 an hour per address). |
| 500 | The query failed: open the report and press Preview. |
| 503 | An authentication scheme is chosen but its key is empty: the endpoint refuses to serve rather than serving openly. |
The query runs as you, so user_crypto_time_view is your own list. Use LIMIT and keep the query under 3 seconds.
API POST: send rows to your URL
Create an API POST report, write the query in the first block, and fill in URL, Method (POST, PUT or PATCH), Body type and, if needed, authentication (Basic, Bearer or API key) and extra Headers as JSON. Press Save, then Send.
| Body type | What the receiver gets |
|---|---|
| JSON | Content-Type: application/json, body [{"column": value, ...}, ...] (dates as ISO text, numbers as numbers). |
| Form | application/x-www-form-urlencoded. One row becomes column=value; several rows become column_0, column_1, … |
| Raw | The text of the result as it is, with the Content-Type you set. |
# what your receiver sees for SELECT symbol, price FROM user_crypto_time_view LIMIT 2
POST /your/path HTTP/1.1
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
[{"symbol": "AAPL", "price": 231.4}, {"symbol": "BTC-USD", "price": 67210.5}]
The answer from your server is shown in the editor: status code, the first part of the body and a few headers.
Webhook
A webhook report is configured exactly like API POST (same settings, same payload, same limits). Use it when the receiver expects an event-style call: point the URL at your Zapier, n8n, Make or own service, choose JSON, and add the secret your receiver checks as a Bearer token or API key header.
Build reports with your own AI key
In Settings → AI assistant, connect a key from Anthropic or OpenAI. In the report editor, a block then has an Ask AI box: describe what you want to see ("my five stocks with the biggest 30-day fall, as bars"), and it proposes the block type, a title, the SQL and a short explanation. Use this SQL puts it in the editor and runs it, so you see the chart straight away; adjust it by asking again ("only Swedish stocks") with the current SQL as the starting point.
- Your key, your cost. Calls are billed by your provider to you. We never use a shared key.
- What is sent. Your question, the SQL in the editor and the names of the tables and columns you may query. No holdings, no rows of data.
- How it is kept. The key is stored encrypted, only its last four characters are shown again, and you can disconnect it at any time.
- The same rules as hand-written SQL. The proposal must pass the same security check; a rejected query is sent back to the model once to be fixed.
What you can query
Read-only SELECT (or WITH … SELECT) on these tables and views:
calendar, collectionticketlink, insider_transaction, symbolmetadata, ticker_analysis, ticketname, ticketprice, user_crypto_time_view, usercollection
The editor's Available fields panel lists the columns. ticketprice.datetime is in epoch seconds (to_timestamp(datetime)). A few things the sandbox does not allow:
set-returning functions such as generate_series, and a CTE with a column list (WITH x(a, b) AS).
Limits & safety
- Outgoing calls (API POST, webhook) reach public addresses only. Private networks, localhost and cloud metadata addresses are refused, redirects are not followed, and only ports 80, 443 and 1024–65535 are allowed. Certificates are always verified.
- An outgoing call times out after 15 seconds; we read at most 64 KB of the answer. At most 30 sends an hour.
- A query returns at most 100 000 rows and must finish within 3 seconds.
- Endpoint, API POST and webhook reports stop working when Premium ends; the reports themselves are kept.
- Anything that looks like abuse (scanning other people's systems, flooding a receiver) ends the access.
Not investment advice. Data comes from public sources and can be delayed or wrong.