Oracle Fusion Cloud – Configuration Guide

Service ID: oracle-fusion

Oracle Fusion Cloud Financials is Oracle's enterprise cloud ERP suite, providing general ledger, accounts payable, and accounts receivable capabilities for mid-to-large enterprises.

Oracle Fusion Cloud Financials — Configuration Guide

This guide is for teams building on Apideck. It covers what the connector can do, which values your customer has to supply, and the behaviour you need to design around.

The Oracle-side procedures — creating the integration user, assigning roles, granting data access, registering the OAuth application, and the Receivables configuration — are performed by your customer's Oracle administrator. They are documented once, for them:

Send your customer to those. This guide does not restate the procedures — where it names a role, a privilege or a scheduled process, it is so you can recognise the cause when a customer reports a symptom, and it points at the step in their guide that fixes it.

What the connector serves

ResourceOperationsNotes
journal-entrieslist, get, create, deleteCreate is asynchronous; delete only while unposted; no update
invoiceslist, get, createNo update, no delete — Oracle's own constraint, see below
ledger-accountslist, getNeeds the Get Enterprise Structures Using REST Service privilege
tracking-categorieslist, getNeeds that privilege and a chart of accounts with a tracking segment
invoice-itemslist, getReceivables standard memo lines; read-only in Oracle's API too
company-infogetReports the ledger the connection is scoped to
subsidiarieslist, getOracle legal entities; tenant-wide, not scoped to the connection's ledger. Oracle documents legal entities under the same enterprise-structures privilege as ledger-accounts, so expect it to need that grant too — not separately verified

The connector is in beta for the Accounting API. List endpoints paginate by offset; the Accounting API caps limit at 200 per request, as it does for every connector.

Each connection is scoped to a single General Ledger. To integrate more than one ledger, create a separate connection per ledger.

Connection settings

Every value below comes from your customer's Oracle tenant. The connection guide tells them where to find each one — the step references are to that document.

