Create a view
Creates a custom view from up to 20 named analytics queries and an HTML render bundle that draws their rows.
Each query is one SELECT over the analytics views (see Run an analytics query) and can use placeholders in the
form {name:Type}, filled in when the view's data is read: {period_start:DateTime64} and
{period_end:DateTime64} (the period's start, inclusive, and end, exclusive, as ISO 8601 timestamps), and
{filter_<name>:String} for each filter you declare (an empty string when the viewer picks no value). Every
query is compiled now, so a typo or a read outside the analytics views fails here with 400 VALIDATION_ERROR
rather than in your customer's dashboard. A view whose queries use the period placeholders needs a period.
A customer-scoped view (the default) starts as a DRAFT: publish it when it's ready. An
organization-scoped view is published straight away.
Body·
- Type: stringnamemin length:1required
The view's name.
- Type: 1…20queriesrequiredProperties: 2
The view's queries. Each is compiled when you save the view.
- Type: stringrender
Bundle min length:1max length:2000000requiredThe HTML document (with its scripts and styles inline) that draws the view, at most 2,000,000 characters. It must listen for the
spondo:datamessage, which carries the view's data: the same{ context, data }object Get a view's data returns. - Type: booleancaps
Enabled Whether the view shows the caps (usage limits) set on the customer's units.
- Type: string | nulldescription
What the view shows.
- Type: …5filtersProperties: 2
Filters viewers can set, at most 5.
- Type: booleanhierarchy
Enabled Whether viewers can narrow the view to one of the customer's units (teams, departments, tenants). When on, List a view's customer units lists the units to pick from.
- nullableperiod
The period the view shows by default. Required when a query uses the period placeholders.
A rolling window that ends when the data is read.
- amountType: integermin:1required
How many units the window covers.
- kindconst:relativerequired
- unitType: "day" or "month" or "year"enumrequired
- Type: enumscope
customer: shown to one customer at a time, with every query narrowed to that customer's records; can be embedded.organization: shows data across all your customers, for your own team; can't be embedded.valuescustomerorganization
Responses
- application/json
- application/json
curl https://billing.getspondo.com/api/v1/experimental/views \
--request POST \
--header "Authorization: Bearer $SPONDO_API_KEY" \
--header "Content-Type: application/json" \
--data @- <<'EOF'
{
"name": "Documents processed",
"description": "Signals per day for the selected period.",
"queries": [
{
"id": "daily",
"sql": "SELECT strftime('%Y-%m-%d', effective_timestamp) AS day, count(*) AS signals FROM fact_signal WHERE ({filter_signal:String} = '' OR signal_name = {filter_signal:String}) AND effective_timestamp >= {period_start:DateTime64} AND effective_timestamp < {period_end:DateTime64} GROUP BY day ORDER BY day"
},
{
"id": "total",
"sql": "SELECT count(*) AS signals FROM fact_signal WHERE ({filter_signal:String} = '' OR signal_name = {filter_signal:String}) AND effective_timestamp >= {period_start:DateTime64} AND effective_timestamp < {period_end:DateTime64}"
}
],
"renderBundle": "<!doctype html><html><body><div id=\"chart\"></div><script>addEventListener(\"message\", (e) => { if (e.data?.type === \"spondo:data\") draw(e.data); });</script></body></html>",
"period": { "kind": "relative", "unit": "day", "amount": 30 },
"filters": [{ "name": "signal", "values": ["document_uploaded", "contract_reviewed"] }],
"hierarchyEnabled": true
}
EOF
{
"hierarchyEnabled": true,
"capsEnabled": false,
"displayId": "view_3Rk8Tq1Zp6Wn0Ys4",
"name": "Documents processed",
"status": "DRAFT",
"previewUrl": "https://billing.getspondo.com/api/views/5c1e9a7b3d2f4e60_view_3Rk8Tq1Zp6Wn0Ys4/preview",
"scope": "customer"
}