Oracle APEX is Oracle's low-code application development platform that runs inside the Oracle Database. When used for Oracle Fusion Cloud ERP extensions, APEX applications are deployed on Oracle Cloud Infrastructure (OCI) — typically on Autonomous Database — and communicate with Fusion Cloud through REST APIs. APEX is free with any Oracle Database license. This card covers APEX 24.2/25.1 integrated with Oracle Fusion Cloud ERP 24B/25A releases. Does NOT cover APEX extensions for Oracle E-Business Suite (EBS) on-premise or Oracle Visual Builder Cloud Service (VBCS).
| Property | Value |
|---|---|
| Vendor | Oracle |
| System | Oracle APEX 24.2 / 25.1 + Oracle Fusion Cloud ERP |
| API Surface | REST (via ORDS for APEX; Fusion REST APIs for ERP data) |
| Current APEX Version | 24.2 (GA), 25.1 (GA), 26.1 (planned 2026) |
| Editions Covered | All APEX editions (free with Oracle DB); Fusion ERP Enterprise |
| Deployment | Cloud (OCI Autonomous Database) |
| API Docs | Oracle APEX Documentation |
| Status | GA |
APEX integrates with Oracle Fusion Cloud ERP through multiple API surfaces. APEX itself exposes APIs through ORDS, while it consumes Fusion Cloud APIs as REST Data Sources.
| API Surface | Protocol | Best For | Direction | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| Fusion REST APIs | HTTPS/JSON | CRUD on Fusion business objects | APEX to Fusion | Fusion-imposed throttling | Yes | No |
| ORDS RESTful Services | HTTPS/JSON | Exposing APEX data to external consumers | APEX outbound | ORDS connection pool limits | Yes | No |
| REST Data Sources | HTTPS/JSON | Declarative Fusion API consumption in APEX pages | APEX to Fusion | Fusion-imposed | Yes | No |
| REST Enabled SQL | HTTPS/JSON | Cross-database queries via ORDS | APEX to remote Oracle DB | ORDS limits | Yes | No |
| Fusion FBDI/ERP Integration | File/REST | Bulk data loads into Fusion | APEX to Fusion | Job-based | No | Yes |
| APEX Automations | PL/SQL + REST | Scheduled background processing | Both | APEX scheduler limits | No | Yes |
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max rows per REST Data Source fetch | 500 (default, configurable) | APEX REST Data Sources | Pagination handles larger sets automatically |
| Max REST request payload | Dependent on ORDS config | ORDS-mediated requests | Default varies by ORDS deployment |
| Fusion REST API page size | 25-500 (object-dependent) | Fusion REST API | Use hasMore/offset pagination |
| APEX page process timeout | 300 seconds (default) | Page processing | Configurable via instance settings |
| Max concurrent ORDS connections | Connection pool dependent | All ORDS traffic | Typically 50-200 per pool on ADB |
| Limit Type | Value | Window | Edition Differences |
|---|---|---|---|
| Fusion REST API calls | Throttled per-tenant | Rolling | Varies by Fusion pod subscription level |
| APEX workspace storage | Tablespace-dependent | N/A | ADB: auto-scaling storage |
| ORDS request throughput | Connection pool bound | Per second | ADB-S: auto-scales with ECPU |
| APEX Automations executions | No hard daily limit | Per schedule | Limited by DB scheduler job slots |
| Limit Type | Value | Notes |
|---|---|---|
| SQL*Net client connections | Not supported | REST-only external connectivity |
| Customer-managed ORDS | Not supported | Must use Oracle-managed ORDS |
| Runtime-only environment | Not supported | Always Full Development |
| Database links | Via DBMS_CLOUD_ADMIN only | Cannot create via Object Browser |
| REST-SQL endpoint (/sql) | Disabled | Not accessible on APEX Service |
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| 3-legged OAuth 2.0 | Accessing Fusion REST APIs in user context | Access: 1h (typical) | Yes (refresh token) | Required for user-specific Fusion data |
| APEX native authentication | Internal APEX app login | Session-based (configurable) | N/A | Database-managed sessions |
| Social Sign-In (OIDC) | SSO with Oracle IDCS | Session-based | N/A | Recommended for enterprise SSO |
| APEX Web Credentials | Server-to-server Fusion API calls | Stored credential | N/A | For background automations and scheduled jobs |
START — User needs to extend Oracle Fusion Cloud ERP
|-- Does the extension need to look like a native Fusion page?
| |-- YES --> Use VBCS (not APEX) — Redwood UX, embedded navigation
| |-- NO --> Continue below
|-- What type of extension?
| |-- Data entry / approval workflows / dashboards
| | |-- Existing SQL/PL/SQL team? --> APEX (lower cost, faster dev)
| | |-- JavaScript/JET team? --> VBCS
| |-- Custom reporting / analytics
| | --> APEX (superior SQL-based reporting, Interactive Reports/Grids)
| |-- Mobile-first application
| | |-- PWA acceptable? --> APEX (built-in PWA support since 21.2)
| | |-- Native app store required? --> VBCS or custom
| |-- Legacy Oracle Forms modernization
| | --> APEX (Strangler Fig pattern, shared database)
|-- Data integration pattern with Fusion?
| |-- Real-time CRUD (< 500 records/operation)
| | --> REST Data Sources with Fusion REST APIs
| |-- Bulk data sync (> 1,000 records)
| | --> APEX Automations + Fusion FBDI (file-based import)
| |-- Event-driven (Fusion Business Events)
| | --> Fusion publishes event --> APEX REST endpoint receives
| |-- Read-only reporting
| | --> REST Data Sources with server-side pagination
|-- Authentication requirement?
| |-- User must see their own Fusion data --> 3-legged OAuth
| |-- Background sync / scheduled jobs --> Web Credentials (client credentials)
| |-- SSO with corporate IdP --> OIDC via IDCS federation
| Criterion | Oracle APEX | Oracle VBCS | Winner For ERP Extensions |
|---|---|---|---|
| Native Fusion UX | Redwood approximation (~80%) | Native Redwood (100%) | VBCS |
| Fusion navigation embedding | Separate app (link/iframe) | Embedded in Fusion menu | VBCS |
| Data-intensive apps | Excellent (SQL/PL/SQL native) | Limited (JavaScript) | APEX |
| Custom reporting | Interactive Reports, Charts, Grids | Basic components | APEX |
| Licensing cost | Free with Oracle DB license | Requires VBCS subscription | APEX |
| SQL/PL/SQL skills | Required | Not needed | Depends on team |
| JavaScript/JET skills | Optional | Required | Depends on team |
| Deployment flexibility | OCI, on-premise, any Oracle DB | OCI only | APEX |
| Identity token propagation | Manual (OAuth setup) | Automatic (same SSO context) | VBCS |
| Fusion Business Object access | REST Data Sources (manual config) | Native data connectors | VBCS |
| PWA support | Built-in (since 21.2) | Limited | APEX |
| CI/CD integration | Git export, YAML/JSON .apx format | Visual Builder Studio built-in | VBCS |
| AI features (2026) | AI Assistant, RAG with Vector Search | AI-assisted builder | APEX |
Deploy an APEX workspace on an OCI Autonomous Database instance. Choose the same OCI region as your Fusion Cloud pod to minimize latency. [src2]
# Using OCI CLI to create an Autonomous Database for APEX
oci db autonomous-database create \
--compartment-id $COMPARTMENT_OCID \
--db-name APEXERP \
--display-name "APEX ERP Extensions" \
--compute-model ECPU \
--compute-count 2 \
--data-storage-size-in-gbs 20 \
--db-workload APEX \
--is-auto-scaling-enabled true
Verify: Access the APEX instance URL and confirm the workspace login page loads.
Create an OAuth confidential application in Oracle Identity Cloud Service (IDCS) associated with your Fusion Cloud instance. Configure allowed scopes for the Fusion REST APIs you need. [src1]
IDCS Configuration:
1. Navigate to IDCS Admin Console > Applications > Add
2. Select "Confidential Application"
3. Configure:
- Name: "APEX ERP Extension"
- Allowed Grant Types: Authorization Code, Client Credentials
- Redirect URL: https://<your-apex-host>/ords/apex_authentication.callback
- Allowed Scopes: Add Fusion REST API scopes
4. Activate the application
5. Note: Client ID, Client Secret
Verify: Use the client credentials to request a token via cURL — expected: JSON with access_token.
Create a Web Credential to store the OAuth client details, then define a REST Data Source pointing to your target Fusion REST API endpoint. [src1, src7]
-- Create Web Credential in APEX (via SQL Workshop or PL/SQL)
BEGIN
APEX_CREDENTIAL.SET_PERSISTENT_CREDENTIALS(
p_credential_static_id => 'FUSION_ERP_OAUTH',
p_client_id => '<your_client_id>',
p_client_secret => '<your_client_secret>'
);
END;
/
Verify: In REST Data Source > Data Profile, click "Fetch Data" and confirm rows return from Fusion.
Create Interactive Reports, Forms, or Cards pages bound to the REST Data Source. APEX 24.2 supports declarative filtering, sorting push-down, and pagination against REST sources. [src1]
Verify: Run the page and confirm Fusion ERP data renders with proper pagination.
For creating or updating Fusion ERP records from APEX, configure POST/PATCH operations on the REST Data Source or use PL/SQL with APEX_WEB_SERVICE. [src7]
DECLARE
l_response CLOB;
l_url VARCHAR2(500) := 'https://<fusion-host>/fscmRestApi/resources/v1/invoices';
BEGIN
l_response := APEX_WEB_SERVICE.MAKE_REST_REQUEST(
p_url => l_url,
p_http_method => 'POST',
p_body => '{"InvoiceNumber":"INV-001","SupplierName":"Acme Corp","InvoiceAmount":5000}',
p_credential_static_id => 'FUSION_ERP_OAUTH'
);
IF APEX_WEB_SERVICE.G_STATUS_CODE != 201 THEN
RAISE_APPLICATION_ERROR(-20001, 'Fusion API error: ' || APEX_WEB_SERVICE.G_STATUS_CODE);
END IF;
END;
/
Verify: Check Fusion ERP UI to confirm the record was created.
Wrap all Fusion API calls with retry logic for transient failures (429 rate limiting, 503 service unavailable). [src5, src7]
PROCEDURE call_fusion_api_with_retry(
p_url IN VARCHAR2,
p_method IN VARCHAR2,
p_body IN CLOB DEFAULT NULL,
p_max_retries IN NUMBER DEFAULT 3,
p_response OUT CLOB,
p_status OUT NUMBER
) IS
l_retry_count NUMBER := 0;
l_wait_seconds NUMBER := 2;
BEGIN
LOOP
p_response := APEX_WEB_SERVICE.MAKE_REST_REQUEST(
p_url => p_url,
p_http_method => p_method,
p_body => p_body,
p_credential_static_id => 'FUSION_ERP_OAUTH'
);
p_status := APEX_WEB_SERVICE.G_STATUS_CODE;
EXIT WHEN p_status IN (200, 201, 204);
EXIT WHEN l_retry_count >= p_max_retries;
EXIT WHEN p_status NOT IN (429, 500, 503);
l_retry_count := l_retry_count + 1;
DBMS_SESSION.SLEEP(l_wait_seconds);
l_wait_seconds := l_wait_seconds * 2;
END LOOP;
END;
Verify: Send a malformed request and confirm the error is caught and logged.
-- Input: Fusion ERP REST API endpoint, OAuth credentials configured
-- Output: All purchase orders loaded into a local staging table
DECLARE
l_response CLOB;
l_url VARCHAR2(500);
l_offset NUMBER := 0;
l_has_more BOOLEAN := TRUE;
l_json JSON_OBJECT_T;
l_items JSON_ARRAY_T;
l_page_size NUMBER := 100;
BEGIN
WHILE l_has_more LOOP
l_url := 'https://<fusion>/fscmRestApi/resources/v1/purchaseOrders'
|| '?limit=' || l_page_size
|| '&offset=' || l_offset;
l_response := APEX_WEB_SERVICE.MAKE_REST_REQUEST(
p_url => l_url,
p_http_method => 'GET',
p_credential_static_id => 'FUSION_ERP_OAUTH'
);
l_json := JSON_OBJECT_T.PARSE(l_response);
l_items := l_json.get_Array('items');
FOR i IN 0 .. l_items.get_size - 1 LOOP
INSERT INTO staging_purchase_orders (
po_header_id, order_number, status, total_amount
) VALUES (
JSON_OBJECT_T(l_items.get(i)).get_Number('POHeaderId'),
JSON_OBJECT_T(l_items.get(i)).get_String('OrderNumber'),
JSON_OBJECT_T(l_items.get(i)).get_String('Status'),
JSON_OBJECT_T(l_items.get(i)).get_Number('TotalAmount')
);
END LOOP;
COMMIT;
l_has_more := l_json.get_Boolean('hasMore');
l_offset := l_offset + l_page_size;
END LOOP;
END;
/
# Input: Valid OAuth access token, Fusion REST API base URL
# Output: JSON array of invoices
# 1. Get access token
curl -s -X POST \
"https://<idcs-host>/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "<client_id>:<client_secret>" \
-d "grant_type=client_credentials&scope=<fusion_scope>"
# 2. Query Fusion ERP invoices
curl -s -X GET \
"https://<fusion-host>/fscmRestApi/resources/v1/invoices?limit=5" \
-H "Authorization: Bearer <access_token>" \
-H "Accept: application/json"
| APEX Local Field | Fusion REST API Field | Type | Transform | Gotcha |
|---|---|---|---|---|
| vendor_name (VARCHAR2) | SupplierName | String | Direct mapping | Fusion enforces lookup validation — supplier must exist |
| invoice_amount (NUMBER) | InvoiceAmount | Number | Direct mapping | Must include CurrencyCode in same payload |
| invoice_date (DATE) | InvoiceDate | String | TO_CHAR(date, 'YYYY-MM-DD') | Fusion expects ISO 8601 date strings, not Oracle DATE |
| po_number (VARCHAR2) | OrderNumber | String | Direct | Case-sensitive match in Fusion |
| line_amount (NUMBER) | InvoiceLines[].Amount | Number | JSON array nesting | Must submit as nested child array in POST payload |
| gl_account (VARCHAR2) | DistributionCombination | String | Segment concatenation | Uses segment1-segment2-...-segmentN format |
| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| 401 | Unauthorized | OAuth token expired or invalid scope | Refresh the access token; verify IDCS application scopes |
| 403 | Forbidden | Insufficient Fusion role/privilege | Assign appropriate Fusion duty role to integration user |
| 404 | Not Found | Wrong API endpoint URL or nonexistent resource | Verify endpoint path matches Fusion release version |
| 429 | Too Many Requests | Fusion API rate limit exceeded | Implement exponential backoff; reduce concurrent sessions |
| 500 | Internal Server Error | Fusion-side processing failure | Parse error response body for Fusion error detail |
| 503 | Service Unavailable | Fusion pod maintenance or overload | Retry with backoff; check Fusion Cloud Status dashboard |
Use APEX Web Credentials with built-in token management. [src1]Add explicit filter predicates to limit Fusion response size. [src7]Pin API version in URL and test in Fusion test pod before cutover. [src1]Use CLOB columns for Description, Comments fields. [src5]Batch multiple Fusion queries per page load; tune ORDS pool size. [src2]-- BAD: Every page view triggers a live Fusion REST API call
-- Consumes Fusion API quota rapidly and adds 200-500ms latency per page
SELECT * FROM apex_data_sources
WHERE rest_source = 'Fusion_Invoices'
-- No caching, no local staging
-- GOOD: APEX Automation syncs Fusion data to local table every 15 minutes
-- Page queries hit local table (sub-ms) instead of Fusion REST API
BEGIN
sync_fusion_invoices_to_local;
END;
/
-- Page query uses local cached data
SELECT * FROM local_invoices
WHERE status = 'APPROVED'
ORDER BY invoice_date DESC;
/* BAD: Extensive CSS overrides trying to match Fusion pixel-perfectly */
/* Months of effort, breaks on every APEX upgrade, never quite right */
.t-Body { font-family: "Oracle Sans" !important; }
.t-Region { border-radius: 16px !important; }
/* 500+ lines of Redwood mimicry... */
/* GOOD: Apply Redwood Theme Style (built-in since APEX 21.1) */
/* Accept that APEX apps are companion apps, not embedded Fusion pages */
/* Customize only brand colors and logo */
.custom-brand { --brand-color: #312D2A; }
-- BAD: Client secrets in APEX substitution strings or application items
-- Visible to any workspace developer, logged in debug output
:APP_FUSION_CLIENT_SECRET := 'my-secret-value-123';
-- GOOD: Store OAuth secrets in APEX Web Credentials (encrypted in metadata)
-- Reference by static ID, never exposed in page items or debug logs
BEGIN
APEX_CREDENTIAL.SET_PERSISTENT_CREDENTIALS(
p_credential_static_id => 'FUSION_ERP_OAUTH',
p_client_id => :P_CLIENT_ID,
p_client_secret => :P_CLIENT_SECRET
);
END;
/
Always include version in API URL path and test against Fusion test instance before each quarterly update. [src1]Pre-fetch LOV values from Fusion /lookups endpoint and use APEX LOV components. [src7]Isolate sensitive ERP extensions in dedicated workspaces. [src3]Always GET the current ETag before PATCH/PUT operations. [src1]Deploy on ATP/ADW if you need database links or SQL*Net connectivity. [src3]Use REST Enabled SQL for ad-hoc queries only; stage data locally for high-volume integration. [src2]# Check ORDS status and version
curl -s https://<apex-host>/ords/_/db-api/stable/metadata-catalog/ \
-H "Accept: application/json" | jq '.version'
# Test Fusion REST API connectivity
curl -s -o /dev/null -w "%{http_code}" \
"https://<fusion-host>/fscmRestApi/resources/v1/invoices?limit=1" \
-H "Authorization: Bearer <token>"
# Check APEX REST Data Source configuration (run in SQL Workshop)
SELECT service_name, base_url, auth_type, status
FROM apex_appl_web_src_modules
WHERE application_id = <your_app_id>;
# Verify APEX Web Credential exists
SELECT static_id, credential_type, valid_for_urls
FROM apex_credentials
WHERE static_id = 'FUSION_ERP_OAUTH';
# Verify APEX Automation job status
SELECT automation_name, last_run_timestamp, last_run_status, next_run_timestamp
FROM apex_appl_automations
WHERE application_id = <your_app_id>;
| APEX Version | Release Date | Status | Key ERP-Relevant Features | Notes |
|---|---|---|---|---|
| 26.1 | 2026 (planned) | Planned | AI-assisted workflows, enhanced GenDev | Preview at APEX events 2025 |
| 25.1 | 2025-04 | Current | Additional REST DS enhancements, AI Assistant GA | Recommended for new projects |
| 24.2 | 2024-10 | Supported | Flexible Remote Servers, REST sort push-down, Workflow Designer | Major release for ERP integration |
| 24.1 | 2024-04 | Supported | Workflow Designer, improved REST Data Sources | First release with declarative workflows |
| 23.2 | 2023-10 | Supported | Template Components, Working Copy | CI/CD improvements |
| 23.1 | 2023-04 | EOL Q4 2025 | PWA enhancements, Task Lists | Legacy — upgrade recommended |
Oracle supports each APEX version for a minimum of 2 years after successor release. Autonomous Database instances receive APEX upgrades on Oracle's schedule — customers cannot defer indefinitely. Applications built on supported API features generally migrate forward without breaking changes.
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Building data-intensive dashboards and reports on Fusion ERP data | Extension must appear as a native Fusion page | VBCS with Fusion Page Composer |
| Team has SQL/PL/SQL expertise and limited JavaScript skills | Team is primarily JavaScript/JET developers | VBCS |
| Budget is constrained — APEX is free with existing Oracle DB license | Organization has VBCS entitlement bundled with Fusion | VBCS (already licensed) |
| Complex multi-step approval workflows with data validation | Simple field-level customizations to existing Fusion pages | Fusion Page Composer (no code) |
| Modernizing Oracle Forms applications that coexist with Fusion | Need seamless SSO token propagation into Fusion context | VBCS (automatic identity propagation) |
| Custom data collection forms that feed into Fusion via REST | Enterprise-scale integration requiring message queuing | Oracle Integration Cloud (OIC) |
| Capability | Oracle APEX | Oracle VBCS | Oracle Page Composer | Notes |
|---|---|---|---|---|
| Fusion UX parity | ~80% (Redwood approx.) | 100% (native Redwood) | 100% (native) | VBCS wins for UX consistency |
| Fusion navigation embed | No (separate app, link) | Yes (Navigator menu) | Yes (inline) | VBCS/Composer only for embedded |
| Development model | Low-code (SQL/PL/SQL) | Low-code (JavaScript/JET) | No-code (drag-drop) | Different skill requirements |
| Data processing | Excellent (full SQL, PL/SQL) | Limited (client-side JS) | None | APEX wins for data logic |
| Reporting | Interactive Reports, Grids, Charts | Basic components | None | APEX significantly stronger |
| Licensing cost | Free with Oracle DB | Subscription required | Included with Fusion | APEX lowest cost |
| Deployment flexibility | OCI, on-premise, any Oracle DB | OCI only | Fusion only | APEX most flexible |
| CI/CD integration | Git, YAML/JSON .apx, CLI | VB Studio built-in | None | Both capable, different tooling |
| AI/ML integration (2026) | RAG, AI Vector Search, AI Assistant | AI-assisted builder | None | APEX leverages DB-native AI |
| Fusion REST API access | Manual REST Data Source setup | Native Business Object binding | N/A | VBCS significantly easier |