Build a dashboard on the platform alone
Stores, files and hosted APIs are in beta and enabled per workspace. Without the grant every endpoint here answers 402.
This is the case the platform is built around, done with nothing but the API.
A coding agent given this page and the reference can assemble it; every call below is an operation in the SDK, named after the operationId you see in the reference.
The shape, in one sentence: the run is your backend function, and each route is a fast path past it for one common operation. Reading a collection, reading a record, summarising a collection, serving a file and writing a record have fast paths. Anything else goes through a run, which is an agent with tools and a person.
What you end up with
- A store,
leads, that an agent fills and your users read and write. - A hosted API at
acme-leads.apis.speechify.aiwith four routes: a list, a summary, a create and an update. - A front end published as files and served by the same API under
/app/*. - An audience: your own workspace for an internal tool, or your users through a token your backend signs.
1. Create the store
Name it for what is in it. An agent attached to it reads the name and the description to decide whether to look here, and a coding agent reads them the same way.
A store is Firestore-shaped: store > collection > document, schemaless JSON, filters on top-level fields, one order_by, a limit, cursor paging, and one aggregate operation.
There are no joins, nested-field filters, full-text search or SQL, on purpose.
The ids query, batch and aggregate are reserved: they are operations on a collection, not documents in it.
2. Let an agent fill it
Attach the store to the agent that produces the data, and give it a run that writes.
A run reads and writes the store with store_query, store_get, store_put, store_delete and store_aggregate.
Ask for one document per lead with a stage and a value, and the agent’s writes land in the leads collection like any other document.
3. Assemble the API
Pick the audience while you create it, narrowest first:
An internal dashboard is a workspace API and needs no key at all: every member’s own credential works.
A customer-facing one is a user_token API, and every route can then scope records to the person calling.
A workspace can refuse public as policy (hosted_apis_public_allowed), and the console asks twice before opening an API to the internet.
4. Add the routes
Each route names what answers it. The four below are the whole dashboard.
The list. GET /leads with a store_query resolver over leads, filtered by a request value the caller may or may not send:
The summary. GET /summary with a store_aggregate resolver: a count and a sum per stage, in one request, from the index rather than the bodies:
The create. POST /leads with a store_write resolver: the POST body lands as a document and the platform mints the id:
The update. POST /leads/{id} with write_mode: merge: the fields sent replace their namesakes on the document the path names and the rest stay:
On a workspace, owner or user_token API the written document carries user_identity set to the caller, and only they can change it afterwards.
Add { "field": "user_identity", "op": "eq", "value": "{{user.sub}}" } to the list’s where and every user sees their own leads.
A write route is never served by a public API, and it counts against the API’s daily_write_cap the way reads and runs count against theirs.
Send an Idempotency-Key from the browser and a retried request replays the first answer instead of writing twice.
5. Publish the front end
Upload the built application as kept files under one prefix, and serve the tree from one route:
/app/ answers dash/index.html, /app/assets/main.js answers dash/assets/main.js, and a deep link with no file behind it answers the entry document, so a client-routed app survives a refresh.
A rebuild that renames its assets uploads new files and touches no route.
Add the API’s own origin to cors_origins if the front end is served from somewhere else; served from /app/* it is same-origin and needs nothing.
6. Call it
From the published front end, on a workspace API:
On a user_token API, replace the key with the JWT your backend signed for the user, and the same calls answer only that person’s leads.
The API’s own OpenAPI document is at /openapi.json, so a coding agent can generate a client for the routes you assembled.
What to watch
Reads, runs and writes today against each cap, per route. A response served from the cache is not a read; a replayed write is not a write.
Where the rest lives
- Runs, tools and the agent’s side of the store: Give an agent data it can query.
- Files, kept and working: Attach a file to a run.
- What a store is and is not: Where content lives.