This card covers Oracle Fusion Cloud ERP (also marketed as Oracle Cloud ERP, part of Oracle Fusion Cloud Applications Suite) across releases 24B and 25A. The rate limits documented here apply to all SaaS-hosted Oracle Fusion Cloud ERP instances including Financials, Procurement, Project Management, and Supply Chain modules. On-premise Oracle E-Business Suite has entirely different limits and is not covered.
| Property | Value |
|---|---|
| Vendor | Oracle |
| System | Oracle Fusion Cloud ERP (Release 24B / 25A) |
| API Surface | REST, SOAP, FBDI, BIP, ESS |
| Current API Version | Release 25A (quarterly release cycle) |
| Editions Covered | All SaaS editions |
| Deployment | Cloud (Oracle-managed SaaS) |
| API Docs | Oracle Fusion Cloud REST API Documentation |
| Status | GA |
Oracle Fusion Cloud ERP exposes multiple integration surfaces, each with distinct rate limits and optimal use cases. Choosing the wrong surface is the most common integration design mistake.
| API Surface | Protocol | Best For | Max Records/Request | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| REST API | HTTPS/JSON | Individual record CRUD, queries <500 records | 499 (GET), 500 (POST) | Identity domain tier | Yes | No |
| SOAP Web Services | HTTPS/XML | Legacy integrations, metadata operations | Varies by service | Shared with REST | Yes | No |
| FBDI | CSV via UCM | Bulk data loads >500 records, migrations | 250 MB / 500K records per file | ESS queue-based | No | Yes |
| BIP Reports | SOAP/REST | Data extraction, report generation | N/A (report-based) | ESS queue-based | No | Partial |
| ESS (Enterprise Scheduler) | REST/UI | Scheduled batch processes, import jobs | N/A (job-based) | Thread pool limited | No | Yes |
| Business Events | REST/Webhook | Event-driven outbound notifications | N/A (event-based) | Publisher throughput | Yes | N/A |
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max records per GET query | 499 | REST API | Use offset + limit parameters for pagination; hasMore attribute indicates remaining records |
| Max records per POST | 500 | REST API | Split larger payloads; use FBDI for bulk operations |
| Max request body size | 1 MB | REST API payload | Applies to single request body; attachments handled separately via UCM |
| Max bulk operation items | 50 | REST API bulk/batch | Per-call limit for composite operations |
| Max FBDI file size | 250 MB | FBDI upload to UCM | Split files exceeding this limit before upload |
| UCM upload timeout | 300 seconds | File transfer to UCM | Timeout applies to the upload operation; large files over slow connections will fail |
| Max records per FBDI file (low-volume) | 50,000 | Low-volume import mode | Per-file limit; use high-volume mode for more |
| Max records per FBDI file (high-volume) | 500,000 | High-volume import mode | Per-file limit; split larger datasets across files |
Oracle Fusion Cloud ERP rate limits are enforced at the identity domain level, not per-application. All REST and SOAP calls from all integrations targeting the same Fusion environment share a single rate limit pool.
| Limit Type | Value | Window | Tier Differences |
|---|---|---|---|
| Authentication requests | 150–4,500 req/min | Per minute | Free: 150, Oracle Apps: 1,000, Premium: 4,500 |
| Token management requests | 150–5,000 req/min | Per minute | Free: 150, Oracle Apps: 1,500, Premium: 5,000 |
| Other API requests | 150–5,000 req/min | Per minute | Free: 150, Oracle Apps: 1,500, Premium: 5,000 |
| Bulk API requests | 200+ req/min | Per minute | Free: 200; higher tiers scale accordingly |
| Max CSV files per import job | 20 | Per job | REST service importActivities limit |
| Max parallel import batches | 10 | Concurrent | Recommended maximum to avoid performance degradation |
| Max records per import submission | 10,000,000 | Per submission | 10 jobs × 20 files × 50K records theoretical max |
ESS jobs run server-side and are controlled by thread pools and work assignments rather than traditional API rate limits. These limits determine how many scheduled processes can run concurrently.
| Limit Type | Default Value | Notes |
|---|---|---|
| Synchronous Java job threads | 5–25 per JMS Processor | Configurable; determines max concurrent RUNNING synchronous jobs |
| Default threads per JMS Processor | 5 | Can be increased to 15+ via Scheduler Configuration, but Oracle-managed in SaaS |
| Recommended jobs per job set | 15–20 | Oracle recommends limiting for troubleshooting simplicity |
| Asynchronous job concurrency | Work-assignment defined | Controlled via workshifts and work assignments |
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| OAuth 2.0 JWT Assertion | Server-to-server integrations | Configurable (default ~1h) | New JWT per request | Recommended for unattended integrations |
| SAML 2.0 Federation | SSO-based user-context operations | Session-based | Via IdP | Requires SAML IdP configuration |
| Basic Auth (Username/Password) | Development, testing, simple scripts | Session timeout | No | Not recommended for production; no MFA support |
| OAuth 2.0 Authorization Code | User-delegated access | Access: ~1h, Refresh: long-lived | Yes | For applications acting on behalf of a user |
START - Need to integrate with Oracle Fusion Cloud ERP
|-- What's the integration pattern?
| |-- Real-time (individual records, <1s)
| | |-- Data volume < 500 records/operation?
| | | |-- YES -> REST API (JSON, straightforward CRUD)
| | | +-- NO -> NOT supported real-time; switch to batch/FBDI
| | +-- Need event notifications?
| | |-- YES -> Business Events (outbound) + REST callback
| | +-- NO -> REST API polling with hasMore pagination
| |-- Batch/Bulk (scheduled, high volume)
| | |-- Data volume < 500 records?
| | | |-- YES -> REST API POST (simpler, no file overhead)
| | | +-- NO (go down)
| | |-- Data volume < 50,000 records?
| | | |-- YES -> FBDI low-volume mode (single file)
| | | +-- NO (go down)
| | |-- Data volume < 500,000 records?
| | | |-- YES -> FBDI high-volume mode (single file)
| | | +-- NO -> FBDI with file splitting (max 20 files/job, 10 parallel jobs)
| | +-- Need data extraction (outbound)?
| | |-- Small dataset -> REST API with pagination
| | +-- Large dataset -> BIP report extraction (BI Publisher)
| |-- Event-driven
| | |-- Oracle publishes events?
| | | |-- YES -> Business Events subscription
| | | +-- NO -> BIP report polling or REST polling (scheduled)
| | +-- Guaranteed delivery needed?
| | |-- YES -> Middleware (OIC) with error handling + retry
| | +-- NO -> Direct REST webhook receiver
| +-- File-based (CSV/XML)
| +-- FBDI (standard Oracle pattern) -> Upload CSV to UCM -> Submit ESS import job
|-- Which direction?
| |-- Inbound (writing to ERP) -> REST (<500 records) or FBDI (>500 records)
| |-- Outbound (reading from ERP) -> REST API (small) or BIP extraction (large)
| +-- Bidirectional -> Design conflict resolution FIRST; use REST for real-time sync
+-- Error tolerance?
|-- Zero-loss required -> Middleware (OIC/MuleSoft) + dead letter queue + FBDI error callbacks
+-- Best-effort acceptable -> Direct REST with exponential backoff retry
| Operation | API Surface | Method / Approach | Max Records | Timeout | Rate Limited By |
|---|---|---|---|---|---|
| Query records | REST | GET with offset/limit | 499 per page | Standard HTTP | Identity domain tier |
| Create single record | REST | POST | 1 | Standard HTTP | Identity domain tier |
| Create batch (small) | REST | POST with payload | 500 | Standard HTTP | Identity domain tier |
| Bulk import (inbound) | FBDI | CSV upload to UCM + ESS job | 500K per file | 300s upload + ESS queue | ESS thread pool |
| Bulk extract (outbound) | BIP | Report execution via ESS | Report-dependent | ESS queue | ESS thread pool |
| Schedule process | ESS | REST /scheduledProcesses endpoint | N/A | Job-dependent | Thread pool (5-25 threads) |
| Upload file | UCM | ERP Integration web service | 250 MB max | 300 seconds | File server concurrency |
| Real-time event | Business Events | Event subscription | N/A | Event-driven | Publisher throughput |
| SOAP operation | SOAP WS | Standard SOAP envelope | Service-dependent | Standard HTTP | Shared identity domain pool |
| Composite operation | REST | Batch endpoint | 50 items | Standard HTTP | Identity domain tier |
Obtain an OAuth 2.0 access token using JWT assertion for server-to-server integration. [src3]
# Exchange JWT for access token
curl -X POST "https://{your-idcs-domain}/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion={your-jwt-assertion}" \
-d "scope=urn:opc:idm:__myscopes__"
Verify: Response contains access_token field with token_type: "Bearer".
Oracle REST API returns a maximum of 499 records per GET request. Use the offset and limit parameters to paginate. [src3]
# First page
curl -X GET "https://{host}/fscmRestApi/resources/v1/invoices?limit=499&offset=0" \
-H "Authorization: Bearer {access_token}"
# Check response for hasMore: true, then increment offset
curl -X GET "https://{host}/fscmRestApi/resources/v1/invoices?limit=499&offset=499" \
-H "Authorization: Bearer {access_token}"
Verify: Response JSON contains hasMore: false when all records retrieved.
For bulk loads exceeding 500 records, upload a CSV file to UCM via the ERP Integration web service. [src4]
curl -X POST "https://{host}/fscmRestApi/resources/v1/erpintegrations" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"OperationName": "uploadFileToUCM",
"DocumentContent": "{base64-encoded-zip-file}",
"DocumentAccount": "fin$/journal$/import$",
"ContentType": "zip",
"FileName": "JournalImport.zip"
}'
Verify: Response returns DocumentId confirming successful upload.
After uploading the FBDI file, submit an ESS scheduled process to execute the import. [src7]
# Submit import job
curl -X POST "https://{host}/fscmRestApi/resources/v1/erpintegrations" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"OperationName": "submitESSJobRequest",
"JobPackageName": "/oracle/apps/ess/financials/generalLedger/programs/",
"JobDefName": "JournalImportLauncher",
"ESSParameters": "300000004976094,1,#NULL"
}'
# Monitor job status
curl -X GET "https://{host}/fscmRestApi/resources/v1/erpintegrations?finder=ESSJobStatusRF;requestId={job_id}" \
-H "Authorization: Bearer {access_token}"
Verify: Response RequestStatus transitions from RUNNING to SUCCEEDED.
When you hit the identity domain rate limit, Oracle returns HTTP 429. Implement exponential backoff starting at 2 seconds. [src1, src5]
import time
import requests
def call_oracle_api(url, headers, max_retries=5):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
wait = min(2 ** attempt, 60) # max 60s
time.sleep(wait)
continue
elif response.status_code == 503:
wait = min(2 ** (attempt + 1), 120)
time.sleep(wait)
continue
return response
raise Exception("Max retries exceeded for Oracle API")
Verify: Function returns valid response without 429 errors after retry sequence.
# Input: Oracle Fusion REST API endpoint, OAuth token
# Output: Complete list of all matching records across all pages
import requests
import time
def extract_all_records(base_url, endpoint, token, query_params=None):
headers = {"Authorization": f"Bearer {token}",
"Content-Type": "application/json"}
all_records = []
offset = 0
limit = 499 # Oracle max per page
has_more = True
while has_more:
url = f"{base_url}/fscmRestApi/resources/v1/{endpoint}"
params = {"offset": offset, "limit": limit}
if query_params:
params.update(query_params)
for attempt in range(5):
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 429:
time.sleep(min(2 ** attempt, 60))
continue
resp.raise_for_status()
break
data = resp.json()
items = data.get("items", [])
all_records.extend(items)
has_more = data.get("hasMore", False)
offset += limit
return all_records
// Input: Base64-encoded zip file, Oracle REST endpoint, OAuth token
// Output: UCM Document ID confirming successful upload
const axios = require('axios'); // v1.6+
async function uploadFBDI(host, token, fileContent, fileName, docAccount) {
const url = `${host}/fscmRestApi/resources/v1/erpintegrations`;
const payload = {
OperationName: 'uploadFileToUCM',
DocumentContent: fileContent, // base64 encoded
DocumentAccount: docAccount,
ContentType: 'zip',
FileName: fileName
};
for (let attempt = 0; attempt < 5; attempt++) {
try {
const resp = await axios.post(url, payload, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
timeout: 300000 // 300s to match UCM timeout
});
return resp.data.DocumentId;
} catch (err) {
if (err.response?.status === 429 || err.response?.status === 503) {
await new Promise(r => setTimeout(r, Math.min(2 ** attempt * 1000, 60000)));
continue;
}
throw err;
}
}
throw new Error('FBDI upload failed after 5 retries');
}
# Input: Oracle host, Bearer token, ESS job request ID
# Output: Job status (RUNNING, SUCCEEDED, ERROR, WARNING)
curl -s -X GET \
"https://{host}/fscmRestApi/resources/v1/erpintegrations?finder=ESSJobStatusRF;requestId={REQUEST_ID}" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" | jq '.items[0].RequestStatus'
| Identity Domain Type | Auth Requests/min | Token Mgmt/min | Other API/min | Bulk/min | Typical Use |
|---|---|---|---|---|---|
| Free Tier | 150 | 150 | 150 | 200 | Development, sandbox |
| Oracle Apps | 1,000 | 1,500 | 1,500 | Scaled | Standard production |
| Premium | 4,500 | 5,000 | 5,000 | Scaled | High-volume enterprise |
| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| 429 | Too Many Requests | Identity domain rate limit exceeded | Exponential backoff: wait 2^n seconds, starting at 2s, max 60s, max 5 retries |
| 503 | Service Unavailable | Oracle Fusion under maintenance or overloaded | Retry with longer backoff (start at 4s, max 120s); check Oracle Cloud Status page |
| 401 | Unauthorized | Token expired or invalid | Refresh OAuth token; check if integration user is locked or password expired |
| 400 | Bad Request | Invalid payload format or field values | Validate payload against REST API describe endpoint; check required fields |
| 404 | Not Found | Resource or endpoint does not exist | Verify endpoint URL matches your Fusion release version; check object accessibility |
| 500 | Internal Server Error | Server-side Fusion error | Log full response; retry once; if persistent, file Oracle SR with correlation ID |
| JBO-25013 | Too Many Objects | Excessive child records in single request | Reduce batch size; split parent-child creates across multiple requests |
Always poll ESS job status after submission; parse the job output/log file for detailed error rows. [src4, src6]Cache tokens centrally with TTL slightly shorter than expiration; use a single token service for all integrations. [src1, src5]Keep FBDI files under 150 MB; compress CSV into zip before upload; split large imports into multiple files. [src4]Schedule BIP extractions in off-peak workshifts; monitor thread utilization via Scheduled Processes UI. [src7]Limit parallel imports to 10 maximum; serialize imports for the same object; purge interface tables between runs. [src4]Audit all integrations sharing the identity domain; migrate SOAP to REST where possible; implement coordinated rate limiting across all clients. [src1]# BAD - Hammering API without backoff, will hit 429 within seconds
while True:
response = requests.get(f"{base}/invoices?offset={offset}")
process(response.json())
offset += 499
# GOOD - Respects rate limits, handles 429, uses appropriate delays
import time
offset = 0
while True:
resp = requests.get(f"{base}/invoices?offset={offset}&limit=499",
headers=headers)
if resp.status_code == 429:
time.sleep(float(resp.headers.get('Retry-After', 5)))
continue
data = resp.json()
process(data['items'])
if not data.get('hasMore'):
break
offset += 499
time.sleep(0.5) # voluntary throttle: ~120 req/min
// BAD - REST POST limited to 500 records; 10,000 records = 20 serial calls
for (const batch of chunk(records, 500)) {
await axios.post(`${base}/journals`, { items: batch });
}
// GOOD - FBDI handles 500K records per file; single upload + ESS job
const csv = generateCSV(records); // all 10,000 records
const zip = await compressToZip(csv);
const base64 = zip.toString('base64');
const docId = await uploadFBDI(host, token, base64, 'import.zip', account);
const jobId = await submitESSJob(host, token, docId);
await pollJobStatus(host, token, jobId);
BAD - Rate limits are per identity domain, NOT per user
Creating 5 integration users does not give you 5x the rate limit.
All users in the same identity domain share the same pool.
GOOD - Maximize value per request:
1. Use query filters (q parameter) to reduce result set size
2. Use fields parameter to request only needed attributes
3. Cache reference data (LOVs, lookups) locally
4. Batch related operations into composite requests (max 50)
5. Schedule bulk operations via FBDI during off-peak hours
Consult OCI service limits documentation separately from Fusion Cloud REST API documentation. [src1]Implement centralized API call logging with timestamps; aggregate across all integration clients; set alerts at 70% of rate limit threshold. [src1, src5]Schedule FBDI imports outside business hours; coordinate with Oracle maintenance windows. [src4, src7]Run purge jobs after every import cycle; automate purge as the final step in every FBDI integration flow. [src6]Load-test in sandbox but validate rate limit assumptions in production with controlled rollout. [src1]Use version-agnostic base URLs where available; pin to a specific release version and update during quarterly testing cycles. [src3]# Test authentication (obtain token)
curl -s -X POST "https://{idcs-domain}/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__" \
-u "{client_id}:{client_secret}" | jq '.access_token'
# Test REST API connectivity
curl -s -o /dev/null -w "%{http_code}" -X GET \
"https://{host}/fscmRestApi/resources/v1/" \
-H "Authorization: Bearer {token}"
# Check ESS scheduled process status
curl -s -X GET \
"https://{host}/fscmRestApi/resources/v1/erpintegrations?finder=ESSJobStatusRF;requestId={JOB_ID}" \
-H "Authorization: Bearer {token}" | jq '.items[0] | {Status: .RequestStatus, StartTime: .StartTime, EndTime: .EndTime}'
# List recent ESS jobs (last 20)
curl -s -X GET \
"https://{host}/fscmRestApi/resources/v1/scheduledProcesses?limit=20&orderBy=SubmittedDT:desc" \
-H "Authorization: Bearer {token}" | jq '.items[] | {id: .RequestId, name: .Name, status: .Status}'
# Verify object accessibility (describe endpoint)
curl -s -X GET \
"https://{host}/fscmRestApi/resources/v1/{resource}/describe" \
-H "Authorization: Bearer {token}" | jq '.Resources[0].attributes | length'
| Release | Date | Status | Key Changes | Notes |
|---|---|---|---|---|
| 25A | 2025-01 | Current | Enhanced Scheduler REST API endpoints | Quarterly update |
| 24D | 2024-10 | Supported | Business Events improvements | — |
| 24C | 2024-07 | Supported | REST API performance improvements | — |
| 24B | 2024-04 | Supported | Revised identity domain rate limit tiers | Rate limit tier structure updated |
| 24A | 2024-01 | Supported | FBDI high-volume mode expanded | New high-volume import objects |
Oracle Fusion Cloud ERP follows a quarterly release cadence with no formal API version numbering. REST endpoints are release-specific; breaking changes are documented in Release Readiness guides published before each quarterly update. Oracle generally provides one quarter advance notice before removing or changing REST API behavior.
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Designing a new Oracle ERP Cloud integration and need to understand all rate limit boundaries | Working with Oracle Cloud Infrastructure (OCI) platform APIs | OCI service limits documentation |
| Troubleshooting 429 errors or ESS job queue bottlenecks | Integrating with Oracle NetSuite (different API surface entirely) | NetSuite SuiteTalk/REST API limits documentation |
| Planning FBDI import strategy for high-volume data loads | Need Oracle Integration Cloud (OIC) message pack limits | OIC service limits documentation |
| Evaluating whether REST API or FBDI is appropriate for your data volume | Working with on-premise Oracle E-Business Suite | E-Business Suite integration guide |