Views
SQL queries kept as per-segment partials, read as tables by name.
Create a view
/v1/namespaces/{name}/views metered: query A view is a SQL query over one namespace (FROM docs) whose answer is kept as partials per segment: COUNT, SUM, MIN, MAX, AVG, COUNT(DISTINCT ...), COUNT_IF and f(...) FILTER (WHERE ...) over any WHERE, GROUP BY any expressions (DATE_TRUNC buckets, CASE, ...), with HAVING, ORDER BY and LIMIT applied on top. Name it as a table in SQL (SELECT * FROM daily_signups, or join it). It is always exact: a segment's partial is reused only while that segment's visible rows are the ones it was computed from, so a write or delete recomputes only the segments it touched. Views go with their namespace. Its name is the tenant's (not a namespace's name, not docs). Creating one runs it once (metered as a query) and answers its columns. A query that can't run from parts is refused with 422 view_not_decomposable and the reason; past the plan's views, 402 view_limit.
Parameters
namestring · pathrequiredThe namespace's name. |
Body application/json
namestringrequired1 to 64 of a-z, 0-9, '-', '_' and '.' |
sqlstringrequiredThe query, over docs. |
Answer
namestring |
namespacestring |
sqlstring |
created_atstring |
columnsstring[] |
typesstring[] |
Status codes
201Created |
400Malformed: not the JSON expected. |
401No key, or an unknown or revoked one. |
402The free plan's included usage this period is used up (queries, query CPU, object-storage reads, bytes returned, writes or storage; the message says which), or its namespace count or daily namespace creations are reached (code namespace_limit): upgrade to pro. |
403The key's scope or namespaces don't allow it, or the tenant is suspended. |
404No such namespace, document, key or tenant (or one this key may not see: the same answer). |
409Exists already, or not possible in this state. |
422Invalid: the message says why (code invalid with fields: which input fields; query_timeout: past the plan's time limit; scan_refused: send scan: true). |
429Over the tenant's or the key's rate, concurrency or cap, or writes arriving faster than the namespace commits them (code write_busy): retry after Retry-After seconds. |
503Object storage failed: retry (nothing was written, unless the code is write_unknown: then it may have been; retrying a write is safe). |
curl -s https://api.skimmerdb.com/v1/namespaces/support/views \
-H "Authorization: Bearer $KEY" \
-d '{"name":"daily_signups","sql":"SELECT DATE_TRUNC('day', ts) AS day, plan, COUNT(*) AS signups FROM docs WHERE kind = 'signup' GROUP BY 1, 2"}'from skimmerdb import SkimmerDB
from skimmerdb._api.api.views import create_view
db = SkimmerDB() # SKIMMERDB_KEY
answer = create_view.sync("support", client=db.api)import { SkimmerDB } from "skimmerdb";
import { createView } from "skimmerdb/api";
const db = new SkimmerDB(); // SKIMMERDB_KEY
const { data } = await createView({ client: db.client, path: { name: "support" }, body: {"name":"daily_signups","sql":"SELECT DATE_TRUNC('day', ts) AS day, plan, COUNT(*) AS signups FROM docs WHERE kind = 'signup' GROUP BY 1, 2"} });{
"name": "daily_signups",
"namespace": "events",
"sql": "SELECT DATE_TRUNC('day', ts) AS day, plan, COUNT(*) AS signups FROM docs WHERE kind = 'signup' GROUP BY 1, 2",
"created_at": "2026-10-18T09:00:00Z",
"columns": [
"day",
"plan",
"signups"
],
"types": [
"int",
"text",
"int"
]
}List a namespace's views
/v1/namespaces/{name}/views A view is a SQL query over one namespace (FROM docs) whose answer is kept as partials per segment: COUNT, SUM, MIN, MAX, AVG, COUNT(DISTINCT ...), COUNT_IF and f(...) FILTER (WHERE ...) over any WHERE, GROUP BY any expressions (DATE_TRUNC buckets, CASE, ...), with HAVING, ORDER BY and LIMIT applied on top. Name it as a table in SQL (SELECT * FROM daily_signups, or join it). It is always exact: a segment's partial is reused only while that segment's visible rows are the ones it was computed from, so a write or delete recomputes only the segments it touched. Views go with their namespace.
Parameters
namestring · pathrequiredThe namespace's name. |
Answer
viewsView[] |
views[].namestring |
views[].namespacestring |
views[].sqlstring |
views[].created_atstring |
Status codes
200OK |
401No key, or an unknown or revoked one. |
404No such namespace, document, key or tenant (or one this key may not see: the same answer). |
429Over the tenant's or the key's rate, concurrency or cap, or writes arriving faster than the namespace commits them (code write_busy): retry after Retry-After seconds. |
curl -s https://api.skimmerdb.com/v1/namespaces/support/views \
-H "Authorization: Bearer $KEY"from skimmerdb import SkimmerDB
from skimmerdb._api.api.views import list_views
db = SkimmerDB() # SKIMMERDB_KEY
answer = list_views.sync("support", client=db.api)import { SkimmerDB } from "skimmerdb";
import { listViews } from "skimmerdb/api";
const db = new SkimmerDB(); // SKIMMERDB_KEY
const { data } = await listViews({ client: db.client, path: { name: "support" } });{
"views": [
{
"name": "daily_signups",
"namespace": "events",
"sql": "SELECT DATE_TRUNC('day', ts) AS day, COUNT(*) AS signups FROM docs GROUP BY 1",
"created_at": "2026-10-18T09:00:00Z"
}
]
}Get a view
/v1/namespaces/{name}/views/{view} Parameters
namestring · pathrequiredThe namespace's name. |
viewstring · pathrequired |
Answer
namestring |
namespacestring |
sqlstring |
created_atstring |
Status codes
200OK |
401No key, or an unknown or revoked one. |
404No such namespace, document, key or tenant (or one this key may not see: the same answer). |
429Over the tenant's or the key's rate, concurrency or cap, or writes arriving faster than the namespace commits them (code write_busy): retry after Retry-After seconds. |
curl -s https://api.skimmerdb.com/v1/namespaces/support/views/view \
-H "Authorization: Bearer $KEY"from skimmerdb import SkimmerDB
from skimmerdb._api.api.views import get_view
db = SkimmerDB() # SKIMMERDB_KEY
answer = get_view.sync("support", "view", client=db.api)import { SkimmerDB } from "skimmerdb";
import { getView } from "skimmerdb/api";
const db = new SkimmerDB(); // SKIMMERDB_KEY
const { data } = await getView({ client: db.client, path: { name: "support", view: "view" } });{
"name": "daily_signups",
"namespace": "events",
"sql": "SELECT DATE_TRUNC('day', ts) AS day, COUNT(*) AS signups FROM docs GROUP BY 1",
"created_at": "2026-10-18T09:00:00Z"
}Delete a view
/v1/namespaces/{name}/views/{view} Its kept partials go with the segments they describe.
Parameters
namestring · pathrequiredThe namespace's name. |
viewstring · pathrequired |
Status codes
204Done (no body) |
401No key, or an unknown or revoked one. |
403The key's scope or namespaces don't allow it, or the tenant is suspended. |
404No such namespace, document, key or tenant (or one this key may not see: the same answer). |
429Over the tenant's or the key's rate, concurrency or cap, or writes arriving faster than the namespace commits them (code write_busy): retry after Retry-After seconds. |
curl -s -X DELETE https://api.skimmerdb.com/v1/namespaces/support/views/view \
-H "Authorization: Bearer $KEY"from skimmerdb import SkimmerDB
from skimmerdb._api.api.views import delete_view
db = SkimmerDB() # SKIMMERDB_KEY
answer = delete_view.sync("support", "view", client=db.api)import { SkimmerDB } from "skimmerdb";
import { deleteView } from "skimmerdb/api";
const db = new SkimmerDB(); // SKIMMERDB_KEY
const { data } = await deleteView({ client: db.client, path: { name: "support", view: "view" } });