Oracle Procurement Cloud REST API Capabilities

Type: ERP Integration System: Oracle Fusion Cloud Procurement (26A) Confidence: 0.87 Sources: 7 Verified: 2026-03-09 Freshness: 2026-03-09

TL;DR

System Profile

Oracle Fusion Cloud Procurement is Oracle's SaaS procurement platform, part of the broader Oracle Fusion Cloud Applications suite. The REST API (version 11.13.18.05) provides programmatic access to procurement objects including purchase requisitions, draft purchase orders, suppliers, supplier negotiations, approved supplier lists, compliance checklists, and catalog management. The API version string remains constant across quarterly releases, but endpoint behavior changes with each release. This card covers Release 26A (January 2026). Receipts and receiving are managed by the SCM Cloud REST API, not the Procurement API. [src1]

PropertyValue
VendorOracle
SystemOracle Fusion Cloud Procurement 26A
API SurfaceREST (HTTPS/JSON)
Current API Version11.13.18.05
Editions CoveredEnterprise (SaaS)
DeploymentCloud
API DocsOracle Procurement 26A REST API
StatusGA

API Surfaces & Capabilities

API SurfaceProtocolBest ForMax Records/RequestRate LimitReal-time?Bulk?
REST APIHTTPS/JSONIndividual CRUD, requisition submission, PO lifecycle actionsPaginated (default 25, max 500)Per-tenant throttlingYesNo
SOAP Web ServicesHTTPS/XMLLegacy integrations, metadata operationsVaries by serviceShared with RESTYesNo
FBDICSV in ZIP via UCMData migration, bulk supplier/PO import100,000 per import5 concurrent importsNoYes
Business Events (OIC)Async/webhook via OICEvent-driven PO status changesN/A (event-based)Subscription-basedYesN/A
ERP Integration ServiceSOAP/RESTOrchestrating FBDI imports with callbacksN/AN/ANoYes
BI Publisher / OTBIHTTPS/SOAPReporting and data extractionReport-dependentFair useNoNo

Rate Limits & Quotas

Per-Request Limits

Limit TypeValueApplies ToNotes
Default page size25 recordsREST API GET requestsConfigurable via limit query parameter
Max page size500 recordsREST API GET requestsUse offset for pagination beyond 500
Max FBDI ZIP file size250 MBFile-Based Data ImportIndividual CSV files within ZIP can be up to 1 GB
Max records per FBDI import100,000File-Based Data ImportSplit larger datasets across multiple import jobs
Max attachment size2 GBREST API file uploadsVia LOB attribute endpoints

Rolling / Daily Limits

Limit TypeValueWindowEdition Differences
REST API requestsNo published hard capPer-tenant throttlingAdaptive throttling — excessive requests receive HTTP 429
Concurrent FBDI imports5Per instanceShared across all FBDI-enabled modules
Concurrent long-running REST requestsTenant-dependentPer instanceNot published — contact Oracle Support
Scheduled processes (ESS jobs)ConfigurablePer instanceAdmin-configurable concurrent job limits

Authentication

FlowUse WhenToken LifetimeRefresh?Notes
OAuth 2.0 Client Credentials (2-legged)Server-to-server integrationConfigurable (default 3600s)New token per expiryRecommended for automated integrations
OAuth 2.0 Authorization Code (3-legged)User-context operationsConfigurable, Refresh: until revokedYesRequires redirect URI registration
JWT Bearer TokenService-to-service with signed JWTPer JWT expiry claimNew JWT per requestRequires certificate upload
Basic AuthDevelopment/testing onlySession-basedNoDeprecated for production

Authentication Gotchas

Constraints

Integration Pattern Decision Tree

