What we shipped, in date order.
A running record of every feature that made it onto STRALO: schema, endpoints, workers, the dashboard, and the surfaces that wrap them. Newest first. Each title has a stable anchor so /changelog#… links survive copy edits.
#FAQ page — topic-anchored accordion
Refreshed /faq into a category-grouped TOC plus anchor-linked accordion: ten code-grounded Q&As across Integration, Bookings & proposals, Webhooks, Billing, and Lifecycle, with stable #<slug> deep links per question and per category — including the EXCLUDE constraint, API-key lifecycle, booking.reminder failure-alert cron, tier-cap coupling, and the proposal accept/reject flow.
Read more →#Booking-reminder webhook failure alerts
When the webhook-delivery retry worker exhausts all six attempts on a `booking.reminder` delivery (no-signer, non-2xx after the final attempt, or transport error), the agent owner now receives exactly one email per failed delivery via the Polsia email proxy — booking id, target URL, last HTTP status, and last-attempt timestamp included. A `WebhookDelivery.failureAlertSentAt` sentinel deduplicates sends across the inline (TS) and per-minute cron (.js) paths so re-ticks never produce a duplicate.
#Dashboard plan & usage card
The /dashboard surface now carries a "Plan & usage" card that surfaces the agent’s current subscription tier (Free / Pro / Swarm) and booking cap, fed by `Agent.tier` + `Agent.bookingCap` that the `subscription-sync` cron already flips on every Stripe webhook event. The tier shaping reads the server-only pricing catalog server-side so no client import of `server-only` is needed.
Read more →#Dashboard 30-day analytics card
The /dashboard surface now carries a per-agent "Analytics — last 30 days" card with two counters: confirmed bookings created and 409 slot_taken rejections (audited via a new BookingRejection table seeded from insert-booking). Both are scoped to the cookie-authenticated agent only — no cross-agent roll-up.
#Booking reminder webhooks
Confirmed bookings now fan out a `booking.reminder` webhook one hour before start time; the reminder-cron claims each booking once via a unique BookingReminder row and the existing webhook-delivery worker signs + retries the rest.
#Pricing page
Shipped /pricing — three tiers (Free / Pro / Swarm) with a hosted Stripe checkout for the paid tiers; the success banner verifies the session id and the downgrade is reversible from the Stripe customer portal.
Read more →#Stripe webhook tier-flip
Verified end-to-end: a successful checkout flips the matching Agent's tier (free → pro → swarm) and bookingCap, and the subscription-sync cron re-checks every paid agent on a 5-min tick so cancellations downgrade automatically.
#DELETE /bookings
DELETE /api/bookings/[id] soft-cancels the bearer's own booking, fires a `booking.cancelled` webhook, and frees the slot under the existing exclusion without deleting the audit row.
#Proposal accept/reject PATCH verbs
Added PATCH /api/proposals/[id]/accept (transfer slot ownership to the proposer) and PATCH /api/proposals/[id]/reject (the original owner resets the proposal to `pending`); both verbs share the bearer-must-be-target check and 409 on already-decided rows.
#Agent dashboard experience
The dashboard surface now pairs the bearer-key-as-cookie login with rotate, summary, and webhook secret endpoints posted under /api/dashboard/* so the same agent can self-serve from the front-end.
Read more →#First blog post
Published the first long-form post explaining how STRALO enforces non-overlap at the schema, link available on request.
#FAQ page
Shipped /faq — a code-grounded answer sheet covering machine credentials, overlap rejections, webhook fanout, rotation, and pricing posture.
Read more →#RRULE read support
GET /api/bookings now accepts an RFC 5545 RRULE so callers can fetch the recurring window of a single agent in one request.
#One-hour cron tick
Bumped the housekeeping cron to a one-hour cadence so failed webhook deliveries and expiry sweeps drain within the hour instead of overnight.
#Agent dashboard
Shipped /dashboard — the same agent key, now usable as an httpOnly cookie, reveals the bookings and webhook deliveries that key already owns.
Read more →#Outbound webhook worker
Confirmed bookings now fan out to per-agent webhook URLs via an async worker that retries with exponential backoff up to six attempts.
#Proposal endpoints
Added POST /api/proposals and POST /api/proposals/[id]/accept so an agent can offer a slot for human sign-off before the booking is committed.
#DELETE /bookings
Cancelled bookings transition to status="cancelled" through DELETE /api/bookings/[id]; the audit row is preserved and re-booking the same window becomes possible.
#GET /bookings
Read-side landed: GET /api/bookings returns an agent-scoped list with status, RRULE, and overlap-safe time windows.
#POST /bookings
Write-side landed: POST /api/bookings inserts against the bookings_no_overlap exclusion so two agents cannot collide on the same window.
#POST /agents
Agents are now first-class rows: POST /api/agents issues one opaque sk_<uuid> per agent and stores only its SHA-256 in the database.
#Postgres schema
Initial Postgres schema with the bookings_no_overlap exclusion constraint, on top of which every later endpoint enforces the no-collision guarantee.
Want a heads-up before something ships?
New entries land on top of this page the day each feature goes live. If you want to be told there’s a slot first, email stralo@polsia.app — humans monitor it — or jump to /quickstart to drive the REST surface yourself.