Reference

fx

The complete fx surface — every call a flow can make, its signature, and the effect it records.

fx is the second argument of every do — the single door to the world. This page is the whole surface; each entry notes the effect it records, which is what feeds the Manifest, caching, and capability checks.

flow({
  do: async (input, fx) => {
    // everything below, on this one object
  },
});

Stores

SignatureRecordsReturns
fx.store(sqlDecl).select().from(t)…readrows (where · orderBy · limit · offset chainable)
fx.store(sqlDecl).insert(t).values(v)writePromise<void>
fx.store(sqlDecl).update(t).set(v).where(…)writePromise<void>
fx.store(sqlDecl).delete(t).where(…)writePromise<void>
fx.store(sqlDecl).findById(t, id)readrow | undefined
fx.store(kv).get / set(key, value, ttl?) / delete / list(prefix?)read / writeper op
fx.store(files).put / get / delete / list(prefix?)read / writeper op
fx.store(index).upsert / search(vector, topK?) / deleteread / writeper op

See Store for the query-builder surface.

Signals

SignatureRecordsNotes
fx.emit(signal, payload?)emitWith the postgres driver, joins your transaction

Flows

SignatureRecordsReturns / notes
fx.call(flow, input?)callThe callee's out — runs through the same pipeline
fx.step(name, fn)Durable step: replays from the journal, never re-runs
fx.fail(code, data, opts?)Typed failure value (opts.message overrides)

Channel

SignatureRecordsNotes
fx.send(template, { to?, data?, via? })sendvia orders the fallback chain; dry runs record would have fired

AI

SignatureRecordsReturns
fx.ask(prompt, input?, { via? })askObject validated against the prompt's out
fx.run(agent, input?)askAgent result
fx.stream(model, { prompt?, data? })askAsyncIterable<string> of chunks
fx.search(embed, query, { topK? })readMatches from the index/embed

AI calls are nondeterministic: journaling is forced on and auto-cache disabled around them.

Vault

SignatureRecordsReturns / notes
fx.vault(contract)readCleartext, inside this flow only — registered with the redactor at boot

Clock

SignatureNotes
fx.clock.now()Epoch-ms, injectable — the only legal "now"
fx.clock.sleep(label, duration)Durable sleep in durable flows; immediate otherwise

Durations: "200ms" · "30s" · "2m" · "1h" · "7d".

Cache

SignatureNotes
fx.cache.get(key)Value or undefined
fx.cache.set(key, value, ttl?)Optional TTL string
fx.cache.getOrSet(key, ttl, produce)Read-through; writes invalidate by effect

Responses

HelperStatusBody
fx.json.ok(value, { meta? })200{ data, meta?, error: null }
fx.json.create(value)201{ data, error: null }
fx.json.empty()204no body
fx.json.with(data, meta)200paginated envelope

Returning a plain value instead answers 200 with { data: value, error: null } — the helpers exist for status and meta control.

Logging, i18n, ids

SignatureNotes
fx.log.debug/info/warn/error(msg, data?)Redacting — secrets print as ***
fx.t(key, params?)Localized message from the i18n config
fx.id()UUID — the only legal id generator

Principals

PropertyShape
fx.auth{ userId: string | null, scopes: Set<string>, verified?: boolean }
fx.operator{ id: string | null } — Console plane
fx.tenant{ id: string | null } — active tenant

Learn more

  • Flow — why fx is the only door
  • Errors — what fx.fail produces
  • Configuration — the drivers behind these calls

On this page