Pipeline template

Forge → Salesforce

When a machine breaches, or is forecast to, open a Salesforce Case so field service can dispatch a technician with the reading already in hand.

Setup: ~10 minutes Direct: no shim needed Auth: OAuth bearer, rotated Target: /services/data/vXX.X/sobjects/Case

Before and after

Manual

  1. The machine fails on second shift.
  2. The plant calls the service line the next morning.
  3. A rep opens a Case from a verbal description.
  4. Dispatch sends a technician without knowing the fault.
  5. The technician arrives without the right part.
  6. A second visit gets scheduled.

With Forge

  1. Forge sees the reading cross the line, or forecasts that it will.
  2. A Case opens immediately with the machine ID and the actual value.
  3. Priority is set by the rule that fired.
  4. The asset record links the Case to the physical machine.
  5. Dispatch sees the fault and the recommended action before routing.
  6. The technician arrives knowing what to bring.

Field mapping

Salesforce Case fieldSourceExample
Subjecttrigger name + machineBearing temp critical on mint_7f3a91c4
Descriptionfield, value, threshold, timestamp, recommended actionmulti-line, see payload
Priorityfixed per trigger"High"
Statusfixed"New"
Originfixed"Forge Automation"
Typefixed"Field Service"
Reasonfixed"Equipment Failure"
AssetIdyour Salesforce Asset record for the machine02i5f000000XyZaAAK
AccountIdthe customer account that owns the machine0015f00000LmNoPQAZ
Origin, Type, Reason, and Priority are picklists. A value that is not already defined in your org is rejected with INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST. Add Forge Automation to the Case Origin picklist before the first run, or use a value your org already has.
Priority is per trigger, not computed. Forge interpolates values into a fixed template and does not evaluate expressions, so create one trigger and tool per priority band rather than trying to derive priority inside the payload.

Set it up

  1. Create a Connected App

    In Salesforce: Setup → App Manager → New Connected App. Enable OAuth settings, set the callback URL to anything valid if you are using the JWT or client-credentials flow, and select the api and refresh_token scopes. Note the consumer key and secret.

    For a server-to-server integration, the client-credentials flow is the simplest. Under the Connected App's policies, set Run As to an integration user with permission to create Cases.

    curl -sS -X POST https://YOUR_DOMAIN.my.salesforce.com/services/oauth2/token \
      -d "grant_type=client_credentials" \
      -d "client_id=YOUR_CONSUMER_KEY" \
      -d "client_secret=YOUR_CONSUMER_SECRET"

    The response carries access_token and instance_url. You need both.

  2. Register Salesforce as a Forge tool

    curl -sS -X POST https://forge.foundrynet.io/v1/tools \
      -H "Authorization: Bearer $FORGE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Salesforce Case (field service, high)",
        "description": "Open a high-priority field service Case for a machine breach",
        "url": "https://YOUR_DOMAIN.my.salesforce.com/services/data/v61.0/sobjects/Case",
        "method": "POST",
        "auth_type": "bearer",
        "auth_secret": "YOUR_SALESFORCE_ACCESS_TOKEN",
        "payload_template": {
          "Subject": "{{trigger_name}} on {{machine_id}}",
          "Description": "Forge detected a machine condition requiring field service.\n\nMachine: {{machine_id}}\nOEM / model: {{oem}} {{model}}\nSite: {{site}}\nCanonical field: {{field}}\nActual value: {{value}}\nThreshold: {{threshold}}\nDetected at: {{timestamp}}\n\nRecommended action: dispatch for bearing inspection and lubrication service. Bring a replacement bearing set for this model. Confirm the reading at the controller before teardown.\n\nForge trigger: {{trigger_name}} ({{trigger_id}})",
          "Priority": "High",
          "Status": "New",
          "Origin": "Forge Automation",
          "Type": "Field Service",
          "Reason": "Equipment Failure",
          "AssetId": "YOUR_ASSET_ID",
          "AccountId": "YOUR_ACCOUNT_ID"
        }
      }'
  3. Create the automation

    In plain terms: when bearing temperature crosses 95 degrees, open a field service Case with the machine ID, the reading, and the recommended action.

    curl -sS -X POST https://forge.foundrynet.io/v1/triggers \
      -H "Authorization: Bearer $FORGE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Bearing temp critical",
        "machine_id": "YOUR_MACHINE_ID",
        "condition": { "field": "sensor_readings.bearing_temp", "op": "gt", "value": 95 },
        "actions": [ { "tool_id": "TOOL_ID_FROM_STEP_2" } ],
        "enabled": true
      }'

    To dispatch on a forecast instead of an actual, use a predicted_breach condition. That path delivers to a plain webhook_url with a fixed body and no tool auth, so it needs a small forwarding endpoint. The ServiceNow template documents that payload in full; the shim logic is identical, only the destination changes.

  4. Keep the token alive

    Salesforce access tokens expire. Forge stores the secret encrypted and cannot refresh it for you, so rotate it on a schedule with PUT /v1/tools/{id}. A daily cron is enough for most session policies.

    #!/usr/bin/env bash
    # rotate-salesforce-token.sh — run daily
    TOKEN=$(curl -sS -X POST https://YOUR_DOMAIN.my.salesforce.com/services/oauth2/token \
      -d "grant_type=client_credentials" \
      -d "client_id=$SF_CLIENT_ID" \
      -d "client_secret=$SF_CLIENT_SECRET" | python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
    
    curl -sS -X PUT "https://forge.foundrynet.io/v1/tools/$FORGE_TOOL_ID" \
      -H "Authorization: Bearer $FORGE_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"auth_secret\": \"$TOKEN\"}"
    If the token lapses, Salesforce returns 401 INVALID_SESSION_ID and Forge records it on the execution log rather than retrying indefinitely. Check /v1/triggers/{id}/executions when Cases stop appearing.

The Case Forge creates

POST /services/data/v61.0/sobjects/Case
Authorization: Bearer 00D5f000008xYzA!AQEAQ...
Content-Type: application/json
X-FoundryNet-Trigger-Id: 7b1e4c92-3d05-4a61-9f28-c4a70d1b8e33

{
  "Subject": "Bearing temp critical on mint_7f3a91c4",
  "Description": "Forge detected a machine condition requiring field service.\n\nMachine: mint_7f3a91c4\nOEM / model: Haas VF-2\nSite: Plant 3 / Cell B\nCanonical field: sensor_readings.bearing_temp\nActual value: 97.2\nThreshold: 95\nDetected at: 2026-07-28T18:04:11.882714+00:00\n\nRecommended action: dispatch for bearing inspection and lubrication service...",
  "Priority": "High",
  "Status": "New",
  "Origin": "Forge Automation",
  "Type": "Field Service",
  "Reason": "Equipment Failure",
  "AssetId": "02i5f000000XyZaAAK",
  "AccountId": "0015f00000LmNoPQAZ"
}

Salesforce responds with the new record:

{ "id": "5005f00000BqRstAAF", "success": true, "errors": [] }

Next