Creating Actions
This guide walks through registering a Forte Action — a URL that Forte calls on a schedule or once at a set time — testing it, and inspecting its delivery history.
Actions are in beta. You can create and manage them today from the console, the forte actions CLI, or the server-side SDK.
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
POSTrequest. - For CLI/SDK use, the Forte CLI installed (
forte login) or a project API token (FORTE_API_TOKEN).
1. Create an 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 (e.g.
0 9 * * *for 9:00 every day) and a timezone (e.g.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
# 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:00ZOmit <projectId> and the CLI prompts you to pick one.
With the SDK (server-side)
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,
},
});A recurring action runs at most once per minute. Schedules that would fire more often are rejected.
2. Handle the 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:
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 it with "invoke now"
You don't have to wait for the schedule. Trigger a one-off run to confirm your endpoint works:
forte actions invoke <projectId> <actionId>await forte.projects.createActionInvocation({ projectId, actionId });This creates a manual invocation immediately, just like a scheduled run.
4. Inspect invocations
Each run is recorded as an invocation with its status, attempts, response code, and timing.
forte actions invocations <projectId> <actionId>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 did not run that occurrence on time.
5. Pause, update, or cancel
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 historyPausing 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