IFS Cloud REST API: OData Projections, Capabilities, and Integration Guide for Aerospace, Defense, and Energy
What are the IFS REST API capabilities for aerospace, defense, and energy integrations?
TL;DR
- Bottom line: IFS Cloud exposes its business logic through ~5,800 OData v4 projections served as REST APIs. Use Premium/Integration projections for stable, documented integration endpoints; avoid building against Standard (Aurena UI) projections as they may change between releases without notice. [src1, src2]
- Key limit: Rate limits are not publicly documented — IFS uses infrastructure-level fair-use throttling. No self-service configuration; excessive requests trigger 429 responses. Plan for conservative throughput (~50-100 requests/second as safe baseline) and implement backoff. [src1, src7]
- Watch out for: Not all projections support all CRUD operations — many are read-only or lack certain entity sets. Always check the API Explorer for the specific projection's capabilities before designing your integration. [src2, src4]
- Best for: Aerospace MRO work order management, defense asset lifecycle tracking, energy plant maintenance scheduling, and field service dispatch — IFS's core vertical strengths with deep domain-specific projections. [src6, src7]
- Authentication: OAuth 2.0 only via IFS Identity and Access Manager (IFS IAM). Use Client Credentials flow for server-to-server integrations; Authorization Code flow for user-context operations. No API keys supported. [src3]
System Profile
IFS Cloud is a unified cloud ERP platform purpose-built for asset-intensive industries: aerospace and defense, energy and utilities, construction, and manufacturing. Unlike traditional ERP systems that bolt on industry modules, IFS was architecturally designed around complex asset management, MRO (maintenance, repair, and overhaul), and field service management from the ground up. The REST API is built on top of the IFS OData Provider, which exposes business entities through "projections" — groupings of entity sets, actions, and functions deployed as OData v4 services. This card covers IFS Cloud releases 24R2 and 25R1. [src1, src4, src6]
| Property | Value |
|---|---|
| Vendor | IFS |
| System | IFS Cloud 24R2 / 25R1 |
| API Surface | REST (OData v4 Projections) |
| Current API Version | Release-based (24R2, 25R1) |
| Editions Covered | Single unified platform (all modules) |
| Deployment | Cloud (SaaS) / Customer-Managed Cloud |
| API Docs | IFS Cloud API Explorer |
| Status | GA |
API Surfaces & Capabilities
| API Surface | Protocol | Best For | Max Records/Request | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| OData Projections (REST) | HTTPS/JSON (OData v4) | CRUD operations, queries, actions on business entities | Configurable via $top (server-enforced max varies) | Fair-use throttling (not published) | Yes | Partial (paged) |
| Premium APIs | HTTPS/JSON (OData v4) | Stable integration endpoints with compatibility guarantees | Same as projections | Shared with projections | Yes | Partial (paged) |
| Entity Service APIs | HTTPS/JSON (OData v4) | Simplified CRUD on core business entities (24R2+) | Same as projections | Shared with projections | Yes | Partial (paged) |
| IFS Connect (Service Bus) | SOAP/XML, REST | Event-driven outbound, message routing, transformation | N/A (message-based) | Configuration-dependent | Async | Yes (batched messages) |
| SOAP (Legacy) | SOAP/XML | Legacy integrations, BPEL workflows | N/A | Shared | Yes | No |
| File-based (EDI/Flat files) | Various | Bulk data import/export, EDI transactions | N/A | N/A | No | Yes |
Rate Limits & Quotas
Per-Request Limits
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max records per query page | Server-enforced (typically 1,000-5,000) | OData Projections | Use $top and $skip for pagination; server may cap $top lower than requested |
| Max request body size | Infrastructure-dependent (typically 10-50 MB) | REST API | Governed by IIS/reverse proxy configuration |
| Max $expand depth | 2-3 levels (projection-dependent) | OData Projections | Deep expansions degrade performance; prefer multiple targeted queries |
| Max $filter complexity | No documented limit | OData Projections | Complex filters with many OR conditions may timeout |
| OData $batch support | Supported | OData Projections | Batch multiple operations in a single HTTP request |
Rolling / Daily Limits
| Limit Type | Value | Window | Edition Differences |
|---|---|---|---|
| API request rate | Fair-use throttling (not publicly documented) | Per-session / per-tenant | No edition differences — single platform |
| Concurrent API sessions | Not publicly documented | Per-tenant | Managed by IFS IAM |
| IFS Connect message throughput | Configuration-dependent | Per-instance | Depends on message queue sizing |
| Session timeout | Configurable (default varies by flow) | Per-session | OAuth tokens have configurable expiry |
Authentication
IFS Cloud exclusively uses OAuth 2.0 via IFS Identity and Access Manager (IFS IAM). No API keys, basic authentication, or other methods are supported. [src3]
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| OAuth 2.0 Client Credentials | Server-to-server integrations, no user context | Configurable (typically 1-2h) | New token per expiry cycle | Recommended for all automated integrations; uses service account |
| OAuth 2.0 Authorization Code | User-context operations, interactive integrations | Configurable (typically 1-2h) | Yes (with offline_access scope) | User authenticates via IFS IAM login page; requires redirect URI |
| OAuth 2.0 ROPC | Legacy integrations that cannot redirect to browser | Configurable | Yes | Highly discouraged — sends credentials directly; no MFA support |
Authentication Gotchas
- Service accounts cannot use external identity providers (Azure AD, Okta) — they must be created in IFS IAM's internal user registry. [src3]
- OAuth token scope determines projection access. Missing permission sets result in 403 errors even with a valid token. [src3]
- Use the OpenID Connect discovery endpoint to find token URLs. Do not hardcode them — they vary by deployment and realm. [src3]
- IFS Cloud runs on Kubernetes — session state may not persist across pod restarts. Always validate tokens before use. [src3]
Constraints
- No publicly documented rate limits — IFS uses fair-use throttling managed at the infrastructure level. Design for conservative throughput and implement 429 retry logic from day one. [src1, src7]
- Projection stability varies by API Class — Standard projections can change between releases without compatibility guarantees. Only Premium and Integration-category projections promise backward compatibility. [src2, src4]
- Custom projections require IFS Developer Studio — not a lightweight operation. Must be deployed as part of a customization package. [src8]
- IFS Connect required for outbound events — no native webhook or platform event system comparable to Salesforce Platform Events. [src7]
- Complex business logic cannot live in OData — the API provides data access, but IFS business logic runs in the PL/SQL layer. [src5]
- Tenant isolation in multi-tenant deployments — API access is scoped to a single tenant; cross-tenant queries require separate authentication. [src3]
Integration Pattern Decision Tree
START — User needs to integrate with IFS Cloud
|-- What's the integration pattern?
| |-- Real-time (individual records, <1s)
| | |-- Data volume < 500 records/operation?
| | | |-- YES --> OData Projection REST API: direct CRUD
| | | |-- NO --> OData $batch + chunking with rate limit handling
| | |-- Need to execute business logic (release WO, approve PO)?
| | | |-- YES --> OData Actions on projection endpoints
| | | |-- NO --> Standard CRUD (GET/POST/PUT/PATCH/DELETE)
| | |-- Need real-time change notifications?
| | |-- YES --> IFS Connect outbound messages + subscriber
| | |-- NO --> Polling with $filter on OBJVERSION or timestamp
| |-- Batch/Bulk (scheduled, high volume)
| | |-- > 100,000 records/day?
| | | |-- YES --> File-based import (EDI/flat files) + IFS Connect
| | | |-- NO --> OData $batch requests with pagination
| | |-- Need delta sync?
| | |-- YES --> Filter by OBJVERSION or modification timestamp
| | |-- NO --> Full extract with $top/$skip pagination
| |-- Event-driven (outbound notifications)
| | |-- Need guaranteed delivery?
| | | |-- YES --> IFS Connect with store-and-forward + acknowledgment
| | | |-- NO --> IFS Connect fire-and-forget with retry configuration
| |-- File-based (EDI/CSV/XML)
| |-- Use IFS Connect file adapters for inbound file processing
| |-- Use data export functionality for outbound flat files
|-- Which direction?
| |-- Inbound (writing to IFS) --> POST/PUT/PATCH via OData
| |-- Outbound (reading from IFS) --> GET with $filter + pagination
| |-- Bidirectional --> Use OBJVERSION for conflict detection + IFS Connect
|-- Error tolerance?
|-- Zero-loss --> IFS Connect store-and-forward + dead letter queue
|-- Best-effort --> Direct OData calls with retry on 429/5xx
Quick Reference
| Operation | Method | Endpoint | Payload | Notes |
|---|---|---|---|---|
| List entity sets in projection | GET | /ifsapplications/projection/v1/{ProjectionName} | N/A | Returns OData service document |
| Query records | GET | /ifsapplications/projection/v1/{ProjectionName}/{EntitySet} | N/A | Use $filter, $select, $expand, $top, $skip, $orderby |
| Get single record by key | GET | /ifsapplications/projection/v1/{ProjectionName}/{EntitySet}({keys}) | N/A | Composite keys: (Key1='val1',Key2='val2') |
| Create record | POST | /ifsapplications/projection/v1/{ProjectionName}/{EntitySet} | JSON | Standard OData v4 format |
| Update record (full) | PUT | /ifsapplications/projection/v1/{ProjectionName}/{EntitySet}({keys}) | JSON | Replaces entire entity |
| Update record (partial) | PATCH | /ifsapplications/projection/v1/{ProjectionName}/{EntitySet}({keys}) | JSON | Only include changed fields |
| Delete record | DELETE | /ifsapplications/projection/v1/{ProjectionName}/{EntitySet}({keys}) | N/A | Not all entity sets support delete |
| Execute action | POST | /ifsapplications/projection/v1/{ProjectionName}/{Action} | JSON (action params) | Bound and unbound actions |
| Execute function | GET | /ifsapplications/projection/v1/{ProjectionName}/{Function}(params) | N/A | Read-only operations |
| Batch request | POST | /ifsapplications/projection/v1/{ProjectionName}/$batch | Multipart/mixed | Bundle multiple operations |
| Get API metadata | GET | /ifsapplications/projection/v1/{ProjectionName}/$metadata | N/A | Returns OData EDMX schema |
Step-by-Step Integration Guide
1. Discover available projections via API Explorer
Navigate to Solution Manager > Integration > API Explorer in IFS Cloud. Filter projections by Category = "Integration" or API Class = "Premium" to find stable integration endpoints. [src2]
Steps in IFS Cloud:
1. Navigate to Solution Manager > Integration > API Explorer
2. Click Settings icon > Column Chooser > add "API Class" column
3. Filter: Categories eq 'Integration' (for integration-specific projections)
4. OR filter: API Class eq 'Premium' (for backward-compatible APIs)
5. Select your target projection (e.g., WorkOrderHandling, PurchaseOrderHandling)
6. Click "OpenAPI v3" to download the specification
7. Note the projection name — this forms the endpoint URL
Verify: The API Explorer shows the projection with available entity sets, actions, and functions listed.
2. Configure IFS IAM service account and OAuth client
Create a service account in IFS IAM for your integration. Register an OAuth 2.0 client application with Client Credentials grant type. [src3]
Steps in IFS Cloud:
1. Navigate to IFS IAM Administration
2. Create a new Service Account (e.g., "MRO_Integration_SA")
3. Navigate to User Administration > Permission Sets
4. Create or assign a permission set that includes required projections
5. Assign the permission set to the service account
6. Navigate to IFS IAM > Clients > Create new client
7. Select grant type: "Client Credentials"
8. Copy Client ID and generate Client Secret
9. Store credentials securely (vault, environment variables)
Verify: The service account appears in IFS IAM with the correct permission sets assigned.
3. Authenticate and obtain access token
Use the OpenID Connect discovery endpoint to find the token URL, then request an access token using Client Credentials flow. [src3]
# Step 1: Discover token endpoint
DISCOVERY_URL="https://yourinstance.ifs.cloud/auth/realms/YourRealm/.well-known/openid-configuration"
TOKEN_URL=$(curl -s "$DISCOVERY_URL" | python3 -c "import sys,json;print(json.load(sys.stdin)['token_endpoint'])")
# Step 2: Request access token
curl -X POST "$TOKEN_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=openid"
Verify: The response contains an access_token field. Decode the JWT to confirm the service account identity.
4. Query records with OData filtering and pagination
Use GET with OData v4 query parameters to retrieve records. [src1, src4]
# Get first 100 active work orders
curl -X GET "https://yourinstance.ifs.cloud/ifsapplications/projection/v1/WorkOrderHandling/ActiveSeparateSet?\$filter=WoStatusDbVal eq 'RELEASED'&\$top=100&\$skip=0&\$select=WoNo,Description,WoStatusDbVal,MchCode&\$orderby=WoNo desc" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "OData-Version: 4.0"
Verify: Response is a JSON object with value array. If value length < $top, you have reached the last page.
5. Create and update records
Use POST to create new records and PATCH for partial updates. IFS uses standard OData v4 format. [src1]
# Create a new purchase order line
curl -X POST "https://yourinstance.ifs.cloud/ifsapplications/projection/v1/PurchaseOrderHandling/PurchaseOrderLineSet" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "OData-Version: 4.0" \
-d '{
"OrderNo": "PO-2026-001",
"LineNo": "1",
"PartNo": "TURBINE-BLADE-A320",
"BuyQtyDue": 25,
"WantedReceiptDate": "2026-04-15"
}'
Verify: GET the record and confirm the fields have been updated. Check the OBJVERSION field to confirm a new version was created.
6. Execute business actions
Use POST to invoke business actions defined on projections — e.g., releasing work orders, approving purchase requisitions. [src1, src4]
# Release a work order
curl -X POST "https://yourinstance.ifs.cloud/ifsapplications/projection/v1/WorkOrderHandling/ActiveSeparateSet(WoNo=12345)/Release" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "OData-Version: 4.0" \
-d '{}'
Verify: GET the entity again and confirm the status has changed (e.g., from "PLANNED" to "RELEASED").
7. Implement error handling and rate limit retries
Parse OData error responses and implement exponential backoff for rate limiting (429) and server errors (5xx). [src1, src3]
import requests, time, json
def ifs_api_request(method, url, token, data=None, max_retries=5):
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
"OData-Version": "4.0"
}
for attempt in range(max_retries):
response = requests.request(method, url, headers=headers, json=data)
if response.status_code in (200, 201, 204):
return response.json() if response.content else None
if response.status_code == 429:
retry_after = response.headers.get("Retry-After", None)
wait = int(retry_after) if retry_after else min(2 ** attempt * 2, 120)
time.sleep(wait)
continue
if response.status_code in (500, 502, 503):
time.sleep(min(2 ** attempt * 3, 120))
continue
error_body = response.json()
error_msg = error_body.get("error", {}).get("message", "Unknown")
raise Exception(f"IFS API error {response.status_code}: {error_msg}")
raise Exception("Max retries exceeded")
Verify: Test with an invalid projection name to confirm 404 error parsing returns a readable message.
Code Examples
Python: Query and paginate work orders for MRO
# Input: IFS Cloud instance URL, access token
# Output: List of all released work orders across all pages
import requests
def get_all_work_orders(instance_url, token, status="RELEASED", page_size=200):
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/json",
"OData-Version": "4.0"
}
all_orders = []
skip = 0
base_url = f"{instance_url}/ifsapplications/projection/v1/WorkOrderHandling"
while True:
url = (f"{base_url}/ActiveSeparateSet"
f"?$filter=WoStatusDbVal eq '{status}'"
f"&$top={page_size}&$skip={skip}"
f"&$select=WoNo,Description,WoStatusDbVal,MchCode"
f"&$orderby=WoNo desc")
resp = requests.get(url, headers=headers)
resp.raise_for_status()
records = resp.json().get("value", [])
if not records:
break
all_orders.extend(records)
if len(records) < page_size:
break
skip += page_size
return all_orders
JavaScript/Node.js: Create asset object with error handling
// Input: IFS Cloud instance URL, access token, asset data
// Output: Created asset record or error details
// npm install [email protected]
const axios = require("axios");
async function createAsset(instanceUrl, token, assetData) {
const url = `${instanceUrl}/ifsapplications/projection/v1/EquipmentObjectHandling/EquipmentObjectSet`;
try {
const response = await axios.post(url, assetData, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
Accept: "application/json",
"OData-Version": "4.0",
},
});
console.log("Asset created:", response.data.MchCode);
return response.data;
} catch (error) {
if (error.response?.status === 403) {
console.error("Permission denied — check service account permission sets");
} else if (error.response?.status === 429) {
console.error("Rate limited — implement exponential backoff");
}
throw error;
}
}
cURL: Quick API connectivity test
# Step 1: Get token endpoint from OpenID discovery
REALM="YourRealm"
DISCOVERY="https://yourinstance.ifs.cloud/auth/realms/$REALM/.well-known/openid-configuration"
TOKEN_URL=$(curl -s "$DISCOVERY" | python3 -c "import sys,json;print(json.load(sys.stdin)['token_endpoint'])")
# Step 2: Authenticate
TOKEN=$(curl -s -X POST "$TOKEN_URL" \
-d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=openid" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# Step 3: Query a few work orders
curl -s "https://yourinstance.ifs.cloud/ifsapplications/projection/v1/WorkOrderHandling/ActiveSeparateSet?\$top=5" \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
-H "OData-Version: 4.0" | python3 -m json.tool
Data Mapping
Field Mapping Reference
| IFS Cloud Field | API Representation | Type | Transform | Gotcha |
|---|---|---|---|---|
| MchCode (Equipment Object) | "MchCode": "PUMP-001" | String (key) | Direct | Case-sensitive in some projections |
| WoNo (Work Order Number) | "WoNo": 12345 | Integer (key) | Direct | Auto-generated on create; do not provide for new records |
| WoStatusDbVal | "WoStatusDbVal": "RELEASED" | String (enum) | Use DB value, not display | Values: PREPARE, RELEASED, STARTED, WORKDONE, REPORTED, FINISHED |
| PlannedStartDate | "PlannedStartDate": "2026-03-03T08:00:00Z" | DateTimeOffset | ISO 8601 with timezone | IFS stores in server timezone; API returns with offset |
| Contract (Site) | "Contract": "PLANT01" | String (key) | Direct | Required for most entities; determines data partition |
| OBJVERSION | "Objversion": "20260303120000" | String (timestamp) | Concurrency token | Include in PATCH/PUT for optimistic locking |
| Detail lines | Nested in $expand | Array of objects | Navigation property | Use $expand=Operations to include child records |
| Custom fields (CFV) | "Cf$_CustomField": "value" | Varies | Prefixed with Cf$_ | Custom fields from customization projects use naming convention |
Data Type Gotchas
- OBJVERSION is a concurrency token, not a timestamp — include it in update requests for optimistic locking. Conflicts return 412 Precondition Failed. [src1]
- Enum fields use DB values (e.g., "RELEASED"), not display labels (e.g., "Released"). Always use DB values in API requests. [src1, src4]
- DateTimeOffset vs Date — sending a DateTime to a Date field may cause unexpected timezone conversions. [src1]
- Composite keys require parenthesized format:
EntitySet(Key1='val1',Key2=123). String keys must be single-quoted; numeric keys are unquoted. [src1]
Error Handling & Failure Points
Common Error Codes
| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| 400 | Validation error | Missing required field, wrong data type, invalid enum | Parse OData error body for field-level details |
| 401 | Token invalid or expired | OAuth token expired, revoked, or malformed | Request new token from IFS IAM; check expiry claim |
| 403 | Insufficient permissions | Service account lacks permission set for projection | Verify permission sets in IFS IAM |
| 404 | Projection or entity not found | Misspelled projection name or wrong instance URL | Check projection name in API Explorer |
| 412 | Concurrency conflict | Another process modified the record since last read | Re-read entity for fresh OBJVERSION, then retry |
| 429 | Rate limit exceeded | Too many requests in too short a period | Exponential backoff; check Retry-After header |
| 500 | Server-side error | PL/SQL business logic exception or DB constraint | Check IFS server logs; may require support ticket |
Failure Points in Production
- Token expiry during long-running batch operations: OAuth tokens typically expire in 1-2 hours; batch jobs may outlast the token. Fix:
Check token expiry claim before each batch chunk and re-authenticate if within 5 minutes of expiry.[src3] - Projection changes after IFS Cloud upgrade: Standard (non-Premium) projections may change between releases, breaking integrations. Fix:
Always use Premium or Integration-category projections for production. Test in sandbox after each upgrade.[src2, src4] - IFS Connect message delivery failures: If a subscriber endpoint is down, messages queue without proactive alerting unless configured. Fix:
Set up monitoring on IFS Connect message queues. Implement heartbeat/health checks for subscriber endpoints.[src7] - Concurrent update conflicts on high-contention entities: Work orders in MRO are frequently updated by multiple systems, triggering 412 errors. Fix:
Implement retry-on-412 logic: re-read entity, merge changes, re-submit with fresh OBJVERSION. Use PATCH for field-level updates.[src1] - Permission set gaps discovered late: Service accounts configured with minimal permissions cause 403 errors when new projections are needed. Fix:
Maintain documented permission matrix. Test all API operations in staging with production service account's exact permission set.[src3]
Anti-Patterns
Wrong: Building against Standard (Aurena UI) projections for integration
// BAD — Standard projections are designed for the Aurena UI and may change
// between IFS Cloud releases without compatibility guarantees.
// Endpoint: /ifsapplications/projection/v1/SomeAurenaPageHandling/EntitySet
Correct: Use Premium or Integration-category projections
// GOOD — Premium APIs have compatibility guarantees and comprehensive documentation.
// Filter by Categories eq 'Integration' or API Class eq 'Premium' in API Explorer.
// Endpoint: /ifsapplications/projection/v1/PremiumIntegrationProjection/EntitySet
Wrong: Hardcoding the token endpoint URL
# BAD — token endpoint varies by deployment, realm, and IAM configuration
token_url = "https://myinstance.ifs.cloud/auth/realms/default/protocol/openid-connect/token"
Correct: Use OpenID Connect discovery to find the token endpoint
# GOOD — dynamically discover token endpoint from well-known configuration
import requests
discovery_url = f"{instance_url}/auth/realms/{realm}/.well-known/openid-configuration"
config = requests.get(discovery_url).json()
token_url = config["token_endpoint"]
Wrong: Ignoring OBJVERSION for updates (risking silent data overwrites)
# BAD — updating without OBJVERSION skips optimistic concurrency check
requests.patch(
f"{url}/WorkOrderHandling/ActiveSeparateSet(WoNo=12345)",
json={"Description": "Updated description"},
headers=headers
)
Correct: Include OBJVERSION for optimistic concurrency control
# GOOD — include OBJVERSION to detect concurrent modifications
record = requests.get(
f"{url}/WorkOrderHandling/ActiveSeparateSet(WoNo=12345)",
headers=headers
).json()
requests.patch(
f"{url}/WorkOrderHandling/ActiveSeparateSet(WoNo=12345)",
json={"Description": "Updated description"},
headers={**headers, "If-Match": record.get("@odata.etag", "*")}
)
Common Pitfalls
- Assuming all projections support write operations: Many projections are read-only; attempting POST/PUT/PATCH returns 405. Fix:
Check the projection's $metadata or API Explorer for supported operations.[src2, src4] - Not using $select to limit response payload: Projections can return 50+ fields per entity, wasting bandwidth. Fix:
Always use $select to request only the fields you need — reduces response size by 80-90%.[src1] - Treating IFS OData as fully OData v4 compliant: Not all OData features are supported on every projection. Fix:
Test each OData feature against your specific projection. Consult $metadata for supported capabilities.[src4, src5] - Forgetting company/site (Contract) context: Most entities are partitioned by company and site. Fix:
Always include Contract in $filter or ensure the service account's permission set restricts to correct company/site.[src1] - Not handling pagination termination correctly: IFS does not always include @odata.nextLink. Fix:
Check if returned record count equals $top. If less, you have reached the last page.[src1] - Using ROPC flow in production: ROPC does not support MFA and sends credentials directly. Fix:
Use Client Credentials for service accounts or Authorization Code for user-context operations.[src3]
Diagnostic Commands
# Discover OpenID Connect configuration (find token endpoint)
curl -s "https://yourinstance.ifs.cloud/auth/realms/YourRealm/.well-known/openid-configuration" | python3 -m json.tool
# Test authentication (obtain token)
curl -s -X POST "$TOKEN_URL" \
-d "grant_type=client_credentials&client_id=CLIENT_ID&client_secret=SECRET&scope=openid" \
| python3 -c "import sys,json;d=json.load(sys.stdin);print('Token OK' if 'access_token' in d else f'Error: {d}')"
# Verify projection accessibility (get metadata)
curl -s "https://yourinstance.ifs.cloud/ifsapplications/projection/v1/WorkOrderHandling/\$metadata" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/xml" | head -30
# Test a basic query (first 5 work orders)
curl -s "https://yourinstance.ifs.cloud/ifsapplications/projection/v1/WorkOrderHandling/ActiveSeparateSet?\$top=5" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "OData-Version: 4.0" | python3 -m json.tool
Version History & Compatibility
| IFS Cloud Release | Release Date | Status | Key API Changes | Migration Notes |
|---|---|---|---|---|
| 25R1 | 2025-05 | Current | API Explorer enhancements; expanded Premium API catalog; Depot Repair APIs | New projections added; existing projections stable |
| 24R2 | 2024-11 | Supported | Entity Service APIs introduced; enhanced API documentation | New integration surface option; projections unchanged |
| 24R1 | 2024-05 | Supported | Premium API class introduced; expanded API Explorer filtering | Filter by API Class to find stable endpoints |
| 23R2 | 2023-11 | Supported | OData v4 improvements; additional MRO and FSM projections | Standard projection catalog expanded |
| 23R1 | 2023-05 | End of Support | Foundation for current OData provider; projection framework matured | Minimum version for modern integration patterns |
| 22R2 | 2022-11 | EOL | Aurena-based API Explorer first introduced | Upgrade required; projections may differ significantly |
When to Use / When Not to Use
| Use When | Don't Use When | Use Instead |
|---|---|---|
| CRUD operations on IFS business entities (work orders, assets, purchase orders) | High-volume event streaming (>1,000 events/second) | IFS Connect for event-driven patterns |
| Querying MRO, asset management, or field service data in real-time | Bulk data migration of >100K records | File-based import via IFS Connect file adapters |
| Building integrations with stable, documented Premium endpoints | Need direct database access or custom SQL queries | N/A — never bypass the API layer in IFS Cloud |
| Aerospace/defense MRO work order automation | Simple reporting or BI dashboards | IFS Lobby/dashboard APIs or BI connector tools |
| Server-to-server integration requiring OAuth 2.0 authentication | Legacy SOAP-based integrations | IFS Connect SOAP endpoints (maintained for compatibility) |
Important Caveats
- IFS does not publicly document specific API rate limits or quota numbers. Design your integration with conservative throughput assumptions and robust 429 retry logic. [src1, src7]
- The distinction between Premium/Integration projections and Standard (Aurena) projections is critical for production stability. Standard projections are the majority of the ~5,800 available, but they lack backward compatibility guarantees. [src2, src4]
- IFS Cloud is a single unified platform without separate editions. API capabilities are the same for all customers; functionality differences come from module licensing, not API tiers. [src6]
- IFS's strength in aerospace, defense, and energy means the deepest projections are in MRO, asset management, and field service management. For these domains, IFS provides richer API surfaces than competing general-purpose ERPs. [src6, src7]
- Custom projections created via IFS Developer Studio are deployment-specific. They must be included in customization packages for migration between environments. [src8]