Creating actions

This guide shows you how to register a Forte Action, test it, and inspect its delivery history. An Action calls a service path on a schedule or once at a set time.

Open Beta

Actions are available to all accounts during Beta. You can create and manage them from the console, CLI, or server-side SDK; interfaces and limits may change before GA.

Prerequisites

  • A Forte Project with at least one Service: an action targets a service in the project, not an arbitrary URL.
  • A path on that service that accepts a POST request.
  • For CLI/SDK use, the Forte CLI installed (forte login) or a project API token (FORTE_API_TOKEN).

1. Create your action

In the console

Open Actions in the sidebar and choose Create Action. Give it a name, pick the target service and the path to call on it, then pick a schedule:

  • Recurring: enter a cron expression (for example, 0 9 * * * for 9:00 every day) and a timezone (for example, America/New_York). Optionally set an active window.
  • One-time: pick the date and time it should run once.

Toggle Retry on failure if Forte should retry when your endpoint errors, and leave Enabled on to start the schedule immediately.

With the CLI

bash
# Recurring: 9:00 AM every weekday, New York time, with retries
forte actions create <projectId> \
  --name nightly-report \
  --service svc_<id> --path /jobs/nightly \
  --schedule recurring \
  --cron "0 9 * * 1-5" \
  --timezone America/New_York \
  --retryable
 
# One-time: run once at a specific instant (ISO 8601)
forte actions create <projectId> \
  --name launch-ping \
  --service svc_<id> --path /hooks/launch \
  --schedule one-time \
  --at 2026-07-01T16:00:00Z

Omit <projectId> and the CLI prompts you to pick one.

With the SDK (server-side)

typescript
import { ForteClient } from "@forteplatforms/sdk";
 
const forte = new ForteClient({ apiToken: process.env.FORTE_API_TOKEN });
 
const action = await forte.projects.createAction({
  projectId,
  createActionRequest: {
    name: "nightly-report",
    targetServiceId: "svc_...",
    targetPath: "/jobs/nightly",
    requestBody: JSON.stringify({ job: "nightly-report" }),
    scheduleType: "RECURRING",
    cronExpression: "0 9 * * 1-5",
    timezone: "America/New_York",
    retryable: true,
  },
});
Minimum cadence

A recurring action runs at most once per minute. Schedules that would fire more often are rejected.

2. Handle each request

When the action runs, Forte sends a POST to your URL with your body and three headers. Verify the trusted header, dedupe on the invocation ID, and return 2xx quickly:

typescript
app.post("/hooks/nightly", (req, res) => {
  // 1. Confirm the call really came from Forte.
  if (req.header("X-Forte-Trusted") !== "1") {
    return res.sendStatus(401);
  }
 
  // 2. Make the handler idempotent: Forte may retry.
  const invocationId = req.header("X-Forte-Action-Invocation-Id");
  if (alreadyProcessed(invocationId)) {
    return res.sendStatus(200);
  }
 
  // 3. Acknowledge fast; do slow work in the background.
  enqueueWork(req.body);
  res.sendStatus(200);
});

3. Test with Invoke now

You don't need to wait for the schedule. Trigger a one-off run to confirm your endpoint works:

bash
forte actions invoke <projectId> <actionId>
typescript
await forte.projects.createActionInvocation({ projectId, actionId });

This creates a manual invocation immediately, just like a scheduled run.

4. Inspect each invocation

Forte records each run as an invocation with its status, attempts, response code, and timing.

bash
forte actions invocations <projectId> <actionId>
typescript
const { items } = await forte.projects.listActionInvocations({ projectId, actionId });

In the console, open the action to see recent invocations, or View all for the full paginated history. A FAILED invocation means your endpoint errored after all attempts; a MISSED invocation means Forte didn't run that occurrence on time.

5. Pause, update, or cancel

bash
forte actions update <projectId> <actionId> --disable     # pause the schedule
forte actions update <projectId> <actionId> --enable      # resume
forte actions update <projectId> <actionId> --cron "0 */6 * * *"  # change schedule
forte actions cancel <projectId> <actionId> <invocationId>        # cancel a pending invocation
forte actions delete <projectId> <actionId>               # remove the action and its history

Pausing keeps the action and its history but stops new runs until you resume it.

Next steps

  • Read the Actions concept for the full status and retry model
  • Host the endpoint your action calls as a Service

Search

Search your resources, console pages, and documentation