Docs / REST API Reference

REST API Reference

Apex REST resources shipped with FlowMason. All endpoints sit under ${OrgDomain}/services/apexrest/... and require session auth (the caller must hold the relevant permset).

Authentication

All endpoints honour the calling user's session, FLS, and CRUD via FMSecurityUtil. Two auth flows:

  1. Standard Salesforce OAuth. Authorization: Bearer <session_id>.
  2. Connected App. For headless integrations; consumer key/secret + Named Principal user with the required permset.

No API-key auth. Every call is on behalf of a real user.

Base URLs

FamilyBasePermset
Pipeline runs/services/apexrest/api/v1/runs/*FlowMason_Pipeline_Runner
AI chat/services/apexrest/api/v1/ai/*FlowMason_Org_Chat_User
Templates/services/apexrest/api/v1/templates/*FlowMason_Pipeline_Author
Settings/services/apexrest/api/v1/settings/*FlowMason_Admin
Logs/services/apexrest/api/v1/logs/*FlowMason_Admin
Analytics/services/apexrest/api/v1/analytics/*FlowMason_Admin
Admin/services/apexrest/api/v1/admin/*FlowMason_Admin
Signal delivery/services/apexrest/fm/v1/signal/*(caller of WaitForSignal)

Pipeline runs

POST /api/v1/runs/{pipelineId}. Start a pipeline

Body:

{
  "input": { "accountId": "001000000000001" },
  "executionMode": "sync"
}

200 sync response:

{
  "status": "Completed",
  "executionId": "uuid",
  "output": { "summary": "..." }
}

202 async response:

{
  "status": "Enqueued",
  "executionId": "uuid",
  "asyncJobId": "707..."
}

GET /api/v1/runs/{executionId}. Poll a tracked run

{
  "status": "Running",
  "progress": 60,
  "currentStage": "summarise",
  "output": null
}

GET /api/v1/runs/{executionId}/trace. Full ExecutionTrace

Returns the JSON shape documented in Pipeline JSON Schema § ExecutionTrace.

POST /api/v1/runs/{executionId}/cancel

Best-effort cancel; works on Running / Yielded / Paused.

AI Chat

POST /api/v1/ai/chat. Org Chat turn

{
  "message": "show me 5 hot leads",
  "conversationId": "uuid",
  "surface": "tab",
  "pipelineId": null,
  "inventoryHint": null,
  "objectScopeJson": null
}

200 response:

{
  "reply": "Here are 5 hot leads...",
  "query": "SELECT Id, Name FROM Lead WHERE Rating='Hot' LIMIT 5",
  "records": [...],
  "sobjectType": "Lead",
  "columns": [...],
  "executionId": "uuid",
  "latencyMs": 1234,
  "toolCalls": 2
}

Errors return 200 with errorCode set in body (typed). Non-200 only for auth + transport failures.

POST /api/v1/ai/chat/dml/dryrun

Two-step DML preview. Returns a confirmation key for the apply leg.

POST /api/v1/ai/chat/dml/apply

Apply with confirmationKey. Single use; expires per cache TTL.

Templates / Settings / Logs / Analytics

  • GET /api/v1/templates — list templates
  • GET /api/v1/templates/{key} — fetch latest version
  • POST /api/v1/templates — create or new version
  • GET /api/v1/settings/providers — provider list + health
  • GET /api/v1/settings/configFM_Config__mdt snapshot
  • GET /api/v1/settings/models — model registry
  • GET /api/v1/logs/runs?pipelineId=X&limit=50 — recent PipelineExecution__c
  • GET /api/v1/logs/stage/{executionId} — per-stage log array
  • GET /api/v1/analytics/summary?since=... — aggregates from FM_Run_Audit__c

Admin

GET /api/v1/admin/health

{
  "status": "healthy",
  "providers": [...],
  "cronJobs": [
    { "name": "FM Org Inventory Nightly", "state": "WAITING", "nextFireTime": "..." }
  ],
  "subscribers": [
    { "trigger": "FlowMasonRunSubscriber", "active": true }
  ],
  "cacheAvailable": true
}

Signal delivery

POST /fm/v1/signal/{signalName}. Wake a WaitForSignal stage

{
  "executionId": "uuid",
  "payload": { "approved": true, "approver": "005..." }
}

Inserts a FM_Signal__c row; the runtime resumes the paused pipeline and threads the payload into context. Lets external systems deliver approval / webhook callbacks without a Salesforce SDK.

Error envelope

{
  "errorCode": "FM_VALIDATOR_REJECTED",
  "errorMessage": "SOQL contains DML keyword",
  "executionId": "uuid"
}

Typed error codes:

CodeHTTPMeaning
FM_PERMSET_DENIED403Caller lacks required permset
FM_SURFACE_DISABLED403Surface token not in orgChatSurfacesEnabled
FM_OBJECT_NOT_ALLOWLISTED403SObject not in FM_Org_Chat_Allowlist__mdt
FM_VALIDATOR_REJECTED400FMSoqlValidator 8-gate failure
FM_RATE_LIMITED429Per-user / per-org cap
FM_PROVIDER_TIMEOUT504Provider exceeded providerTimeoutMs
FM_GOVERNOR_LIMIT503Hard governor breach
FM_PIPELINE_NOT_FOUND404No matching MDT or object row
FM_PIPELINE_VALIDATION400PipelineValidator rejected on load
FM_DML_REFUSED403One of three DML fail-closed gates blocked

Rate limits

EndpointCapConfig key
/ai/chat60 / user / minorgChatMaxTurnsPerMinutePerUser
/ai/chat/dml/apply3 / user / minorgChatDmlMaxConfirmationsPerMinute

Salesforce platform also imposes per-org REST limits — typically 1M requests / 24 h on Enterprise.

CORS

Salesforce REST API rejects cross-origin browser calls by default. For LWC / Visualforce in the same org, no CORS needed. For external SPAs, add the origin under Setup → CORS.