START — User needs to integrate with Oracle Procurement Cloud
|-- What's the procurement object?
|   |-- Purchase Requisitions
|   |   |-- Volume < 1,000 records/day?
|   |   |   |-- YES -> REST API: purchaseRequisitions (POST + submitRequisition)
|   |   |   +-- NO -> FBDI: Import Requisitions template via ERP Integration Service
|   |-- Purchase Orders
|   |   |-- Creating/editing POs?
|   |   |   |-- YES -> REST API: draftPurchaseOrders (POST/PATCH), then submit
|   |   |   +-- NO (read-only) -> REST API: purchaseOrders (GET + actions)
|   |   |-- Need PO lifecycle events?
|   |   |   |-- YES -> Business Events via OIC (PO event subscription)
|   |   |   +-- NO -> REST API polling with lastUpdateDate filter
|   |   +-- Bulk PO creation?
|   |       +-- YES -> FBDI: Purchase Orders Import template
|   |-- Suppliers
|   |   |-- Volume < 500 suppliers/day?
|   |   |   |-- YES -> REST API: suppliers (POST/PATCH)
|   |   |   +-- NO -> FBDI: Supplier Import template
|   |   +-- Need real-time supplier updates?
|   |       |-- YES -> REST API polling (no business events for suppliers)
|   |       +-- NO -> Scheduled FBDI export via BI Publisher
|   |-- Receipts / Receiving
|   |   +-- Use SCM Cloud API: receivingReceiptRequests (NOT Procurement API)
|   +-- Sourcing / Negotiations
|       +-- REST API: supplierNegotiations, draftSupplierNegotiationResponses
|-- Which direction?
|   |-- Inbound -> Use draftPurchaseOrders or FBDI
|   |-- Outbound -> Use purchaseOrders or requisitionLifecycleDetails
|   +-- Bidirectional -> Design conflict resolution on PO status + lastUpdateDate
+-- Error tolerance?
    |-- Zero-loss -> FBDI with ERP Integration Service callbacks + retry queue
    +-- Best-effort -> REST API with exponential backoff on 429/503

Quick Reference

OperationMethodEndpointPayloadNotes
Create requisitionPOST/purchaseRequisitionsJSONCreates header; add lines as child resource
Submit requisitionPOST/purchaseRequisitions/{id}/action/submitRequisitionJSONTriggers approval workflow
Cancel requisitionPOST/purchaseRequisitions/{id}/action/cancelJSONOnly if not yet approved
Get all POsGET/purchaseOrdersN/ARead-only; supports query filters
Create draft POPOST/draftPurchaseOrdersJSONRequired for PO creation
Submit draft POPOST/draftPurchaseOrders/{id}/action/submitDocumentJSONMoves to approval
Cancel POPOST/purchaseOrders/{id}/action/cancelJSONOnly open POs
Close POPOST/purchaseOrders/{id}/action/closeJSONCloses all lines and schedules
Freeze POPOST/purchaseOrders/{id}/action/freezeJSONPrevents further changes
Create supplierPOST/suppliersJSONCreates supplier header
Register supplierPOST/supplierRegistrationRequests/{key}/action/registerJSONSelf-service registration flow
Get supplier negotiationsGET/supplierNegotiationsN/ARFQ, RFI, auction details
Create receipt (SCM)POST/receivingReceiptRequestsJSONPart of SCM API, not Procurement
Requisition lifecycleGET/requisitionLifecycleDetailsN/AEnd-to-end P2P view per requisition
Check fundsPOST/purchaseRequisitions/{id}/action/checkFundsJSONBudget validation

Step-by-Step Integration Guide

1. Authenticate and obtain access token

Configure a Confidential Application in the Fusion Applications Identity Domain and obtain an OAuth 2.0 access token using client credentials flow. [src5]

# Obtain OAuth 2.0 token from Fusion Identity Domain
curl -X POST "https://<identity-domain>.identity.oraclecloud.com/oauth2/v1/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=<CLIENT_ID>" \
  -d "client_secret=<CLIENT_SECRET>" \
  -d "scope=urn:opc:resource:consumer::all"

