REST API Reference
The Celiq API lets you query your data warehouse, retrieve semantic layer definitions, and embed Celiq data into your own applications. Available on the Team plan.
Base URL
All API requests must use HTTPS. HTTP requests will be rejected.
Authentication
Authenticate using an API key in the Authorization header.
Create API keys in your workspace under Lumen → API Keys.
curl https://app.celiq.co/api/v1/workspace \
-H "Authorization: Bearer clq_your_api_key_here"
Key format
All Celiq API keys begin with clq_ followed by 64 hex characters.
Keys can be revoked at any time from the API Keys page.
Rate limits
| Plan | Requests/minute | Queries/day |
|---|---|---|
| Team | 60 | Unlimited |
Rate limit headers are included in every response:
X-RateLimit-Limit, X-RateLimit-Remaining,
X-RateLimit-Reset.
Workspace
Response
{
"workspace": {
"id": "d3e30ecc-...",
"name": "Tickete",
"plan": "team",
"created_at": "2026-01-15T10:30:00Z"
}
}
Projects
Response
{
"projects": [
{
"id": "71d4bbc2-...",
"name": "Production Analytics",
"slug": "production-analytics",
"created_at": "2026-01-15T10:30:00Z"
}
]
}
Nodes
Path parameters
| Parameter | Type | Description |
|---|---|---|
| slug required | string | Project slug (e.g. production-analytics) |
Response
{
"nodes": [
{
"id": "...",
"name": "orders",
"status": "active",
"content": "node: orders\nlabel: \"Orders\"\n...",
"cml": "node: orders\nlabel: \"Orders\"\n...",
"created_at": "2026-01-15T10:30:00Z"
}
]
}
Path parameters
| Parameter | Type | Description |
|---|---|---|
| slug required | string | Project slug |
| name required | string | Node name (e.g. orders) |
Response
{
"node": {
"id": "...",
"name": "orders",
"content": "node: orders\nlabel: \"Orders\"\n...",
"cml": "node: orders\nlabel: \"Orders\"\n...",
"created_at": "2026-01-15T10:30:00Z"
}
}
Query
Run a raw SQL query against a connection in your workspace. Only SELECT, WITH, and EXPLAIN statements are allowed. Results are capped at 1,000 rows.
Request body
| Parameter | Type | Description |
|---|---|---|
| connection_id required | string | UUID of the connection to query against |
| sql required | string | SQL query (SELECT, WITH, or EXPLAIN only) |
| limit optional | integer | Max rows to return. Default: 1000. Max: 1000. |
Example request
curl -X POST https://app.celiq.co/api/v1/query \
-H "Authorization: Bearer clq_your_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "71d4bbc2-...",
"sql": "SELECT country, SUM(revenue) AS total_revenue FROM orders GROUP BY 1 ORDER BY 2 DESC LIMIT 10"
}'
Response
{
"columns": ["country", "total_revenue"],
"rows": [
{ "country": "India", "total_revenue": 124500 },
{ "country": "US", "total_revenue": 87200 }
],
"row_count": 2
}
Errors
The API uses standard HTTP status codes. Error responses include an
error field with a human-readable message.
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request — missing or invalid parameters |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — API access requires Team plan |
| 404 | Not found — project or node doesn't exist |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Error response format
{
"error": "Project not found"
}
SDKs & examples
Official SDKs are coming soon. In the meantime, the API works with any HTTP client.
Example: Daily Slack report
// Send yesterday's revenue to Slack every morning
const res = await fetch('https://app.celiq.co/api/v1/query', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.CELIQ_API_KEY}` },
body: JSON.stringify({
connection_id: process.env.CELIQ_CONNECTION_ID,
sql: "SELECT SUM(revenue) AS total_revenue, COUNT(*) AS order_count FROM orders WHERE order_date = CURRENT_DATE - 1",
}),
});
const { rows } = await res.json();
// Post to Slack
await slack.chat.postMessage({
channel: '#metrics',
text: `Yesterday: ₹${rows[0].total_revenue.toLocaleString()} revenue, ${rows[0].order_count} orders`,
});
Example: Export to CSV (Python)
import requests, csv
r = requests.post('https://app.celiq.co/api/v1/query',
headers={'Authorization': 'Bearer clq_your_key'},
json={
'connection_id': '71d4bbc2-...',
'sql': 'SELECT * FROM orders LIMIT 1000',
}
)
data = r.json()['rows']
with open('orders.csv', 'w') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)