IFS OData API: A Developer's Survival Guide
Everything you need to work with IFS Cloud's OData API — OAuth 2.0 authentication, querying and mutating entities, calling actions, error handling, and the stateless limitations you need to plan around.
Published
IFS OData API: A Developer's Survival Guide
IFS Cloud has fundamentally changed the supported boundary for external integrations. Direct database calls and the legacy .NET Access Provider are not the pattern for a new managed-Cloud integration; projection APIs exposed through OData are now one of the main supported choices.
If you've been building IFS integrations for years, this shift can feel jarring. If you're new to IFS, OData is likely your first and only option. Either way, mastering the IFS OData API is no longer optional—it's essential.
This guide walks you through everything you need: authentication flows, query syntax, mutation patterns, action invocation, error handling, and the critical stateless limitations that will shape how you design integrations.
Part 1: Understanding OData and IFS Cloud
What Is OData?
OData (Open Data Protocol) is a standardized protocol for exposing data through RESTful APIs. It builds on HTTP and REST principles, meaning any application with basic HTTP capabilities can consume it.
Key characteristics:
- Stateless: Each request is independent. The API doesn't remember your previous calls.
- Resource-based: Data is organized as entities and collections, accessed via URIs.
- Query-driven: Complex filters, projections, and ordering are built into the query syntax.
- Standard formats: Typically JSON or XML responses.
The Shift from PL/SQL to OData
In previous IFS versions (Applications 10 and earlier), developers worked with:
- PL/SQL APIs: Direct database access with full transactional control
- BizAPIs (Activities and Services): High-level operations
- .NET Access Provider: Direct database connections for client-side code
IFS Cloud changes the supported external boundary. Customer integrations should use documented projections, IFS Connect/files/events or another supported service—not the managed database. Internally, IFS Cloud still generates and runs PL/SQL, and licensed customer source customisations can include layered PL/SQL. OData is therefore a major external API surface, not the only technology in the product.
For a new external integration against an IFS-managed Cloud environment, do not:
- Call arbitrary database PL/SQL from an external managed-Cloud integration
- Use the .NET Access Provider
- Access logical units (LUs) directly from the database
Projection REST/OData endpoints sit on top of entity/business logic. Other external integration routes remain relevant where the target capability supports them.
IFS Cloud Architecture
IFS Cloud deploys OData services behind the IFS Proxy, a gateway that:
- Validates incoming access tokens
- Routes authenticated requests to backend containers
- Ensures all API communication is stateless
This architecture means two critical things:
- OAuth 2.0/OIDC bearer tokens are the supported Cloud API pattern; do not design new integrations around Basic Authentication
- Cross-request workflow state must be designed explicitly in the client, middleware, or a server-side IFS operation
Part 2: OAuth 2.0 Authentication
IFS Identity and Access Manager (IAM)
IFS Cloud uses IFS IAM, an OAuth 2.0 authorization server that:
- Issues access tokens for API requests
- Manages user authentication via OpenID Connect
- Supports multiple OAuth 2.0 flows for different client types
- Can delegate authentication to external identity providers (Azure AD, etc.)
OAuth 2.0 Flows Supported
IFS Cloud supports multiple OAuth 2.0 flows depending on your integration scenario:
1. Authorization Code Flow (Interactive Users)
Best for: Web applications where users log in interactively.
┌─────────────────────────────────────────────────────┐
│ 1. Browser redirects to IFS IAM login page │
│ 2. User provides credentials │
│ 3. IAM returns authorization code │
│ 4. Backend exchanges code for access token │
│ 5. Token used for API requests │
└─────────────────────────────────────────────────────┘
2. Authorization Code + PKCE (Mobile/SPAs)
Best for: Native apps and single-page applications where you can't securely store secrets.
Adds a code challenge/verifier pair to prevent authorization code interception.
3. Client Credentials Flow (Service-to-Service)
Best for: Headless integrations, scheduled jobs, middleware.
Response:
Obtaining Access Tokens
Step 1: Identify Your Endpoint
Find the token endpoint in IFS's metadata document:
Use the returned token_endpoint exactly. Do not infer a fixed path; it has varied across IFS releases/identity setups:
https://yourinstance.example/<identity-path>/protocol/openid-connect/token
Step 2: Request a Token
For client credentials flow:
Step 3: Use the Token
Attach the access token to every API request using the Authorization header:
ActivityService and its payloads are illustrative throughout this guide. Substitute a projection/entity set discovered in the target tenant's API Explorer and verify its $metadata before calling it.
Important Authentication Notes
- Token Expiration: Use the returned
expires_in; do not assume one hour. Client-credentials clients normally request a new token rather than receive a refresh token. - Scopes: Request only scopes configured/documented for that IAM client.
openididentifies an OIDC request but is not a universal authorisation scope for every service client. - Service Users vs. End Users: A headless client and an interactive user can represent different principals. Grant the client only the projections and underlying business-data access its integration needs.
- No Session Switching: Unlike PL/SQL's
ALTER SESSIONcommand, you cannot impersonate another user mid-stream. Each token represents one specific user/service account.
Part 3: Querying Data with OData
OData Query Structure
Projection URLs commonly follow this shape; copy the exact base context (main, historically int, etc.), version and names from the target API Explorer:
https://ifs.example.invalid/int/ifsapplications/projection/v1/{ProjectionName}.svc/{EntitySet}{QueryOptions}
Parts breakdown:
- ProjectionName: The API endpoint (e.g.,
ActivityService) - EntitySet: The collection being queried (e.g.,
Activities) - QueryOptions: Filters, ordering, paging, etc.
Basic GET Request
Fetch all activities:
Response:
Query Options: Filtering
Use $filter to narrow results:
Common filter operators:
| Operator | Meaning | Example |
|---|---|---|
eq | equals | Status eq 'Active' |
ne | not equals | Status ne 'Inactive' |
gt | greater than | CreatedDate gt 2026-01-01T00:00:00Z |
ge | greater or equal | Amount ge 1000 |
lt | less than | Amount lt 5000 |
le | less or equal | Amount le 5000 |
and | logical AND | Status eq 'Open' and Priority eq 'High' |
startswith() | string prefix | startswith(Description, 'Contract') |
endswith() | string suffix | endswith(Description, 'Review') |
contains() | substring | contains(Description, 'urgent') |
Complex filter example:
Query Options: Projection ($select)
Fetch only specific columns to reduce payload size:
Response includes only those fields.
Query Options: Ordering ($orderby)
Sort results by one or more fields:
Use asc (default) or desc for direction. Multiple fields:
Query Options: Paging ($top, $skip)
Implement pagination for large result sets:
This returns 10 records, skipping the first 20. Combine with $orderby for predictable pagination:
IFS can enforce server-driven paging. When a response contains @odata.nextLink, follow that URL until it is absent rather than assuming $top returned the complete result. For long-running incremental extracts, use a deterministic order and a tie-breaker key so records sharing the same modification timestamp are not skipped.
Complex Query Example
Fetch the 10 most recent open activities with only essential fields:
Part 4: Creating and Modifying Data
The ActivityService payloads in this section are illustrative. Use API Explorer and $metadata for the exact projection, entity-set, key, required properties, and capabilities in your target release. An entity set may be readable without being insertable, updatable, or deletable, and lifecycle transitions should normally use the projection's declared action rather than writing a status property directly.
POST: Creating Entities
Send a JSON payload with required fields:
Response (201 Created):
PUT: Full Entity Replacement
Where the entity set declares replacement support, replace the complete writable representation. Many IFS APIs expose PATCH or actions instead, so do not assume PUT is available:
PATCH: Partial Updates
Update only specific fields:
DELETE: Removing Entities
Remove an entity:
Response: 204 No Content (success) or error status code.
Part 5: Calling Actions
OData actions allow you to invoke business logic beyond simple CRUD. Actions are custom operations tied to entities or collections.
The action names below are deliberately illustrative. Copy the exact bound/unbound action name, namespace, binding path, and parameter names from $metadata or API Explorer; these details differ between projections and releases.
Finding Available Actions
Check the OData metadata to see available actions:
Look for <Action> elements in the XML response.
Invoking an Action on an Entity
Example: Call the SendNotification action on a specific activity:
Response:
Invoking an Action on a Collection
Some actions operate at the collection level:
Part 6: The Stateless Reality and Its Implications
This is perhaps the most critical concept IFS developers must internalize: OData is stateless.
What Stateless Means
Each API request is independently authenticated and carries its own request context. The server does not preserve client-controlled transaction state between calls:
- Your previous requests
- Session variables you set
- User context from prior calls
- Transactional state
Every single request must include complete context.
The Transactional Problem
In PL/SQL, you could group multiple operations in a transaction and roll back all of them if something failed:
An individual create, update, or action request can execute atomically inside IFS. What the client cannot do is keep that database transaction open across several ordinary HTTP requests. You cannot:
- Wrap multiple API calls in a single transaction
- Automatically roll back a series of changes if the last one fails
If one business request succeeds and a later, separate request fails, the first change normally stands. Design a durable workflow with stored progress, an external deduplication/business-correlation key, safe retry rules, and business-approved reversal operations. Do not assume every IFS projection accepts a generic idempotency header.
Workaround: Compensating Transactions
Use supported business actions to reverse a completed step; deleting an order or invoice is rarely an acceptable generic compensation. This skeleton records progress before invoking a documented reversal action:
Workaround: Batch Operations
Some IFS projections support OData batch calls—multiple operations in a single HTTP request. Check the service metadata and your target release. If available:
Separate operations in a batch remain independent. OData also defines a multipart changeset for an atomic group of change operations; use it only where the IFS service declares and supports that behaviour, and test rollback on the exact release. A batch envelope alone is not an atomic transaction.
Request Context via Documented Headers
An OData client cannot set arbitrary Oracle session variables. Standard HTTP headers such as Accept-Language, and any IFS-specific headers explicitly documented for the endpoint, can carry request context. Do not invent X-IFS-* headers: unsupported headers may simply be ignored.
Part 7: Error Handling
OData uses standard HTTP status codes plus detailed error responses.
Common HTTP Status Codes
| Code | Meaning | Cause |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource successfully created |
| 204 | No Content | Successful DELETE or update with no response body |
| 400 | Bad Request | Invalid query syntax or request structure |
| 401 | Unauthorized | Missing or invalid access token |
| 403 | Forbidden | Valid token but insufficient permissions |
| 404 | Not Found | Entity or endpoint doesn't exist |
| 409 | Conflict | The service reports a resource/concurrency conflict; business validation can also be returned under another documented error status |
| 412 | Precondition Failed | ETag/concurrency precondition did not match |
| 429 | Too Many Requests | Rate limit exceeded; retry with backoff |
| 500 | Internal Server Error | Unhandled server-side exception |
| 503 | Service Unavailable | Server maintenance or overload |
Error Response Format
IFS OData errors use the standard top-level error object. Optional diagnostic fields vary by release and failure; the inspected Cloud service returned code, message, and details:
Fields:
- code: Error identifier for programmatic handling
- message: Human-readable description
- details: Optional structured diagnostics. Do not depend on it being present, and do not expect a server stack trace to be exposed.
Best Practices for Error Handling
1. Always check for errors:
2. Retry only operations that are safe to repeat:
This helper deliberately accepts only reads. A timed-out POST or action may already have completed in IFS even when the client never received the response. Retry a mutation only when the projection documents an idempotency mechanism or your workflow can prove that replay is safe.
3. Create a centralized error handler fragment:
For integrations using tools like Novacura Flow, create an error-handling fragment that checks the response status and extracts error details for logging or notifications.
Part 8: Practical Integration Patterns
Pattern 1: Simple Data Sync (Read)
Periodically fetch updated records:
The overlap intentionally returns duplicates. Deduplicate or upsert by the entity key, then store a UTC checkpoint only after the local transaction succeeds. A strict ModifiedDate gt last_timestamp filter can lose rows when several records share a timestamp or a commit becomes visible late.
Pattern 2: Create with Related Data
Create an order and its lines using the exact writable sets or, preferably, a projection action designed to validate the whole business operation. If the API exposes only separate calls, persist workflow state and use an approved cancellation action rather than assuming DELETE is a rollback:
Pattern 3: Apply a Declared Action
Fetch records, then invoke the action declared in $metadata. This is a sequence of calls, not an OData batch or an atomic transaction:
Part 9: Key Takeaways and Best Practices
Mandatory Practices
-
Use the configured OAuth 2.0/OIDC flow: New Cloud API integrations should use bearer tokens. Use client credentials only when that grant and principal have been explicitly configured for the unattended integration.
-
Renew tokens correctly: Access tokens expire. Cache and renew service tokens using the configured grant; do not assume client-credentials tokens include a refresh token.
-
Design for statelessness: Never assume the server remembers prior requests. Include full context in each call.
-
Handle errors explicitly: Don't ignore non-2xx responses. Implement retry logic for transient failures.
-
Validate projections: Before building integrations, check the IFS API Explorer to ensure endpoints exist and understand their behavior.
Performance Optimization
- Use $select to fetch only required fields
- Use $filter to reduce result sets at the API level
- Implement pagination by following
@odata.nextLink; use$toponly as a requested page size - Batch operations when possible (if supported by projection)
- Cache tokens to avoid re-authenticating on every call
Security Considerations
- Never commit tokens or secrets to version control; use environment variables
- Validate SSL certificates in production
- Use service accounts with minimal required permissions
- Monitor token usage and rotate credentials regularly
- Encrypt data in transit (always HTTPS)
Common Pitfalls to Avoid
- Assuming session state: This is the #1 mistake from PL/SQL developers
- Forgetting authorization headers: Every request needs the Bearer token
- Ignoring rate limits: Implement backoff; don't hammer the API
- Not handling 404s: Entities may not exist; gracefully handle not-found errors
- Over-fetching data: Use $select to minimize payload size
- Chaining assumptions: Don't assume a POST succeeded just because you didn't get an error immediately; verify in the response
Resources and Further Learning
- IFS Official Documentation: https://docs.ifs.com (Authentication, RESTful OData APIs, API Explorer)
- OAuth 2.0 Specification: https://tools.ietf.org/html/rfc6749
- OpenID Connect: https://openid.net/connect/
- OData v4 Standard: https://www.odata.org/
Getting Help
- IFS Community: https://community.ifs.com (ask questions, share solutions)
- Novacura Flow: Dedicated IFS OData integration tools and connectors
- Postman: Test OData endpoints interactively before writing code
- API Explorer: Built into IFS, shows available projections and OpenAPI specs
Conclusion
The OData API represents a modern, standards-based approach to IFS integration. Yes, it's different from PL/SQL. Yes, it requires rethinking how you handle transactions and state. With projection contracts validated from metadata and governed through upgrades, it can also provide a consistent, scalable integration boundary.
Master the fundamentals in this guide—OAuth 2.0, query syntax, stateless design patterns—and you'll build integrations that are robust, maintainable, and ready for whatever IFS Cloud throws at you.
The API is powerful. Use it wisely.
Need help building against the IFS OData API?
Syrett Consultancy can support API design, authentication setup, and integration patterns that work with IFS Cloud's real constraints.