Verify: Response contains access_token field with a JWT value and expires_in (typically 3600).

2. Create a purchase requisition

Create a requisition header with at least one line. The requisition starts in "Incomplete" status until submitted. [src2]

curl -X POST "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/purchaseRequisitions" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "RequisitioningBUName": "US1 Business Unit",
    "PreparerId": 300000001234567,
    "Description": "Office Supplies Q2",
    "lines": [{
      "LineNumber": 1,
      "ItemDescription": "Printer Paper A4",
      "CategoryName": "Office Supplies",
      "Quantity": 100,
      "UnitPrice": 5.99,
      "UOMCode": "EA",
      "CurrencyCode": "USD"
    }]
  }'

Verify: Response HTTP 201 with RequisitionHeaderId in response body.

3. Submit requisition for approval

After creating lines, submit the requisition to trigger the approval workflow. [src2]

curl -X POST "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/purchaseRequisitions/<ReqHeaderId>/action/submitRequisition" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{}'

Verify: Response returns "result": "SUCCESS" — requisition status changes to "Pending Approval".

4. Query purchase orders with filters

Retrieve POs filtered by date range, status, or supplier. [src1]

curl -X GET "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/purchaseOrders?q=OrderNumber%3D1234&expand=lines&limit=25&offset=0" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Verify: Response contains items array with PO header and expanded lines child resources.

5. Create a supplier

Create a new supplier record with addresses and sites as child resources. [src3]

curl -X POST "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/suppliers" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "Supplier": "Acme Corp",
    "SupplierType": "Supplier",
    "TaxOrganizationType": "Corporation",
    "addresses": [{"AddressName": "HQ", "Country": "US", "AddressLine1": "123 Main St", "City": "New York", "State": "NY", "PostalCode": "10001"}],
    "sites": [{"ProcurementBU": "US1 Business Unit", "SupplierSite": "MAIN", "PaymentCurrencyCode": "USD"}]
  }'

Verify: Response HTTP 201 with SupplierId in response body.

6. Implement FBDI bulk import

For volumes exceeding 1,000 records, use FBDI via the ERP Integration Service. [src4]

# Upload ZIP to UCM and trigger import job
curl -X POST "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/erpintegrations" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "OperationName": "importBulkData",
    "DocumentContent": "<BASE64_ENCODED_ZIP>",
    "DocumentName": "PoImport.zip",
    "ContentType": "zip",
    "JobName": "/oracle/apps/ess/prc/po/PurchaseOrderImportEss",
    "ParameterList": "US1 Business Unit,N,#NULL,#NULL,N,N"
  }'

Verify: Job status returns "SUCCEEDED" — check import error report for rejected records.

Code Examples

Python: Query purchase orders with pagination

# Input:  OAuth token, Fusion host URL
# Output: List of all open purchase orders

import requests

def get_all_open_pos(host, token, bu_name="US1 Business Unit"):
    url = f"https://{host}/fscmRestApi/resources/11.13.18.05/purchaseOrders"
    headers = {"Authorization": f"Bearer {token}"}
    params = {
        "q": f'Status="OPEN";ProcurementBUName="{bu_name}"',
        "limit": 500, "offset": 0,
        "expand": "lines",
        "fields": "OrderNumber,SupplierId,Supplier,Status,OrderedAmount,CurrencyCode"
    }
    all_pos = []
    while True:
        resp = requests.get(url, headers=headers, params=params)
        if resp.status_code == 429:
            import time
            time.sleep(int(resp.headers.get("Retry-After", 30)))
            continue
        resp.raise_for_status()
        data = resp.json()
        all_pos.extend(data.get("items", []))
        if not data.get("hasMore", False):
            break
        params["offset"] += params["limit"]
    return all_pos

JavaScript/Node.js: Create purchase requisition

// Input:  Fusion host, OAuth token, requisition data
// Output: Created requisition header ID

