Skip to main content

What is an action?

An action is a single HTTP request task: SafeFetch stores the request intent, makes the HTTP request to any URL (API endpoint, internal service, etc.), retries if needed, and stores the final result.

Lifecycle

StatusDescription
pendingQueued, waiting for dispatch
activeHTTP request in flight
awaiting_approvalHeld for human approval
completedTarget API responded successfully
failedMax retries exhausted
cancelledCancelled by user

Action fields

id
string
required
Unique action ID (for example act_...).
status
string
required
Lifecycle status: pending, active, awaiting_approval, completed, failed, cancelled.
url
string
required
Target URL for the HTTP request.
method
string
required
HTTP method (GET|POST|PUT|PATCH|DELETE).
body
object|null
JSON body sent to the target URL.
headers
object|null
Optional per-action outbound headers.
dedupe
string|null
Deduplication key for semantic duplicates (24-hour window).
idempotency_key
string|null
Idempotency key from request header (24-hour window).
attempts
integer
required
Number of delivery attempts already used.
retries
integer
required
Maximum delivery attempts before failed.
callback
string|null
Optional URL notified on completion/failure.
actions
string[]
Allowed operations for current status (approve, cancel, retry).
error
object | null
Structured error detail, present only when status is failed. Contains:
  • source"target" if the endpoint returned a non-2xx response; "dispatch" for network errors, DNS failures, or timeouts.
  • message — human-readable description (same as last_error).
  • response_code — HTTP status code from the target (null for dispatch errors).
  • response_body — response body from the target (null for dispatch errors).

Synchronous mode

Pass sync: true when creating an action to block the request until the action reaches a terminal status (completed, failed, or cancelled). The response is the final action object with response_code, response_body, and duration_ms populated.
curl -X POST http://localhost:3000/v1/actions \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://api.example.com/charge", "body": { "amount": 500 }, "sync": true }'
# Response arrives only after the action completes (or times out)
Timeout: The server holds the connection for up to 30 seconds by default (max 120 seconds). If the action hasn’t completed by then, the response returns the current action state with status: pending or status: active. Incompatible with approve: true. Synchronous mode cannot wait for a human to approve. Combining both returns 400 invalid_sync.

Available operations

actions: ["cancel"]

Receipt page

Every action gets a shareable receipt_url (e.g. /r/rcpt_...) returned in the API response on creation and retrieval. The receipt page shows the full action lifecycle — status, URL, timing, attempts, request body, and response — with sensitive headers masked. No authentication is required to view a receipt; access is secured by the unguessable receipt token.

Computed fields

receipt_url
string
Shareable URL for this action’s receipt page. Secured by an unguessable token — no authentication required to view.
retries_remaining
integer
Returned for retried pending/active actions. Computed as retries - attempts.
next_retry_in_seconds
integer
Seconds until next_retry_at when a retry is scheduled.