Tidebase Tidebase GitHub Start self-hosting
Docs

How to wire Tidebase into a SvelteKit app

SvelteKit endpoints receive a web Request, which is exactly what Tidebase’s recovery webhook handler takes — so the webhook mounts in one line, and your routes enqueue durable runs and read live run state for the UI. No adapters anywhere.

// src/routes/api/tidebase/+server.ts — recovery webhook
import { Tidebase } from '@tidebase/sdk'
import { generateReport } from '$lib/workflows/generate-report'

const tide = new Tidebase()
tide.workflow('generate-report', generateReport)
const handler = tide.webhook()

export const POST = ({ request }) => handler(request)
// src/routes/api/reports/+server.ts — enqueue, don't execute
import { json } from '@sveltejs/kit'
import { Tidebase } from '@tidebase/sdk'

const tide = new Tidebase()

export async function POST({ request }) {
  const { topic } = await request.json()
  const { run } = await tide.enqueue('generate-report', {
    input: { topic },
    dedupeKey: `report-${topic}`
  })
  return json({ runId: run.id })
}
// src/routes/reports/[runId]/+page.server.ts — live progress for the page
import { Tidebase } from '@tidebase/sdk'

const tide = new Tidebase()

export async function load({ params }) {
  const detail = await tide.runs.get(params.runId)
  return { status: detail.run.status, state: detail.state, gates: detail.gates }
}

Tidebase is an open-source checkpoint layer for AI agents: wrap your steps, and failed runs resume from the last safe point — in your own Postgres, without moving execution into a new runtime.

The shape

  • Enqueue from endpoints. tide.enqueue writes a durable queued run (deduped against double submits) and returns the runId immediately — the request never carries agent work, which keeps you inside serverless limits on adapter-vercel/netlify deployments.
  • Execute in a worker. The honest tradeoff, stated plainly: Tidebase does not execute your code. A long-lived Node process runs tide.work({ queues: ['default'] }) with your workflows registered and executes jobs off the queue; retries, backoff, and lease-expiry requeues are Tidebase’s job. On serverless SvelteKit deployments this worker is a small companion service.
  • Load run state in load. Progress, step results, and pending gates come from runs.get — server-rendered, no client polling infrastructure required (poll or use SvelteKit’s invalidate on whatever cadence suits the page).

Approvals on your own pages

A workflow paused at run.gate('approve-send', ...) appears in the load data above as a pending gate. Render approve/reject buttons and resolve from a form action using the resolveUrl and resolveToken the gate’s webhook channel delivers — durable, exactly-once, recorded with the actor. See human approval gates.

Recovery semantics

When a non-queue run stalls or fails, Tidebase POSTs a signed run.resume payload to /api/tidebase; the SDK verifies the HMAC (TIDEBASE_WEBHOOK_SECRET on both sides) and re-invokes the workflow with the same runId. Completed steps replay from Postgres per the replay contract. The webhook executes the remaining workflow inline, so on serverless it inherits the platform’s time limits — for long tails, prefer queues, where the reconciler requeues without a webhook.

What Tidebase does not do here

  • Alpha, opt-in auth. Set TIDEBASE_API_KEY before exposing the Tidebase server beyond localhost.

Repo: https://github.com/BlueprintLabIO/tidebase · See also: How to run durable AI workflows behind a Next.js route