PAMbaseDocs
Guide

Calendar.

What you're building

A calendar app that publishes the user's schedule as events — signals other apps can react to. The payoff: a food app you've never heard of can offer lunch the moment a gap opens up, with zero integration between the two of you. You are the producer in PAMbase's canonical proactive flow.

Prerequisites

You have a connection token from the connect flow (the long-lived credential that authorizes your app for one user), and it carries the write scope memory:write:schedule.*. A scope is a single permission; this one lets your app write into the schedule namespace.

Scopes to request

ScopeWhy
memory:write:schedule.*publish free slots and bookings

A pure producer reads nothing, so request only this one. See permissions.

What to write

A signal is how your app tells the ecosystem something just happened: a type plus a structured payload. Emit free-form schedule.* signals with ISO-8601 UTC times — they fan out to subscribers and are never stored as memory.

typescript
await pambase.emitSignal({
type: "schedule.slot_free",
payload: { start: "2026-05-22T14:00:00Z", mins: 30 },
});
// → { accepted: true } — fanned out to subscribers; not memory.
await pambase.emitSignal({
type: "schedule.booked",
payload: { title: "Dentist", start: "2026-05-22T09:00:00Z", end: "2026-05-22T09:45:00Z" },
});
Signals notify; remember() persists

A signal is ephemeral — it triggers other apps' agents to react now. If you also want a durable record (“the user has a 2pm dentist appointment”), remember it in the schedule scope. Emitting needs signal:emit.

How to read

Reading is optional for a calendar. To surface upcoming context, recall from the schedule scope and let your LLM interpret it.

typescript
const { memories } = await pambase.recall({ query: "this week", scope: "schedule", limit: 10 });
// memories → [{ id, type, scope, content, importance, occurredAt, sourceApp? }, …]

Why this is proactive

This is the whole point. Emitting schedule.slot_free lets other apps react. A food / commerce app that subscribed to a webhook (an HTTP callback PAMbase fires when an event occurs) sees the slot, schedules a reminder, and gets lunch delivered in time — and neither app knew the other existed. Calendar plus commerce is the end-to-end canonical scenario.

Use ISO-8601 and standard names

Always send start/end as ISO-8601 UTC strings, and use the standard schedule.slot_free / schedule.booked names from the Catalog. That naming is the contract consumers match on — a custom name won't be picked up by other apps' subscriptions.

Next