const axios = require("axios"); // v1.6+

async function createRequisition(host, token, reqData) {
  const url = `https://${host}/fscmRestApi/resources/11.13.18.05/purchaseRequisitions`;
  try {
    const resp = await axios.post(url, reqData, {
      headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
    });
    const reqId = resp.data.RequisitionHeaderId;
    await axios.post(`${url}/${reqId}/action/submitRequisition`, {},
      { headers: { Authorization: `Bearer ${token}` } });
    return reqId;
  } catch (err) {
    if (err.response?.status === 429) {
      const retryAfter = err.response.headers["retry-after"] || 30;
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      return createRequisition(host, token, reqData);
    }
    throw err;
  }
}

cURL: Test API connectivity

# Input:  Valid OAuth token, Fusion host
# Output: Resource metadata

# Test authentication and list procurement resources
curl -s -X GET "https://<fusion-host>/fscmRestApi/resources/11.13.18.05" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" | python -m json.tool

# Describe purchaseRequisitions resource (schema/metadata)
curl -s -X GET "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/purchaseRequisitions/describe" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" | python -m json.tool

Data Mapping

Field Mapping Reference

Source FieldTarget FieldTypeTransformGotcha
External PO NumberOrderNumberStringDirect (if auto-numbering disabled)Auto-numbering overrides any provided value
Supplier NameSupplierStringExact match requiredMust match existing supplier record
Item NumberItemNumberStringMust exist in Item MasterProcurement does not auto-create items
Unit PriceUnitPriceNumberDecimal, 2-6 placesCurrency code must match PO currency
Delivery DateNeedByDateDateISO 8601 (YYYY-MM-DD)Must be future date
Ship-To LocationShipToLocationCodeStringMust match HR locationLocation codes are HR-managed
Charge AccountChargeAccountSegmentsStringSegment1-Segment2-...-SegmentNUse action/deriveChargeAccount for defaults
Tax ClassificationTaxClassificationCodeStringMust match tax setupInvalid codes cause silent tax calculation failures

Data Type Gotchas

Error Handling & Failure Points

Common Error Codes

CodeMeaningCauseResolution
400Bad RequestMalformed JSON, invalid field values, boolean as true/falseValidate payload against the describe endpoint
401UnauthorizedExpired or invalid OAuth tokenRefresh token and retry
403ForbiddenMissing Fusion security role or data security policyVerify integration user roles
404Not FoundInvalid resource path or non-existent record IDConfirm API version and resource name
429Too Many RequestsTenant-level throttle exceededExponential backoff: Retry-After header or 30s default
500Internal Server ErrorFusion application error, invalid business logicCheck payload against business rules; review ESS job logs
503Service UnavailableFusion instance under maintenance or overloadRetry after 60s; check Oracle Cloud Status page

Failure Points in Production

Anti-Patterns

Wrong: Using purchaseOrders resource to create POs

# BAD — purchaseOrders is read-only, returns 405 Method Not Allowed
curl -X POST "https://host/fscmRestApi/resources/11.13.18.05/purchaseOrders" \
  -H "Authorization: Bearer $TOKEN" -d '{"Supplier": "Acme"}'

Correct: Using draftPurchaseOrders to create, then submit

# GOOD — create via draftPurchaseOrders, then submit for approval
curl -X POST "https://host/fscmRestApi/resources/11.13.18.05/draftPurchaseOrders" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"Supplier": "Acme", "ProcurementBUName": "US1 Business Unit"}'
# Then submit:
curl -X POST "https://host/.../draftPurchaseOrders/<id>/action/submitDocument" \
  -H "Authorization: Bearer $TOKEN" -d '{}'

Wrong: Polling for supplier changes without date filter

# BAD — retrieves ALL suppliers every poll cycle, wasting API quota
def check_supplier_updates(host, token):
    resp = requests.get(f"https://{host}/.../suppliers", headers={"Authorization": f"Bearer {token}"})
    return resp.json()["items"]

