Core concepts

Tasks

Tasks

One-off webhook dispatches with scheduled execution and payload control.

A task is a one-off HTTP dispatch. You define a target URL, an HTTP method, an optional payload, and an optional scheduled time. Underlayer will make the HTTP call at the specified time (or immediately) and record the result.

Creating a task

POST /api/v1/scheduler/tasks

{
  "name": "send-invoice",
  "url": "https://my-service.com/hooks/invoice",
  "method": "POST",
  "headers": { "X-Source": "underlayer" },
  "payload": { "invoice_id": "inv_001" },
  "execute_at": "2025-09-15T09:00:00Z"
}

Fields

  • name: human-readable label shown in the dashboard.
  • url: the endpoint Underlayer will call.
  • method: HTTP verb: GET, POST, PUT, PATCH, DELETE.
  • headers: optional object of additional request headers.
  • payload: optional JSON body (forwarded as-is).
  • execute_at: required ISO 8601 future timestamp. The API rejects past or present values.

Task lifecycle

A task moves through the following states:

  • pending: waiting for execute_at to arrive.
  • processing: claimed by the worker; HTTP call in progress.
  • retrying: dispatch failed but retries remain; waiting for next_retry_at.
  • success: terminal — last dispatch returned a 2xx status.
  • dead: terminal — retries exhausted without a 2xx. Task moves to the dead-letter queue.
  • cancelled: terminal — cancelled by the system (e.g. monthly execution limit reached or storage quota exceeded).

Cancelling a task

You can cancel a pending task before it dispatches via DELETE /api/v1/scheduler/tasks/{id}. Once a task has started running it cannot be cancelled.

Scheduling requirement

execute_at is required and must be a future ISO 8601 timestamp. The API rejects past or present timestamps. If you need to trigger a dispatch immediately without a scheduled time, use Publish events instead of tasks.

Publish events (immediate)

Publish events are the immediate-dispatch path. Use POST /api/events when you want fan-out without scheduling a future execute_at.

POST /api/events

{
  "topic": "orders.created",
  "payload": { "order_id": "ord_123" },
  "target_url": "https://my-service.com/hooks/orders"
}