SettingRequiredWhere its value comes from
HostyesThe subdomain of the Fusion Applications URL (abcd1234 in https://abcd1234.fa.us2.oraclecloud.com) — Step 4
Data CenteryesThe data-center segment of the same URL (us2) — Step 4
Client IDyesThe OAuth confidential application in OCI IAM / IDCS — Step 5
Client SecretyesSame application; authenticates the token request — Step 5
Token URLyesThe tenant's IDCS / OCI IAM token endpoint. A different host from Host/Data Center — Step 5
ScopeyesPer-tenant; read off the application's authorized-resources list in the OCI console — Step 5
LedgeryesDropdown, populated by a live read once data access exists — Step 6
Data Access SetyesDropdown, same. Must grant Read-Write for journal creation — Step 6
Default Journal Sourceyes (if using journal-entries)A fixed dropdown, currently Manual / Accruals — not free text. Must be a source the customer's GL accepts for import — Step 7
Default Journal Categoryyes (if using journal-entries)A fixed dropdown, currently Manual / Accrual / Adjustment — Step 7
Tracking Segment Value Set Codeyes (if using tracking-categories)The value set behind the chart-of-accounts segment to expose as tracking categories — Step 7
Receivables Business Unityes (if using invoices)The business unit invoices are created in — Step 7
Receivables Transaction Sourceyes (if using invoices)A manual Receivables transaction source — Step 7
Invoice Transaction TypenoThe Receivables transaction type name applied to a standard invoice — type: "standard" or no type at all. Tenant-defined; Oracle seeds one called Invoice. Left blank, Oracle applies its own default — Step 7
Invoice Flexfield ContextnoContext code of the transaction descriptive flexfield whose segments custom_fields are written to. Leave empty when the segments are global — Step 7

Two of these are silent-failure risks worth knowing about when you support a customer:

  • Receivables Business Unit only affects creates. An invoice created under a business unit the customer's data-access grant does not cover is invisible to the connection afterwards, so keep the two aligned. Empty invoice lists come from the data-access grant, not from this setting.
  • Tracking Segment Value Set Code has nothing to point at on a chart of accounts with no tracking segment, and a chart cannot be restructured once its ledger has posted journals.

Authentication

OAuth 2.0 client credentials against the customer's IDCS / OCI IAM token_url host, which is a different domain from the Fusion instance every other request uses. Oracle maps the token to the Fusion user whose User Name is exactly the Client ID (Step 5). Reads and invoice creation work; on some tenants Oracle's scheduler intermittently refuses these tokens, which surfaces as 503 on journal-entry create (see below).

Oracle authorizes API calls under that Fusion Applications user, not under the OAuth client, so a token request can succeed while every REST call returns 403: the user is missing its roles, or no user with the Client ID as its name exists.

A blanket 403 has two other causes worth ruling out with your customer, both covered by the connection guide: their Fusion user may lack the Access FSCM Integration Rest Service privilege, which General Accounting Manager carries but a least-privilege custom role has to be given explicitly; or the scheduled processes that make any role change effective may simply not have been run yet.

What connection validation does and does not prove

Validation calls the Ledgers list endpoint. A green validation confirms Host, Data Center and authentication.

It does not confirm:

  • that the Data Access Set grants Read-Write — validation only performs a read, so a read-only grant surfaces later as a journal-import security failure;
  • that the user can see any data at all — Oracle returns an empty list rather than an error for a principal with no data access, so validation is green either way.

If General Ledger resources work but invoice lists come back empty, the cause is almost always missing Business Unit data access: Receivables visibility is secured by business unit, entirely separately from the GL Data Access Set. A new grant is also not live for a REST caller until both of the scheduled processes in the connection guide's Step 2.5 have run, in order — Send Pending LDAP Requests first, then Import User and Role Application Security Data; in live verification a role change reached REST reads within a minute of the first completing. And on the verification pod the integration user also needed Application Implementation Consultant to see Receivables at all — see the Receivables guide, Section I. Verify with an API read: a grant that looks correct in Users with Data Access is not proof it is live for a REST caller.

Journal-entry behaviour

Creating a journal entry is asynchronous — it submits the entry to Oracle's journal-import process and returns immediately. The journal does not exist yet when the call returns.

  • The id in the create response is a submission receipt, prefixed with ess-group: (e.g. ess-group:238151661897615) so your code cannot mistake it for a journal id. You can use it on journalEntriesOne and journalEntriesDelete straight away: while the import is still running they answer 404, and once the journal exists they answer for that journal, whose own id is in the response. The receipt keeps working for as long as the journal exists.
  • A create that returns 2xx has been submitted. Oracle answers a submission it will not accept with a success status and a request id of -1; the connector turns that into an error rather than handing back an id that refers to nothing. Oracle gives no reason, and no import request exists to inspect, so the connector checks one thing itself: whether Oracle's scheduler accepts the connection's credentials at that moment. A 503 means it does not — on some tenants the scheduler refuses a client-credentials token for stretches of up to about thirty minutes while every read keeps working; retry later without changing anything. A 403 means the scheduler accepts the credentials, which makes a privilege gap the most likely cause — but the check cannot tell that apart from a submission Oracle would not accept, so treat it as a lead rather than a verdict and retry the journal on its own before changing any roles. A 502 means the check itself did not answer; retry. Closed periods and bad account combinations are not reported here: those surface only after a successful submission, in the asynchronous import's own log.
  • The request can also be refused before Oracle is contacted at all. A 422 means the connection is missing one of Ledger, Data Access Set, Default Journal Source or Default Journal Category, and names the one that is missing. A 400 means the payload broke one of the rules below.
  • Reads return at most 25 line items per journal, and on a list no more than the request's own limit per journal, while the entry's own totals describe the whole journal. Oracle exposes no route to the remaining lines, so a journal with more lines cannot be read in full through this API. A response whose lines may be incomplete carries a truncated_child_collection entry in meta.warnings.
  • To find the resulting journal, list journal entries once the import has had time to complete (seconds to several minutes) and use the listed entry's id for subsequent journalEntriesOne calls.
  • Journals are always created Unposted. Posting is a separate step in Oracle and is not performed by this connector.
  • Update is not supported at any status — Oracle provides no API route to edit journal content. To change an unposted journal, delete it and recreate it; correct a posted journal with a reversal in Oracle. Delete works only while the journal is unposted.
  • Only the ledger's functional currency is supported. No multi-currency journal entries.
  • Filtering: filter[start_date] and filter[end_date] select on the Oracle posting date, inclusive; unposted journals have no posting date and never match a date range. filter[status] matches Oracle's stored status exactly, including its letter case — a tenant can hold both cases of the same status, and a journal stored in the other case reads back with the same unified status but is silently absent from a list filtered on it. So filter[status]=draft is not a complete way to find unposted journals, including one saved without completion; omit the filter and check each entry's own status when completeness matters. filter[end_date] must be exactly YYYY-MM-DD — a timestamp-shaped value (the form filter[updated_since] takes) is refused with a 400. filter[status] and filter[updated_since] are supported; filter[scope] and filter[subsidiary_id] are refused. Sorting works on created_at and updated_at.
  • Account and period validation errors are not returned by the create call — they surface only in the asynchronous import, which this connector does not expose. Your customer can check the request under Navigator → Tools → Scheduled Processes in Oracle.
  • On a journal line, send the account as ledger_account.code (the account combination, e.g. 01.000.1200) — never ledger_account.id, which is Oracle's internal combination id and is not a segmented account code.

What a journal create accepts

Oracle takes the whole entry as a single import that the connector assembles and balances, so the payload rules are stricter than the unified schema alone suggests. Each of these is refused with a 400 naming the field, rather than being accepted and silently dropped:

  • Amounts are always positive. line_items[].type (debit / credit) carries the direction on its own, and a zero or negative total_amount is refused. This differs from the unified schema's own field description, which describes credits as negative — send the absolute amount.
  • At least two lines, and they must balance to zero.
  • Every line needs ledger_account.code, non-blank. It is the only part of ledger_account that is read.
  • posted_at must be an ISO 8601 calendar date (YYYY-MM-DD, optionally with a time). A non-ISO value such as 09/15/2026 is refused rather than interpreted, because its meaning depends on the writer's locale and the guess would select a different accounting period. posted_at selects the accounting date and therefore the period; accounting_period on its own selects the period directly, in Mon-YY form; sending both with different meanings is refused.
  • No tax. tax_code, tax_type and a line's tax_amount, tax_rate or tax_type are refused if present. (tax_inclusive is currently ignored rather than refused.)
  • memo holds 214 characters, each line's description 240, and title 87. Longer is refused — Oracle would accept it and then discard the whole import silently, or keep the journal and trim the title. Emoji and other characters outside the Basic Multilingual Plane count as four each against these limits, because that is how Oracle stores them.
  • pass_through is not supported on this operation and is refused. Anything added to the submission makes Oracle reject the entire import without saying why, so it is rejected up front instead of producing a create that quietly never becomes a journal.

Fields the unified schema accepts here and Oracle never stores: status (journals always import Unposted), number, display_id, company_id, subsidiary, journal_symbol, tracking_categories, custom_fields, attachments, source_type, source_id, and per line line_number, base_currency_amount, tracking_category/tracking_categories, customer, supplier, employee, department_id, location_id and worktags. Cost centres and departments are segments of the account combination, so they are set through ledger_account.code. The per-resource API reference carries the full list.

Invoice behaviour

  • Create only. Oracle will only ever create a completed invoice, and a completed invoice cannot be deleted and accepts almost no edits — not its amounts, dates or lines. Update and delete are therefore not supported; correct an invoice with a credit memo or an adjustment, which is what Oracle itself expects.
  • Reference the customer with customer.display_id (the account number) on a create. customer.id carries Oracle's internal party id — it is what filter[customer_id] takes on reads, but Oracle refuses it on a write.
  • Line amounts must be self-consistent, unless the line carries a discount. Oracle computes each line's amount from quantity × unit_price and ignores a total_amount sent alongside, so a request whose total_amount disagrees with that product is rejected rather than silently invoiced for the product. A discounted line is the exception, because Receivables has no line-discount field: there the disagreement IS the discount, so total_amount is honoured and absorbed into the unit price. A discount sent with only a unit_price is treated as one unit; sent with only a quantity, there is no price to reduce and the request is refused rather than invoiced at full price.
  • Line amounts are not rounded to the currency. A quantity or unit_price derived from the other line values is kept at ten decimals, so 100 over 3 units reads back as a unit price of 33.3333333333; Oracle rounds only the invoice totals to the currency. Send quantity and unit_price when the exact line amount matters.
  • invoice_date does not set the accounting date. Oracle assigns that itself, to an open period. Forcing it would fail for any invoice dated into a closed period.
  • Reference an invoice item by name in item.code. Receivables matches memo lines on their exact, case-sensitive name and rejects the item's id, so line_items[].item.id is not populated. Some seeded memo lines are reserved for other document types and are refused on a customer invoice; Goods and Services is the general-purpose one.
  • The list is not restricted to sales invoices — credit and debit memos come back in the same list, distinguished by type. Oracle transaction types are tenant-defined names, so a custom type reads as other.
  • Filtering: filter[id_since], filter[updated_since], filter[created_since], filter[number] and filter[customer_id] are supported. filter[ids] is not — Oracle cannot match a list of ids on this resource. Sorting works on created_at, updated_at and id.
  • Not available: subsidiary (an invoice carries only the legal entity's code, not the id the Subsidiaries resource is keyed by) and billing_address / shipping_address (only site codes exist behind them — no street, city or country). Both are readable with raw=true.
  • Tax figures follow the tenant's tax configuration. sub_total and total_tax are assembled from the invoice's installments, with freight included in sub_total so that sub_total + total_tax reconciles to total. On a tenant with no tax rules configured, total_tax is 0. line_items[].tax_amount and tax_rate.rate are returned by the single-invoice read only; the list carries the header total_tax and each line's tax_rate.code.

Reference-resource behaviour

  • ledger-accounts — name, code and display_id all carry the account combination (e.g. 01.000.1200); id is Oracle's internal combination id and is the only value that addresses a single record. filter[classification] and filter[status] are supported. filter[name] is not: Oracle publishes no description for an account combination. Classifications Oracle does not model (income, other_income, other_expense, costs_of_sales, other) match nothing and return an empty list.
  • tracking-categories — a connection exposes exactly one chart-of-accounts segment, chosen by the Tracking Segment Value Set Code setting, so that ids stay unambiguous. Reads only.
  • invoice-items — Receivables standard memo lines. Read-only in Oracle's API as well as here; they are maintained under Manage Standard Memo Lines. Inventory items from the Product Management item master are not returned. No filters and no sort — the list pages like every other list here.
  • subsidiaries — Oracle legal entities, tenant-wide: the list is not scoped to the connection's ledger, so expect entities unrelated to it. Reads only.

Make your first API call

curl --location 'https://unify.apideck.com/accounting/journal-entries' \
 --header 'x-apideck-consumer-id: test-consumer' \
 --header 'x-apideck-app-id: {APIDECK_APP_ID}' \
 --header 'x-apideck-service-id: oracle-fusion' \
 --header 'Authorization: Bearer {APIDECK_API_KEY}'