Correct: Filtering by LastUpdateDate for incremental sync

# GOOD — only fetches suppliers modified since last poll
def check_supplier_updates(host, token, last_poll_time):
    resp = requests.get(f"https://{host}/.../suppliers",
        headers={"Authorization": f"Bearer {token}"},
        params={"q": f'LastUpdateDate>"{last_poll_time}"', "limit": 500})
    return resp.json()["items"]

Wrong: Using REST API for bulk supplier migration (>5,000 records)

# BAD — creates suppliers one-by-one via REST, hits throttling at scale
for supplier in ten_thousand_suppliers:
    requests.post(url, json=supplier, headers=headers)

Correct: Using FBDI for bulk supplier import

# GOOD — batch via FBDI, handles 100K records per import
import base64, zipfile, io
def bulk_import_suppliers(host, token, csv_data):
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
        zf.writestr("SupplierImport.csv", csv_data)
    payload = {"OperationName": "importBulkData",
        "DocumentContent": base64.b64encode(buf.getvalue()).decode(),
        "DocumentName": "SupplierImport.zip", "ContentType": "zip",
        "JobName": "/oracle/apps/ess/prc/poi/SupplierImportEss"}
    return requests.post(f"https://{host}/.../erpintegrations",
        json=payload, headers={"Authorization": f"Bearer {token}"})

Common Pitfalls

Diagnostic Commands

# Test authentication — should return 200 with resource list
curl -s -o /dev/null -w "%{http_code}" \
  "https://<fusion-host>/fscmRestApi/resources/11.13.18.05" \
  -H "Authorization: Bearer <TOKEN>"

# Describe a resource — returns field names, types, and constraints
curl -s "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/purchaseRequisitions/describe" \
  -H "Authorization: Bearer <TOKEN>" | python -m json.tool

# Check requisition lifecycle (end-to-end P2P status)
curl -s "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/requisitionLifecycleDetails?q=RequisitionNumber=<REQ_NUM>" \
  -H "Authorization: Bearer <TOKEN>"

# Check FBDI job status
curl -s "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/erpintegrations?finder=ESSJobStatusRF;requestId=<JOB_ID>" \
  -H "Authorization: Bearer <TOKEN>"

# List all POs for a supplier
curl -s "https://<fusion-host>/fscmRestApi/resources/11.13.18.05/purchaseOrders?q=Supplier=%22Acme%22&limit=10" \
  -H "Authorization: Bearer <TOKEN>"

Version History & Compatibility

API VersionRelease DateStatusBreaking ChangesMigration Notes
11.13.18.05 (26A)2026-01CurrentgenerateHighlights action added (AI)New AI summary feature for POs
11.13.18.05 (25D)2025-10SupportedSupplier Eligibility resource addedNew endpoint for supplier qualification
11.13.18.05 (25C)2025-08SupportedPO actions enhancedAdded duplicate, renumber actions
11.13.18.05 (25B)2025-05SupportedFBDI playbook updatedNew integration patterns documented
11.13.18.05 (25A)2025-02SupportedNoneBaseline for 2025 integrations

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Real-time requisition creation and submission (<1,000/day)Bulk requisition migration (>10,000 records)FBDI via ERP Integration Service
PO lifecycle management (freeze, close, cancel, hold)Creating purchase orders (purchaseOrders is read-only)draftPurchaseOrders resource
Supplier master data sync (<500 suppliers/day)Bulk supplier migration (>5,000 records)FBDI: Supplier Import template
Querying PO status and requisition lifecycleCreating receipts against POsSCM Cloud receivingReceiptRequests API
Event-driven PO status integrationEvent-driven supplier or agreement changesPolling with LastUpdateDate filter
Interactive sourcing/negotiation responsesAutomated mass negotiation processingFBDI or SOAP Web Services

Important Caveats

Related Units