Skip to content

Patterns — overview

LinkWorld gives you many primitives — ctx.kv, ctx.secrets, ctx.events, ctx.tools, on_inbound, heartbeats, wires, grants, rooms. Picking the right one for a use case isn’t obvious from the reference docs alone. This section solves that. Each pattern takes a real problem (“how do I react to an email”) and shows the canonical solution, the alternatives you should reject, and why.

Read this first if you’re building anything non-trivial. The reference docs explain what each primitive does; the patterns explain which one to reach for. Most architecture mistakes come from using a primitive that “could work” instead of the one LinkWorld designed for the job.

If you need to…Use this pattern
Store an API key, OAuth token, signing secretStoring credentials
Have each tenant plug in their own third-party keyBYO API keys
Run a multi-step process over hours, days, or weeksMulti-step workflows
React when a tenant receives an emailReacting to emails
Have one app trigger another app’s logicCross-app events
Reach a service LinkWorld doesn’t ship a skill forIntegrating non-platform services
Send more than a handful of emails per day per tenantSending email at scale

Going the other direction — if you’ve already reached for a specific primitive and want to sanity-check it’s the right one:

PrimitiveRight forWrong for — see instead
ctx.kvApp state, cursors, counters, non-sensitive prefsAPI keys → Storing credentials
ctx.secretsCredentials, tokens, signing secretsPublic settings → manifest install_settings
manifest.install_settingsUI-rendered tenant-tunable configPer-request state → ctx.kv
task_createOne-shot scheduled actions, simple cronMulti-step branching → Multi-step workflows
agents[].heartbeatsRecurring agent routines with judgmentPure DAGs → workflow primitives
lifecycle.on_inboundChannel-inbound (email, WhatsApp, voice, web)Cross-app events → Cross-app events
subscribes_toCross-app event consumptionInbound channels → Reacting to emails
ctx.events.emitPub/sub to subscribing appsSync RPC → ctx.apps.invoke
ctx.apps.invokeSync cross-app call needing an answerFire-and-forget → ctx.events.emit
ctx.team.delegateMaster agent → specialist in same appAcross apps → ctx.apps.invoke
ctx.tools.call (scoped)Platform-mediated third-party servicesProvider with API key → BYO API keys
HTTP request to third-party APIService you can’t reach via a scopeService the platform skills cover → scope catalog

Three questions to ask in order:

  1. Does LinkWorld ship a scope for this? Check the scope catalog. If yes, declare the scope and call the tool. Stop here.
  2. Does the third party expose a normal HTTP API? Then it’s BYO API keys — tenant brings the key, your app reads via ctx.secrets. Stop here.
  3. Is it a web-UI-only service? Then it needs a platform skill, not partner-app code. See Integrating non-platform services for how to request one.

If a pattern doc says ❌ DON’T, treat that as load-bearing — those came from real failures. Common offenders:

  • Storing API keys in ctx.kv (the lint will block deploy)
  • Polling email_search instead of using on_inbound
  • Building state machines instead of agent heartbeats
  • Calling another app’s HTTP endpoint directly (bypassing ctx.events.emit / ctx.apps.invoke)
  • Trying to run Playwright inside the partner-app sandbox
  • Sending unbounded outbound mail without a daily cap

If your draft architecture relies on any of the above, stop and read the matching pattern doc before you write more code.

These patterns will land as the platform surfaces stabilize:

  • Forms + approval flows (when the Commitments Inbox API stabilizes for partner-app use)
  • RAG-backed search inside app UIs (when bridge-side RAG hits GA)
  • Multi-domain sending (when platform-managed secondary domains ship)

If your use case isn’t covered above and the reference docs don’t make the answer obvious, open a discussion at github.com/linkworld/linkworld — the gap is on us, not on you.