IFS Cloud is an enterprise ERP platform focused on asset-intensive industries (aerospace, defense, energy, manufacturing, construction). Its event architecture is built into the Oracle database layer, implementing the ECA (Event-Condition-Action) pattern directly in PL/SQL business logic. The Event Registry manages all event definitions, conditions, and action mappings. Events can trigger seven different action types including REST calls for webhook-style outbound integrations, Workflow starts via the embedded Camunda engine, and Streams notifications for in-app messaging. This card covers the event framework across all IFS Cloud editions (24R2 and 25R1). [src1, src3, src7]
| Property | Value |
|---|---|
| Vendor | IFS |
| System | IFS Cloud 24R2 / 25R1 |
| API Surface | Event Framework (ECA) + OData REST |
| Current Version | Foundation1 / 24R2 |
| Editions Covered | All editions |
| Deployment | Cloud (SaaS) / Hybrid / On-Premise |
| API Docs | IFS Events Documentation |
| Status | GA |
IFS Cloud provides multiple integration surfaces. The Event Framework is the primary mechanism for outbound, reactive integrations. [src1, src3, src6]
| API Surface | Protocol | Best For | Max Records/Request | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| Event Framework (ECA) | PL/SQL / DB triggers | Outbound notifications, webhook REST calls, workflow triggers | Per-event (single entity change) | No explicit limit (DB-bound) | Yes | No |
| OData REST API (Projections) | HTTPS/JSON (OData v4) | CRUD operations, queries, integrations | Configurable (5,000+ projections) | Fair-use / throttled | Yes | Partial (paged) |
| IFS Connect | XML/XSLT message bus | Async message routing, connector integrations | Per-message | Depends on routing config | Async | No |
| Workflows (Camunda) | REST / BPMN | Multi-step process orchestration, human tasks | N/A | N/A | Yes | N/A |
| Streams Notifications | Internal messaging | In-app user notifications | N/A | N/A | Yes | N/A |
| Application Messages | XML via connectors | B2B integrations (EDI, partner connectors) | Per-message | Connector-dependent | Async | No |
IFS Cloud does not publish explicit per-request rate limits for the event framework. Events fire synchronously within database transactions, so throughput is bounded by database capacity. [src1, src3]
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Event actions per event | No hard limit | Event Framework | Multiple actions registered per event; all execute sequentially within the transaction |
| REST Call timeout | Configurable (default varies) | REST Call event action | Outbound REST calls exceeding timeout fail silently; no retry |
| Streams message recipients | User-scoped | Streams Message action | Notifications delivered only to Foundation1 users |
| Execute Online SQL scope | Single transaction | Execute Online SQL | SQL runs within the triggering transaction — failure rolls back everything |
| Limit Type | Value | Window | Edition Differences |
|---|---|---|---|
| OData API requests | Fair-use / throttled | Per-session | Not edition-specific; IFS manages throttling at proxy layer |
| Concurrent API sessions | Tenant-dependent | Per-tenant | Controlled by IFS IAM; depends on deployment topology |
| Workflow engine capacity | Instance-dependent | Per-instance | Camunda throughput depends on infrastructure sizing |
| Application Message throughput | Connector-dependent | Per-connector | IFS Connect routing rules control message flow rates |
IFS Cloud uses OAuth 2.0 via the IFS Identity and Access Manager (IFS IAM) for API access. The event framework itself does not require separate authentication. Outbound REST Call event actions can include authentication headers. [src6]
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| OAuth 2.0 Client Credentials | Server-to-server, scheduled jobs | Configurable via IFS IAM | Yes | Recommended for integrations |
| OAuth 2.0 Authorization Code | User-context, interactive apps | Session-dependent | Yes | Requires redirect URI configuration |
| Basic Authentication | Data migration only | Session timeout | No | Explicitly not recommended for production |
| Bearer Token (REST Call action) | Outbound REST calls from events | Pre-configured | No | Static token; no auto-refresh |
| OAuth 2.0 (Workflow delegate) | Outbound REST calls from Workflows | Per-request | Yes | Supported in IFS REST Call delegate |
START -- User needs event-driven integration with IFS Cloud
|-- What's the event source?
| |-- IFS Cloud entity change (insert/update/delete)
| | |-- System-defined event exists?
| | | |-- YES --> Use system-defined event (better performance) [src1]
| | | |-- NO --> Create custom event on entity's base table [src1, src3]
| | |-- What action do you need?
| | |-- Notify external system (webhook)? --> REST Call event action [src2]
| | |-- Complex multi-step process? --> Start Workflow event action [src4, src7]
| | |-- Send email? --> E-Mail event action [src1]
| | |-- Execute database logic? --> Execute Online SQL (CAUTION) [src1]
| | |-- Notify IFS users? --> Streams Message [src1]
| | |-- Route to middleware? --> Application Message [src1]
| |-- External system pushes data TO IFS Cloud?
| |-- YES --> OData REST API (POST/PUT via projections) [src6]
| |-- Need transformation? --> IFS Connect inbound connector [src1]
|-- Timing requirement?
| |-- Real-time (<1s) --> REST Call event action [src2]
| |-- Near real-time --> Workflow orchestrates async REST calls [src4, src5]
| |-- Batch/scheduled --> OData API polling with date filter [src6]
|-- Error tolerance?
|-- Zero-loss --> Workflow with retry + IFS Connect [src4, src5]
|-- Best-effort --> REST Call event action (fire-and-forget) [src2]
| Action Type | Purpose | Execution Context | External? | Retry? | Notes |
|---|---|---|---|---|---|
| Send email notifications | Async (mail queue) | Yes (SMTP) | Mail server retry | Supports substitution fields for dynamic content | |
| Execute Online SQL | Run PL/SQL/SQL statements | Synchronous (same transaction) | No | No | CAUTION: failure rolls back triggering transaction |
| Application Message | Route to IFS Connect | Async (message queue) | Yes (via connector) | Connector-dependent | Supports XSLT transformation |
| Task | Create user assignment | Synchronous | No | N/A | Visible in Enterprise Explorer |
| Start Workflow | Trigger Camunda workflow | Async (workflow engine) | Yes (via workflow) | Workflow-defined | Primary mechanism for complex multi-step integrations |
| Streams Message | In-app notification | Async | No | N/A | Foundation1 users only |
| REST Call | Outbound HTTP request | Synchronous | Yes | No | Webhook-style; fire-and-forget |
| Field Type | Syntax | Example | Notes |
|---|---|---|---|
| New value after change | NEW:{AttributeName} | NEW:ORDER_STATUS | Available for insert and update events |
| Old value before change | OLD:{AttributeName} | OLD:ORDER_STATUS | Available for update and delete events |
| Event-specific field | &{FieldName} | &EVENT_DATETIME | Standard parameters: datetime, user, rowkey |
| Context variable | #{ContextVar} | #USER_IDENTITY | System-level: user, mail, phone |
Navigate to IFS Solution Manager > Events. Check for existing system-defined events. If none exists, create a custom event by selecting the Logical Unit, trigger type, and timing. [src1, src3]
Steps in IFS Cloud:
1. Navigate to Solution Manager > Events
2. Search for target entity (Logical Unit name)
3. If system-defined event exists: click to view (read-only except subscriptions)
4. If no system event, create Custom Event:
- Click "+" to add new event
- Select Logical Unit (e.g., CustomerOrderLine)
- Set trigger: "New" / "Modify" / "Remove"
- Set timing: "After" (post-commit, safer) or "Before" (pre-commit, can block)
- Select attributes to expose as NEW: and OLD: parameters
- Enable the event
Verify: Event appears in list with status "Enabled". For custom events, verify the database trigger was created.
Add conditions that filter when the action should execute. [src1]
Condition configuration:
1. Open event action configuration
2. Add conditions using parameter substitution:
Example: NEW:ORDER_STATUS = 'Released' AND OLD:ORDER_STATUS != 'Released'
3. Multiple conditions are AND-ed by default
4. Leave conditions empty to fire on every event occurrence
Verify: Test with matching and non-matching record modifications. Only matching records trigger the action.
Create a REST Call action to notify external systems when the event fires. [src2]
REST Call event action setup:
1. In Event Actions, click "+" to add new action
2. Set Action Type: "REST Call"
3. Configure:
- URL: https://external-system.example.com/webhook/ifs-event
- Method: POST
- Headers: Content-Type: application/json
- Body:
{
"event": "order_status_change",
"order_no": "NEW:ORDER_NO",
"old_status": "OLD:ORDER_STATUS",
"new_status": "NEW:ORDER_STATUS",
"changed_by": "#USER_IDENTITY",
"timestamp": "&EVENT_DATETIME"
}
4. Authentication: Bearer Token (if required)
5. Enable the event action
Verify: Change a matching record. Check external system's webhook endpoint logs for the incoming POST request.
For complex multi-step integrations, trigger a Camunda workflow instead of a direct REST call. [src4, src7]
Workflow event action setup:
1. In Event Actions, set Action Type: "Workflow"
2. Reference the deployed Workflow process definition key
3. Map event parameters to workflow input variables
4. Enable the event action
The workflow handles:
- Multiple outbound REST calls with retry logic
- Human approval tasks if needed
- Error handling and compensation
Verify: Trigger the event. Check IFS Workflow Monitor for a new workflow instance.
External systems can invoke IFS Workflows directly via the Camunda REST API. [src4]
# Get OAuth token from IFS IAM
TOKEN=$(curl -s -X POST \
"https://yourifs.cloud/auth/realms/ifs/protocol/openid-connect/token" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# Start a workflow instance
curl -X POST \
"https://yourifs.cloud/main/ifsapplications/projection/engine-rest/process-definition/key/MyWorkflow/start" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"withVariablesInReturn": true,
"variables": {
"orderNumber": {"value": "CO-12345", "type": "String"},
"integrationTarget": {"value": "external-erp", "type": "String"}
}
}'
Verify: Query workflow history to confirm instance completed successfully.
Use the IFS REST Call delegate within a Camunda workflow service task. [src5]
<!-- Camunda service task for REST Call delegate -->
<serviceTask id="callExternalApi" name="Call External System"
camunda:delegateExpression="${ifsHttpConnectionDelegate}">
<extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="ifsBpaHttpConnectionMethod">POST</camunda:inputParameter>
<camunda:inputParameter name="ifsBpaHttpConnectionUrl">
https://external-system.example.com/api/orders
</camunda:inputParameter>
<camunda:inputParameter name="ifsBpaHttpConnectionHeaders">
{"Content-Type": "application/json"}
</camunda:inputParameter>
<camunda:inputParameter name="ifsBpaHttpConnectionBody">
{"order_no": "${orderNumber}", "status": "${newStatus}"}
</camunda:inputParameter>
<camunda:inputParameter name="ifsBpaHttpConnectionOutputs">
{"externalId": "$.id", "confirmationCode": "$.confirmation"}
</camunda:inputParameter>
<camunda:inputParameter name="ifsBpaRestResponseCheck">true</camunda:inputParameter>
</camunda:inputOutput>
</extensionElements>
</serviceTask>
Verify: After workflow completes, check that output variables are populated in workflow history.
# Input: Incoming HTTP POST from IFS REST Call event action
# Output: Processed event data, logged and acknowledged
# pip install flask==3.x
from flask import Flask, request, jsonify
import logging, json
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route("/webhook/ifs-event", methods=["POST"])
def handle_ifs_event():
payload = request.get_json(force=True)
event_type = payload.get("event", "unknown")
logging.info(f"IFS event: {event_type} | {json.dumps(payload)}")
if event_type == "order_status_change":
order_no = payload.get("order_no")
new_status = payload.get("new_status")
# Add your business logic here
return jsonify({"status": "received"}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
// Input: IFS Cloud instance URL, OAuth credentials
// Output: Changed records since last poll timestamp
// npm install [email protected]
const axios = require("axios");
async function getIfsToken(ifsUrl, clientId, clientSecret) {
const resp = await axios.post(
`${ifsUrl}/auth/realms/ifs/protocol/openid-connect/token`,
new URLSearchParams({
grant_type: "client_credentials",
client_id: clientId,
client_secret: clientSecret,
}),
{ headers: { "Content-Type": "application/x-www-form-urlencoded" } }
);
return resp.data.access_token;
}
async function pollChangedOrders(ifsUrl, token, sinceTimestamp) {
const url = `${ifsUrl}/main/ifsapplications/projection/v1/CustomerOrderHandling.svc/CustomerOrderSet`;
const resp = await axios.get(url, {
headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
params: { $filter: `Objversion gt '${sinceTimestamp}'`, $top: 100 },
});
return resp.data.value || [];
}
# Step 1: Get OAuth token
TOKEN=$(curl -s -X POST \
"https://yourifs.cloud/auth/realms/ifs/protocol/openid-connect/token" \
-d "grant_type=client_credentials&client_id=ID&client_secret=SECRET" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# Step 2: Query OData projection
curl -s "https://yourifs.cloud/main/ifsapplications/projection/v1/CustomerOrderHandling.svc/CustomerOrderSet?\$top=3" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json"
# Step 3: List workflow process definitions
curl -s "https://yourifs.cloud/main/ifsapplications/projection/engine-rest/process-definition" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
| IFS Event Parameter | External Field | Type | Transform | Gotcha |
|---|---|---|---|---|
NEW:ORDER_NO | order_number | String | Direct | Format includes prefix (e.g., "CO-12345") |
NEW:ORDER_STATUS | status | String (enum) | Map to external codes | IFS uses internal status codes |
OLD:ORDER_STATUS | previous_status | String (enum) | Map to external codes | Only available in Modify events |
&EVENT_DATETIME | event_timestamp | DateTime | ISO 8601 conversion | Server-local time zone, not UTC |
#USER_IDENTITY | changed_by | String | Direct | IFS user ID, not display name |
#USER_MAIL_ADDRESS | user_email | String | Direct | May be empty if not configured |
&ROWKEY | record_key | String (GUID) | Direct | Enables deep linking back to IFS record |
| LOB attachments | N/A | Binary | Not available | LOBs excluded from event parameters |
| Scenario | Symptom | Cause | Resolution |
|---|---|---|---|
| Execute Online SQL failure | User's transaction rolls back with generic error | SQL syntax error or constraint violation | Wrap SQL in BEGIN...EXCEPTION...END blocks |
| REST Call timeout | Event fires but external system never receives payload | Target endpoint slow or unreachable | Implement health check; consider Workflow with retry |
| Custom event performance hit | Slow insert/update on affected table | Database trigger overhead on high-volume table | Review trigger necessity; consider async Application Message |
| OAuth token expired | REST Call returns 401 silently | Static Bearer Token in event action expired | Use Workflow with OAuth 2.0 delegate for auto-refresh |
| Workflow fails to start | Event fires but no workflow instance | Process definition key mismatch or not deployed | Verify process key in Workflow Monitor; redeploy |
| Condition evaluation error | Event action never fires | Incorrect substitution syntax or type mismatch | Test conditions with known data; verify attribute names |
Wrap all SQL in BEGIN...EXCEPTION...END blocks. Log errors to a custom error table instead of raising exceptions. [src1]Use polling with OData date filters as reconciliation fallback. For critical events, use Workflow with retry logic. [src2]Audit custom events quarterly. Disable events no longer needed. Prefer system-defined events. [src1, src3]Explicitly declare variable types in both event action mapping and workflow definition. [src4]-- BAD: runs in triggering transaction; HTTP call failure rolls back user's order
BEGIN
send_http_request('https://external.com/api', :NEW:ORDER_NO);
INSERT INTO external_db_link.orders VALUES (:NEW:ORDER_NO, :NEW:STATUS);
END;
-- GOOD: REST Call action fires within transaction but does not block on failure.
-- For guaranteed delivery, use Workflow:
Event Action Type: REST Call (or Workflow for retry)
URL: https://external.com/api/webhook
Method: POST
Body: {"order_no": "NEW:ORDER_NO", "status": "NEW:ORDER_STATUS"}
-- BAD: creates a redundant database trigger alongside existing system event
Custom Event: CustomerOrder_Modify_After
(System-defined event already exists for CustomerOrder status changes)
-- GOOD: attach action to existing system-defined event, no extra trigger overhead
Event: CustomerOrder.StatusChanged (system-defined)
Action Type: REST Call
Condition: NEW:ORDER_STATUS = 'Released'
-- BAD: no retry, no delivery confirmation, no dead letter queue
Event: InventoryTransaction.New
Action: REST Call to WMS
(If WMS is down 10 minutes, all inventory events are permanently lost)
-- GOOD: Workflow handles retry; polling catches gaps
Event: InventoryTransaction.New
Action: Start Workflow "InventorySyncWorkflow"
- Service Task: REST Call to WMS (3 retries, exponential backoff)
- Error Handler: Log to error table, send alert email
PLUS: Scheduled OData polling job every 15 minutes as reconciliation
Use Application Message (async, fires after commit) or design receiving system to handle orphan events. [src1]Keep Execute Online SQL to simple validations. Move complex logic to Workflows. [src1]Load-test custom events with production-representative data volumes. [src1, src3]Use a configuration table or IFS System Parameter for target URLs. [src2]Use "After" for notifications and integrations. Use "Before" only for validations. [src1]Monitor Camunda REST API (/engine-rest/process-instance). Alert on creation latency. [src4]# Test IFS Cloud OAuth authentication
curl -s -X POST "https://yourifs.cloud/auth/realms/ifs/protocol/openid-connect/token" \
-d "grant_type=client_credentials&client_id=CLIENT_ID&client_secret=SECRET" \
| python3 -c "import sys,json;d=json.load(sys.stdin);print('Auth OK' if 'access_token' in d else f'Error: {d}')"
# Verify OData projection accessibility
curl -s "https://yourifs.cloud/main/ifsapplications/projection/v1/CustomerOrderHandling.svc/$metadata" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/xml" | head -20
# List deployed workflow process definitions
curl -s "https://yourifs.cloud/main/ifsapplications/projection/engine-rest/process-definition" \
-H "Authorization: Bearer $TOKEN" | python3 -c "import sys,json;[print(p['key'],p['name']) for p in json.load(sys.stdin)]"
# Check workflow instance history (last 10)
curl -s "https://yourifs.cloud/main/ifsapplications/projection/engine-rest/history/process-instance?sortBy=startTime&sortOrder=desc&maxResults=10" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
# Monitor active workflow instances
curl -s "https://yourifs.cloud/main/ifsapplications/projection/engine-rest/process-instance?active=true" \
-H "Authorization: Bearer $TOKEN" | python3 -c "import sys,json;d=json.load(sys.stdin);print(f'{len(d)} active instances')"
| IFS Release | Date | Status | Event Framework Changes | Migration Notes |
|---|---|---|---|---|
| 25R1 | 2025-06 | Current | Enhanced workflow integration, improved monitoring | Workflow definitions may need redeployment |
| 24R2 | 2024-10 | Supported | REST Call improvements, OAuth 2.0 in Workflow delegate | Verify REST Call configurations after upgrade |
| 23R1 | 2023-06 | Supported | Custom command workflow triggering added | New capability; no breaking changes |
| 22R1 | 2022-06 | Legacy | Workflow (Camunda) engine integration with events | Minimum version for Workflow event actions |
| 21R2 | 2021-10 | Legacy | Streams Message event action type introduced | -- |
| Foundation1 (Apps 10) | Pre-2021 | Legacy | Original ECA framework (5 action types, no REST Call/Workflow) | REST Call and Workflow require IFS Cloud upgrade |
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Need real-time outbound notifications on entity changes | Need to poll IFS for changed records on a schedule | OData REST API with date filter polling |
| Want webhook-style integration without custom code | Need guaranteed exactly-once delivery | Message broker (IFS Connect + MQ) or middleware (MuleSoft, Boomi) |
| Triggering multi-step processes (approvals, multi-system sync) | Need simple CRUD operations on IFS data | OData REST API direct calls |
| Conditional email alerts on business entity changes | Need complex data transformation before sending | IFS Connect with XSLT transformers |
| Need to validate/block transactions before commit | Need high-volume streaming (>10K events/min) | Dedicated streaming platform (Kafka, RabbitMQ) with OData polling |