The manifest entry
tappify.extension.json instead — the
$schema line gives your editor completion and validation, and
tappify extension doctor checks the result.
cache is the one field the command leaves out: add "1m", "5m" or "1h" yourself when
repeating the same input over the same window is safe.
kind: "read" is retried twice when the connection fails. kind: "write" is never retried,
and neither is a call that timed out. A procedure whose name reads like a write — create,
update, delete, send, set — without kind: "write" is a doctor warning.
Calling it
await tap.server.getSummary({ days: 7, platform: "all" }). Both
are typed from the two schemas once you have run
tappify extension types.
Handling it
request carries everything the host knows:
User-scoped documents are the one thing missing from
documents: they never leave the host.
What the host does around it
- Validates your input against the declared schema.
- Answers from its own cache when the declaration has a
cachewindow and the same install asked the same thing over the same filters. - Mints a five-minute install token and posts to
POST {server.baseUrl}/tappify/procedures/getSummarywith that token, the credentials, the documents and the current filters. A sandbox project usesserver.sandboxBaseUrlwhen you declared one. - Validates your output against the declared output schema.
- Caches the result for the declared window.
- Records the call and its latency on your Runtime page.
TapServerError { code, message } carrying your own code and message — the
message is what your component shows, so write one a person can act on.
A procedure is for reads and for your own bookkeeping. Anything that changes the owner’s
data in your system is an action, and an action goes through an approval card.
Deploy your server
Where the handler above runs, and what to set
server.baseUrl to.Testing with the SDK
Drive the handler above with
createTestClient, the way Tappify calls it.