Applications

Coordinator

Schedules and coordinates reliable webhook callbacks.

@scrape-admin/coordinator is a lightweight, multi-tenant service for scheduling webhook callbacks on a cron expression and retrying them reliably, rather than relying on each client (such as Web) to implement its own scheduling and retry logic.

It integrates with Scrape Admin's web app: a collection entry's destinations can be scheduled with the coordinator so the entry is refreshed on its cronExpression, with the coordinator calling back into the web app (or any other client) to run the actual work.

Authentication

Every request must send an x-tenant-id header identifying the caller. All scheduled webhooks and runs are scoped to that tenant — a tenant can only read or modify its own data.

API

All endpoints are under /api/v1/webhooks/scheduled:

MethodPathDescription
GET/List scheduled webhooks for the tenant.
POST/Create a scheduled webhook.
GET/:idGet a scheduled webhook.
PATCH/:idUpdate a scheduled webhook (reschedules it).
DELETE/:idMark a scheduled webhook for deletion.
GET/:id/runsList runs for a scheduled webhook.
POST/:id/runsManually trigger a run, outside its cron schedule.
GET/:id/runs/:runIdGet a single run.
POST/rebuildRebuild all of the tenant's schedules (for example, after a deploy).

A scheduled webhook has one or more destinations (see Schema's zWebhookDestination), an optional payload, and a cronExpression. Each run creates one attempt per destination and retries failed attempts up to maxAttempts times with the statuses pending, running, retrying, completed, and failed.

Typed client

@scrape-admin/coordinator-sdk wraps the API in a typed client for use from other apps — see Coordinator SDK for the full usage guide:

import { createCoordinatorClient } from '@scrape-admin/coordinator-sdk'

const coordinator = createCoordinatorClient({
  baseUrl: 'http://localhost:3001',
  tenantId: 'my-tenant',
})

const webhook = await coordinator.scheduledWebhooks.create({
  destinations: [{ url: 'https://example.com/hooks/scrape-complete' }],
  cronExpression: '*/5 * * * *',
})

await coordinator.scheduledWebhooks.runs(webhook.id).trigger()

For running the app locally or with Docker, see the coordinator README.

Copyright © 2026