# Oracle Fusion Cloud ERP — integration documentation

> Machine-readable rendition of Oracle Fusion Cloud ERP simulator documentation. The machine contract named in the overview below is the authority on request and response shapes; this page carries what a schema cannot say — what is deliberately unsupported, what the real product documents that this simulator does not implement, what each error code means, and the workflows.

API version: `11.13.18.05`

The Oracle Fusion simulator exposes a subset of the Oracle Fusion Cloud ERP Financials integration surface. It mirrors Oracle's REST (fscmRestApi) and SOAP endpoints, payload shapes, response envelopes and error codes so an external application can integrate against it using the same code paths it would use against a real Oracle Fusion instance.

This simulator follows the externally observable integration patterns of Oracle Fusion Cloud ERP. It does NOT implement the full Oracle Financials feature set. Only the resources, operations and query parameters listed below are supported; anything else should be assumed unimplemented.

## Terminology

| Term | Definition |
| --- | --- |
| Environment key | A system-generated, immutable identifier (env_…) that selects which tenant's simulator a request targets. It is not a credential and is safe to put in URLs. |
| fscmRestApi | The Oracle Fusion Financials/SCM REST API root. Every Financials resource is mounted under it. Contacts are NOT: Oracle serves them from the CX family at crmRestApi, and so does this simulator - the Financials path answers 404. |
| CustomerTransactionId | Oracle's primary key for a receivables transaction (invoice). 18-digit numeric, generated by the simulator. |
| Business Unit | Oracle's organizational scoping concept for financial transactions. |
| Transaction Source | Logical source classification for the invoice (e.g. MANUAL). |
| WSDL | XML description of a SOAP service. Fetch it with `?WSDL` appended to the service endpoint. |
| UsernameToken | WS-Security authentication header carrying a username and password. This simulator serves the WSS 1.0 secext namespace (oasis-200401-wss-wssecurity-secext-1.0.xsd) with the PasswordText profile; PasswordDigest is refused with env:Client.PasswordTypeUnsupported. |

## Base URLs

| Purpose | Template |
| --- | --- |
| Instance URL | `https://erplab.cloud/sim/{environmentKey}` |
| REST base URL | `https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05` |
| SOAP base URL | `https://erplab.cloud/sim/{environmentKey}/soap` |
| OAuth token URL | `https://erplab.cloud/sim/{environmentKey}/oauth/token` |

## Authentication

### OAuth 2.0 client credentials (REST)

All REST calls to fscmRestApi. This is the only REST authentication method the simulator implements.

Required:

- client_id
- client_secret
- scope
- OAuth token URL
- REST base URL

**1. Request an access token**

Send a form-encoded POST to the tenant's OAuth token URL. scope is REQUIRED: Oracle marks it required on the client_credentials grant, and this endpoint refuses a request without it with 400 invalid_request. Against this simulator send urn:opc:resource:consumer::all; against a real Oracle environment send the scope configured on the resource application in your identity domain.

```bash
curl --request POST \
  "https://erplab.cloud/sim/{environmentKey}/oauth/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=urn:opc:resource:consumer::all" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
```

Success response:

```json
{
  "access_token": "5p1c…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "urn:opc:resource:consumer::all"
}
```

Using the token:

```bash
curl --request GET \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=10" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Accept: application/json"
```

Tokens are valid for 1 hour. Cache them and re-mint shortly before expiry. Revoking a client invalidates all of its outstanding tokens.

| Status | Meaning |
| --- | --- |
| 400 | invalid_request — a required parameter is missing: grant_type, client_id, client_secret or scope. |
| 400 | invalid_scope — the requested scope exceeds the scope granted to this client, or urn:opc:resource:consumer::all was combined with another scope. Oracle requires that one to be requested on its own. |
| 401 | invalid_client — unknown client_id, wrong client_secret, revoked client, or credential issued for a different environment. All four return the same code and the same message; the response never confirms that a client_id exists. |
| 405 | invalid_request — the token endpoint accepts POST only. |

### WS-Security UsernameToken (PasswordText) (SOAP)

All SOAP calls. Mint a SOAP credential under ERP simulator → SOAP credentials; the password is shown once.

Required:

- SOAP username
- SOAP password
- SOAP endpoint

**1. Add the WS-Security header inside the SOAP envelope**

```xml
<soap:Header>
  <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken>
      <wsse:Username>YOUR_SOAP_USERNAME</wsse:Username>
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">YOUR_SOAP_PASSWORD</wsse:Password>
    </wsse:UsernameToken>
  </wsse:Security>
</soap:Header>
```

Success response:

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <createSimpleInvoiceResponse xmlns="http://xmlns.oracle.com/apps/financials/receivables/transactions/invoices/invoiceService/">
      <result>…</result>
    </createSimpleInvoiceResponse>
  </soap:Body>
</soap:Envelope>
```

SOAP credentials do not expire. Revoke them from the ERP simulator settings page when no longer needed.

| Status | Meaning |
| --- | --- |
| 401 | env:Client.AuthRequired or env:Client.AuthFailed — missing or invalid UsernameToken, or credential issued for a different environment. |
| 400 | env:Client.MalformedXml or env:Client.DtdForbidden — invalid XML or DTD/XXE detected. |

## First request

After obtaining a bearer token, list the first page of receivables invoices for your tenant. The response is the Oracle paging envelope.

```bash
curl --request GET \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=5&totalResults=true" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Accept: application/json"
```

Response:

```json
{
  "items": [ /* up to 5 invoice objects */ ],
  "count": 5,
  "hasMore": true,
  "limit": 5,
  "offset": 0,
  "totalResults": 80,
  "links": [{ "rel": "self", "href": "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices", "kind": "collection" }]
}
```

If `hasMore` is true, request the next page by increasing `offset` by `limit`. Stop when `hasMore` is false.

## Pulling data

**List**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Single record**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Filter**

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  --data-urlencode "q=InvoiceStatus='Complete' and InvoiceBalanceAmount>=1000" \
  --data-urlencode "orderBy=TransactionDate:desc" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Page loop**

```bash
# Walk every page until hasMore=false.
LIMIT=100; OFFSET=0
while : ; do
  PAGE=$(curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=$LIMIT&offset=$OFFSET" \
    -H "Authorization: Bearer $TOKEN")
  echo "$PAGE" | jq '.items[] | .CustomerTransactionId'
  HAS_MORE=$(echo "$PAGE" | jq -r '.hasMore')
  [ "$HAS_MORE" = "true" ] || break
  OFFSET=$((OFFSET + LIMIT))
done
```

**Field projection**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?fields=CustomerTransactionId,TransactionNumber,EnteredAmount&limit=10" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Embedded children**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?expand=receivablesInvoiceLines&limit=5" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Response envelope:

| Field | Description |
| --- | --- |
| items | Array of resource items for this page. |
| count | Number of items returned on this page (≤ limit). |
| hasMore | true if there are more pages after this one. |
| limit | Echo of the requested or default page size. |
| offset | Echo of the requested offset. |
| totalResults | Only present when totalResults=true was supplied. Exact total across all pages. |
| links | HATEOAS links. The collection envelope includes a `self` link. |

## Writing data

### Create an invoice (REST)

Required: BusinessUnit, TransactionType, TransactionSource, BillToCustomerNumber, InvoiceCurrencyCode, and at least one receivablesInvoiceLines entry. Server generates CustomerTransactionId, TransactionNumber, EnteredAmount and InvoiceBalanceAmount. A new invoice comes back COMPLETE, with its installments already generated - Oracle's InvoiceStatus defaults to Complete and Oracle requires that value on create, so there is no completion step to call and /action/complete answers 404. Until 2026-08-04 this description claimed the opposite, which sent a reader looking for a completion call that does not exist.

```bash
curl --request POST \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "BusinessUnit": "Vision Operations",
    "TransactionType": "Invoice",
    "TransactionSource": "MANUAL",
    "BillToCustomerNumber": "0001001",
    "InvoiceCurrencyCode": "USD",
    "receivablesInvoiceLines": [
      { "LineNumber": 1, "Description": "Consulting", "Quantity": 10, "UnitSellingPrice": 125 }
    ]
  }'
```

- AR-1010 if BillToCustomerNumber does not match a customer in this tenant.
- AR-1030 if InvoiceCurrencyCode is not a defined, enabled currency. Line amounts are computed as Quantity x UnitSellingPrice and rounded to that currency's precision, so a zero-decimal currency such as JPY returns whole units and a three-decimal currency such as KWD keeps its third decimal. An amount that cannot be represented in its own currency is never stored.
- AR-1030 also if a line's Quantity x UnitSellingPrice is non-zero but rounds to zero at the currency's precision — 0.4 JPY, say. A line you asked for is never quietly turned into a line for nothing. Asking for zero outright is different and is accepted, because zero-amount invoices are legitimate.
- AR-1000 lists every missing required attribute via o:errorPath.

### Patch mutable fields

Updatable fields: InvoiceStatus, PaymentTerms, TransactionDate — Oracle 26B allows only these three. Any other attribute returns AR-1020, including BusinessUnit, TransactionType, TransactionSource, InvoiceCurrencyCode, DueDate, DeliveryMethod and Email; set those on create instead. Reassigning the bill-to customer through PATCH is not supported.

```bash
curl --request PATCH \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{ "PaymentTerms": "NET30", "TransactionDate": "2026-07-25" }'
```

### Complete an invoice (does not exist - returns 404)

There is no completion step. Oracle creates receivables invoices with InvoiceStatus Complete - the attribute defaults to Complete and Oracle states "Value must be Complete when creating a receivables invoice" - so an invoice is already Complete when POST returns. This simulator previously created invoices Incomplete and served an /action/complete endpoint; neither exists in Oracle, and code written against that flow failed on a real pod at the second call. The endpoint answers 404, the same as any unknown action, because that is what a real Oracle pod answers - it never had this action to withdraw. Oracle documents three actions on this resource: approve, rework and splitInstallments; only splitInstallments is implemented here.

```bash
# Nothing to call. POST /receivablesInvoices already returns
# "InvoiceStatus": "Complete", with installments generated.
# The old endpoint answers 404, like any unknown action:
#
#   POST https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{id}/action/complete
#   -> 404  Resource path not found
#
# Confirm the status on the created invoice instead:
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Conventions

| Topic | Detail |
| --- | --- |
| Content type (REST) | Requests and responses use application/json. POST/PATCH must set Content-Type: application/json. |
| Content type (SOAP) | Requests and responses use text/xml; charset=utf-8. SOAPAction header is required. |
| Character encoding | UTF-8 throughout. SOAP envelopes must not include a DOCTYPE. |
| Dates | yyyy-MM-dd (date-only fields such as TransactionDate, DueDate). |
| Currency amounts | JSON numbers with at most 4 decimal places. Currency is selected per invoice via InvoiceCurrencyCode. |
| Identifiers | CustomerTransactionId is a 15–18 digit numeric string-safe number generated by the simulator. |
| Booleans | true/false in JSON; "true"/"false" tolerated in query string parameters (onlyData, totalResults). |
| Nulls | Explicit JSON null is allowed in PATCH bodies for the nullable attributes PATCH accepts. On receivablesInvoices that is InvoiceStatus, PaymentTerms and TransactionDate only - DueDate was given as the example here until 2026-08-04 and is rejected with AR-1020 like any other read-only attribute. |
| Pagination | Offset/limit. Default limit 25, maximum 500. Use hasMore + offset to iterate. |
| TLS | All published URLs are HTTPS. Local development may use HTTP on 127.0.0.1. |
| Authorization header | Bearer scheme for REST; WS-Security UsernameToken inside the SOAP envelope for SOAP. No cookies, no API-key headers. |
| Idempotency | Not currently enforced. Retrying a POST creates a new invoice. Use PATCH to update an existing invoice. |
| Rate limits | Not enforced in this phase. |

## Limitations

- REST writes are scoped to Receivables (AR) Invoices and their lines. Contacts and customerAccountSitesLOV are read-only.
- DELETE is not implemented for any resource.
- The q grammar supports the operators listed above; full Oracle expression coverage (BETWEEN, IS NULL, nested grouping beyond AND/OR) is not implemented.
- Only the `receivablesInvoiceLines` child accessor is expandable.
- OAuth tokens are simple opaque bearer values; introspection, refresh and revocation endpoints are not exposed. The `scope` claim is empty unless scopes are set directly on the client row.
- Rate limiting and idempotency keys are not enforced in this phase.
- SOAP supports only the PasswordText profile; SAML and PasswordDigest are not implemented.
- Data generation: the only supported tenant action is a destructive full reset of the ERP simulator (ERP simulator settings → Danger zone). Granular re-seeding, additional fixture profiles and per-object regeneration are not exposed.

## Capability matrix

Every capability, with its support status. `not_supported` means exactly that — do not build against it.

| Capability | Protocol | Resource | Operations | Auth | Status | Notes |
| --- | --- | --- | --- | --- | --- | --- |
| OAuth 2.0 token endpoint | OAuth | `/oauth/token` | client_credentials | client_id + client_secret | **supported** | POST only, application/x-www-form-urlencoded. Required parameters: grant_type=client_credentials, scope, client_id, client_secret - credentials may instead be sent as HTTP Basic. scope is REQUIRED, as Oracle marks it; send urn:opc:resource:consumer::all, on its own. Returns access_token, token_type=Bearer, expires_in=3600, scope. |
| List receivables invoices | REST | `/receivablesInvoices` | GET (list) | Bearer | **supported** | q, fields, limit, offset, orderBy, totalResults, onlyData, expand=receivablesInvoiceLines, finder=PrimaryKey (invoiceSearch is documented by Oracle and refused here) |
| Retrieve one invoice | REST | `/receivablesInvoices/{id}` | GET | Bearer | **supported** |  |
| Add a line to an invoice | REST | `/receivablesInvoices/{id}/child/receivablesInvoiceLines` | POST | Bearer | **supported** | Raises the invoice total by Quantity x UnitSellingPrice. The increase goes to the last open installment, so installment identities and any applied receipts survive; if every installment is closed a new one carries it. Oracle publishes no delete and no update on this child - to LOWER an amount, issue a credit memo. |
| List invoice lines | REST | `/receivablesInvoices/{id}/child/receivablesInvoiceLines` | GET | Bearer | **supported** |  |
| Retrieve one invoice line | REST | `/receivablesInvoices/{id}/child/receivablesInvoiceLines/{CustomerTransactionLineId}` | GET | Bearer | **supported** | Honours fields, onlyData and links. Oracle documents expand and dependency here too; neither is implemented anywhere on this surface, so both are refused by name. |
| Create invoice | REST | `/receivablesInvoices` | POST | Bearer | **supported** |  |
| Patch invoice | REST | `/receivablesInvoices/{id}` | PATCH | Bearer | **supported** | Updatable: InvoiceStatus, PaymentTerms, TransactionDate. Anything else is rejected with AR-1020. InvoiceStatus accepts all three of Oracle's values - Complete, Incomplete, Frozen - and is the only status attribute this resource lets you change. |
| Complete invoice | REST | `/receivablesInvoices/{id}/action/complete` | POST | Bearer | **not_supported** | Not an Oracle action. Returns 404, as a real pod does for an unknown action. Oracle creates invoices Complete, so there is no completion step - remove the call. |
| Delete invoice | REST | `/receivablesInvoices/{id}` | DELETE | Bearer | **supported** | 204 with no response body, as Oracle documents. Lines and installments go with it. Refused 400 AR_TRX_DELETE_NOT_ALLOWED when the invoice carries receipt applications - Oracle states no preconditions, and that restriction is ours, deliberately: cascading would destroy the record of where a customer's money went. Unapply first. |
| List invoice installments | REST | `/receivablesInvoices/{id}/child/receivablesInvoiceInstallments` | GET | Bearer | **supported** | Every invoice has at least one installment. Fields: InstallmentId, Sequence, DueDate, OriginalAmount, InstallmentBalanceDue, AmountPaid, Status (OP/CL), ClosedDate, DaysLate, LastUpdateDate. |
| Retrieve one installment | REST | `/receivablesInvoices/{id}/child/receivablesInvoiceInstallments/{InstallmentId}` | GET | Bearer | **supported** |  |
| Split installments | REST | `/receivablesInvoices/{id}/action/splitInstallments` | POST | Bearer | **supported** | Adds installments to a COMPLETE invoice and changes the amounts and due dates of existing ones. Installments are matched by InstallmentSequenceNumber and updated in place, so applied receipts stay attached. Rules: the amounts must sum to the transaction amount; a due date must be on or after the transaction date; sequences are contiguous; a new installment must be greater than zero while an existing one may be set to zero; an installment cannot be set below the amount already applied to it; and a closed installment's amount and due date cannot change. An installment cannot be deleted, so the payload must name every installment the invoice already has - omitting one is refused 400 AR-1040, and setting its amount to zero is the documented alternative. Breaching the applied-amount floor or changing a closed installment is refused 409 AR-2012 naming the installment. |
| Incremental sync via LastUpdateDate | REST | `/receivablesInvoices` | GET (q filter) | Bearer | **supported** | LastUpdateDate is emitted as `YYYY-MM-DDTHH:mm:ss.sss+0000` and is q-filterable on INVOICES ONLY — Oracle marks it x-queryable false on the installments child, and on standardReceipts, so neither can be filtered by watermark. That costs nothing here: child mutations cascade to the parent invoice's LastUpdateDate, so ONE cursor over receivablesInvoices detects both header and installment changes. It is the only incremental-sync cursor Oracle offers on this data. |
| List contacts | REST | `/crmRestApi/.../contacts` | GET (list) | Bearer | **supported** | CX base path - Financials has no contacts resource. q, fields, expand=ContactPoint, limit, offset, orderBy, totalResults, onlyData, finder=PrimaryKey\|ContactPartyNumberRF |
| Retrieve one contact | REST | `/crmRestApi/.../contacts/{PartyNumber}` | GET | Bearer | **supported** | Keyed by PartyNumber, as Oracle keys the item path. |
| Create / update contact | REST | `/crmRestApi/.../contacts` | POST / PATCH / DELETE | Bearer | **not_supported** | Read-only here; writes answer 405 naming the operation. Oracle DOES publish these - the contacts resource documents Create, Update and Delete alongside the two reads - so this is a limitation of the simulator, not of Oracle. Stated because every other row in this matrix distinguishes the two, and without it you cannot tell which way to adapt. |
| Contact points | REST | `/crmRestApi/.../contacts/{PartyNumber}/child/ContactPoint` | GET (list, retrieve) | Bearer | **supported** | One row per communication type (EMAIL, PHONE). |
| Contacts on the Financials path | REST | `/fscmRestApi/.../contacts` | any | Bearer | **not_supported** | Not a resource of Oracle Financials. Returns a plain 404, the same as any unknown resource, because that is what a real pod returns - the migration note lives here in the docs rather than on the wire. |
| List receivables adjustments | REST | `/receivablesAdjustments` | GET (list) | Bearer | **supported** | Read-only. q on the six attributes Oracle marks queryable, fields, limit, offset, orderBy, totalResults, onlyData, links, finder=PrimaryKey;AdjustmentId. The same rows are visible per customer through the transactionAdjustments child of the account-activity resources. |
| Retrieve one receivables adjustment | REST | `/receivablesAdjustments/{AdjustmentId}` | GET | Bearer | **supported** | Returns a single adjustment. One belonging to another tenant answers 404, indistinguishable from one that does not exist. |
| Create / update / delete adjustment | REST | `/receivablesAdjustments` | POST / PATCH / DELETE | Bearer | **not_supported** | Oracle documents no create, update or delete for adjustments - the POST operation page does not exist while the GET page on the identical URL shape does. 405. Together with the absence of any credit-memo apply operation, this means no published REST call lowers a transaction's balance, here or on a real pod. |
| Receivables adjustment descriptive flexfields | REST | `/receivablesAdjustments/{AdjustmentId}/child/receivablesAdjustmentDFF` | GET | Bearer | **not_supported** | Oracle's one child on this resource. No descriptive flexfield contexts are defined anywhere in this simulator, so the collection would describe an extension surface that does not exist. Refused by name, and expand naming it is refused rather than answered with an empty array. |
| List receipt methods | REST | `/receiptMethods` | GET (list) | Bearer | **supported** | Read-only. q, fields, limit, offset, orderBy, totalResults, onlyData, finder=PrimaryKey;ReceiptMethodId. Use it to discover the values accepted as ReceiptMethod on a standard receipt. Oracle publishes no status attribute, so an active and a retired method look identical here. |
| Retrieve one receipt method | REST | `/receiptMethods/{ReceiptMethodId}` | GET | Bearer | **supported** |  |
| Create / update / delete receipt method | REST | `/receiptMethods` | POST / PATCH / DELETE | Bearer | **not_supported** | Oracle documents only the two GET operations; receipt methods are Receivables setup. 405. Add methods on the ERP simulator settings page. |
| List customer account sites | REST | `/customerAccountSitesLOV` | GET (list) | Bearer | **supported** | One row per site USE, keyed by SiteUseId. q, fields, limit, offset, orderBy, totalResults, onlyData, finder=PrimaryKey;SiteUseId. Oracle list of values carries no address attributes and no SiteUseCode. |
| Retrieve one customer account site | REST | `/customerAccountSitesLOV/{SiteUseId}` | GET | Bearer | **supported** |  |
| Site purposes as a child collection | REST | `/customerAccountSites/{id}/child/siteUses` | GET | Bearer | **not_supported** | Withdrawn. Oracle documents no such child: its list of values is already keyed by SiteUseId, so each row IS a site use. The old path returns 404, as a real Oracle pod does for a resource it has never had. |
| Create / update customer account site | REST | `/customerAccountSitesLOV` | POST / PATCH / DELETE | Bearer | **not_supported** | Oracle documents only GET on this resource. |
| Create simple invoice | SOAP | `InvoiceService` | createSimpleInvoice | WS-Security UsernameToken | **supported** |  |
| WSDL retrieval | SOAP | `InvoiceService?WSDL` | GET | none | **supported** |  |
| Create standard receipt | REST | `/standardReceipts` | POST | Bearer | **supported** | Requires Amount, BusinessUnit, Currency, ReceiptDate, ReceiptMethod. Creates the receipt UNAPPLIED (or UNIDENTIFIED when no customer resolves) and returns before any application is made. Privilege: AR_CREATE_RECEIVABLES_RECEIPT_PRIV. |
| List / retrieve standard receipts | REST | `/standardReceipts and /standardReceipts/{StandardReceiptId}` | GET | Bearer | **supported** | q, fields, expand=remittanceReferences, limit, offset, orderBy, onlyData, totalResults. Privilege: AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |
| Update standard receipt customer details | REST | `/standardReceipts/{StandardReceiptId}` | PATCH | Bearer | **supported** | Only CustomerAccountNumber, CustomerBankAccountNumber, CustomerName, CustomerSite. Blocked on applied, approved, reversed, automatic, netting, bill-to receivables, frozen and unaccounted receipts. |
| Delete standard receipt | REST | `/standardReceipts/{StandardReceiptId}` | DELETE | Bearer | **supported** | Eligibility restricted: a receipt with applications, or one that is accounted, frozen, reversed or automatic, cannot be deleted. It is never silently unapplied to make it deletable. |
| Remittance references | REST | `/standardReceipts/{id}/child/remittanceReferences` | POST / GET | Bearer | **supported** | Supported nested inside the receipt POST and as a standalone child POST afterwards. PATCH and DELETE are not offered: not confirmed as supported by Oracle 26B. |
| Resource metadata (describe) | REST | `/<resource>/describe` | GET | Bearer | **supported** | Oracle's runtime metadata endpoint. Returns Resources.<name> with attributes (name, type, mandatory, updatable, queryable, precision), collection (rangeSize, links, actions), item (links including one per child, actions) and links. `updatable` is PATCH-ability, not writability on create - BusinessUnit is required on invoice create and reports updatable:false. `queryable` is the same fact the OpenAPI schema publishes as x-queryable; Oracle names it queryable here. Prefer this over our OpenAPI document when you want metadata through a mechanism a real pod also serves. Not emitted, because the shape could not be confirmed: children (children appear as rel:child item links instead), lov, controlType, scale, allowChanges and link cardinality. |
| List / retrieve credit memos | REST | `/receivablesCreditMemos and /receivablesCreditMemos/{CustomerTransactionId}` | GET | Bearer | **supported** | Credit memos share the {CustomerTransactionId} id space with invoices but are a SEPARATE Oracle resource with its own attribute names - CreditMemoCurrency not InvoiceCurrencyCode, TransactionBalanceDue not InvoiceBalanceAmount. A credit memo never appears under /receivablesInvoices and an invoice id answers 404 here, so sync both resources if you are reconciling a balance. Nine attributes are filterable; the amounts are not, because Oracle does not mark them queryable. |
| Create a credit memo | REST | `/receivablesCreditMemos` | POST | Bearer | **supported** | Requires BusinessUnit, TransactionDate and TransactionNumber, which Oracle marks required - the number is supplied by the caller here, unlike an invoice's. BillToCustomerNumber is also required, a stated divergence: Oracle marks it optional and presumably resolves the account another way, and no other route to one is modelled. Lines are receivablesCreditMemoLines with a positive Amount each; the total is derived. The memo is created unapplied, and stays that way - see the row below. |
| Update a credit memo | REST | `/receivablesCreditMemos/{CustomerTransactionId}` | PATCH | Bearer | **supported** | CreditMemoStatus, RecipientEmail and TransactionType. Oracle states no "only these" restriction on this resource, unlike invoices. AllowCompletion and ControlCompletionReason are refused by name: they drive an approval workflow that is not modelled, and storing them would look like they took effect. TransactionType must stay Credit Memo, since that column is what separates this resource from /receivablesInvoices. |
| Credit memo lines | REST | `/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines` | GET / POST | Bearer | **supported** | Get all, Get one and Create a set - exactly the three Oracle publishes; there is no update and no delete. The attribute names are the credit memo's own (LineDescription, LineAmountCredit, LineQuantityCredit), NOT the invoice line's. The header amount is re-derived from the lines on every write. |
| Approve or rework a credit memo | REST | `/receivablesCreditMemos/{CustomerTransactionId}/action/*` | action | Bearer | **not_supported** | Oracle documents all four; this simulator implements none of them and refuses each BY NAME rather than as unknown, so you can tell a missing feature here from one that does not exist in Oracle. Credit memos are seeded as part of the dataset. The seven child collections Oracle documents are likewise not modelled and answer 404. Worth knowing before you plan around it: APPLYING a credit memo to an invoice is not a REST operation in Oracle either. The credit memo create body carries no attribute naming an invoice, and creditMemoApplications publishes only Get and Get all - so there is no published call that reduces an invoice's balance, here or on a real pod. Raising an amount is a new invoice line; lowering one is Receivables processing that the REST surface does not expose. |
| Account activity children (all seven: receipts, applications, schedules, credit memos, credit memo applications, adjustments, transactions paid by others) | REST | `/receivablesCustomerAccountActivities/{AccountId}/child/* and /receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/*` | GET (list) | Bearer | **supported** | All seven children Oracle documents, on BOTH parents, each also embeddable with expand (or expand=all): standardReceipts, standardReceiptApplications, transactionPaymentSchedules, creditMemos, creditMemoApplications, transactionsPaidByOtherCustomers, transactionAdjustments. Each child has its OWN queryable set and its own attribute names - read the operation you are calling rather than assuming the parent's. Several attributes are derived on read (CreditMemoStatus, ReferenceTransactionStatus, PaymentDaysLate) and filter as predicates but cannot be sort keys. |
| Customer account activities (list and read) | REST | `/receivablesCustomerAccountActivities and /receivablesCustomerAccountSiteActivities` | GET (list, retrieve) | Bearer | **supported** | Both operations Oracle documents on the parent. Emits AccountId, AccountNumber, CustomerId, CustomerName, TaxpayerIdentificationNumber, TaxRegistrationNumber, audit fields, and the two aggregates - which Oracle names for the GRAIN of the resource: TotalOpenReceivablesForAccount and TotalTransactionsDueForAccount on the account resource, TotalOpenReceivablesForSite and TotalTransactionsDueForSite on the site one. The site resource also emits BillToSiteUseId. Do not carry an attribute name from one to the other. READ THE CAVEATS: both totals are amounts in the LEDGER currency (USD here), not in the invoice currency, and the resource carries no currency attribute - Oracle does not define one, because there is no ambiguity. TotalOpenReceivablesForAccount can be NEGATIVE when a customer has unapplied cash exceeding what they owe. Voided transactions are excluded, so the totals agree with receivablesInvoices for the same customer once you convert. |
| Standard receipt applications (read) | REST | `/receivablesCustomerAccountActivities/{AccountId}/child/standardReceiptApplications and the customer-account-site equivalent` | GET | Bearer | **supported** | Read-only in the 26B contract. Applications are created only by Apply Receipts Using AutoMatch; there is no POST. |
| Apply Receipts Using AutoMatch | Scheduled process | `AR_APPLY_RECEIPTS_USING_AUTOMATCH` | — | — | **supported** | Asynchronous. Runs on a recurring tenant schedule, is enqueued after a receipt is created, and can be submitted on demand from the simulator UI. Not externally submittable: no public ESS API is exposed because the exact Oracle job package and parameter list have not been verified. |
| Apply receipt action (Oracle 26C) | REST | `/standardReceipts/{id}/action/applyReceipt` | POST | — | **not_supported** | Intentionally not implemented. The applyReceipt action is Oracle 26C; this simulator targets 26B. Requests return 404. |
| Customers / Parties (TCA) | REST | `customers / partyAccounts` | — | — | **planned** |  |
| ESS jobs (BI Publisher, FBDI) | SOAP | `ErpIntegrationService` | — | — | **planned** |  |

## REST resources

### `receivablesInvoices`

Create, retrieve, list, partially update and delete Receivables (AR) invoices, read their lines and installments, and re-cut the payment schedule with the splitInstallments action. There is no completion step: an invoice is Complete when POST returns, and /action/complete answers 404 — this line said the resource completes invoices until 2026-08-04, three rows above an operations table saying the opposite.

Base path: `/fscmRestApi/resources/11.13.18.05/receivablesInvoices`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices` | supported | Returns a paged collection wrapped in the Oracle envelope (items, count, hasMore, limit, offset, links, optional totalResults). |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}` | supported | Returns a single invoice. An invoice belonging to another environment is indistinguishable from one that does not exist — both answer 404. `expand` works here exactly as it does on the collection: `expand=receivablesInvoiceLines,receivablesInvoiceInstallments`, or `expand=all`. An expanded child is byte-identical to the same row read from its own child endpoint, and a child with no rows comes back as an empty array rather than being omitted. Until 2026-08-05 this operation REFUSED expand, which was narrower than Oracle — the operation page documents it — and that refusal was published as the contract while this very example used it. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines` | supported | Adds a line to an existing invoice - Oracle's documented Create on this child, and the way an invoice's amount is RAISED. The invoice total moves by Quantity x UnitSellingPrice, and the increase is added to the last open installment so that every installment keeps its identity and any receipt applied to it is undisturbed; when every installment is already closed, a new one carries the increase. An Incomplete invoice has no schedule, so nothing is allocated and the schedule is derived when it completes. Accepts Description, Quantity, UnitSellingPrice and LineNumber; anything else is refused by name. There is no delete and no update on this child, in Oracle or here, so an amount is LOWERED with a credit memo rather than by removing a line. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines` | supported | Returns the lines for one invoice, in LineNumber order, wrapped in the same envelope as the parent list. To read a single line, use the item read below - it returns the same row this collection would, byte for byte. q filters on CustomerTransactionLineId ONLY: Oracle marks seven attributes queryable on this child and this simulator emits one of them, and - the part that matters - LineNumber, Description, Quantity, UnitSellingPrice and LineAmount are NOT queryable in Oracle. Filtering on those is refused here because it fails on a real pod too. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines/{CustomerTransactionLineId}` | supported | Returns one line of the parent invoice. The row is identical to the one the child collection returns for the same key. Oracle documents five parameters on this operation and none of the collection ones, so q, limit, offset, orderBy, finder and totalResults are refused by name here rather than ignored. Until 2026-08-10 this path was not implemented and answered 404 naming itself; before 2026-08-04 it ignored the key entirely and answered 200 with the WHOLE collection. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices` | supported | Creates a COMPLETE invoice with one or more lines, which is Oracle's default and the only value accepted on POST. Header and lines are inserted atomically; if line insertion fails the header is rolled back. The payment schedule is built server-side, so the invoice has at least one installment the moment it exists. |
| PATCH | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}` | supported | Updates exactly three attributes — InvoiceStatus, PaymentTerms and TransactionDate — which is Oracle's whole PATCH surface on this resource: "You can update only the InvoiceStatus, PaymentTerms, and TransactionDate attributes." Any other attribute in the body is refused with 400 AR-1020 naming it, never ignored. InvoiceStatus accepts Complete, Incomplete or Frozen. Changing PaymentTerms re-derives the installment schedule, and is refused when the invoice is posted to GL, has receipt applications, or the customer profile disables term overrides. This said only "updates mutable fields", which named none of them. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/action/complete` | not_supported | This action does not exist. Oracle creates receivables invoices Complete, so there is nothing to promote, and Oracle documents no complete action on this resource - only approve, rework and splitInstallments. The endpoint answers 404 like any unknown action. It was marked supported here until 2026-08-04, which put a POST .../action/complete path carrying a 200 into the published OpenAPI spec: a generated client called an endpoint that does not exist. |
| DELETE | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}` | supported | Permanently deletes the invoice together with its lines and installments. Returns 204 with NO response body. This is irreversible and there is no undo — the simulator keeps no copy. An invoice that has receipt applications is refused with 400 AR_TRX_DELETE_NOT_ALLOWED rather than silently unapplied, because deleting it would destroy the record of where a customer's money went; unapply first. Oracle states no preconditions for this operation, so that restriction is this simulator's conservative choice and is recorded as unverified. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments` | supported | Returns the payment schedules (installments) for one invoice, ordered by Sequence ascending. Every invoice has at least one installment — a single-installment invoice mirrors the invoice total and due date. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments/{InstallmentId}` | supported | Returns one installment of the parent invoice. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/action/splitInstallments` | supported | Rewrites the invoice's payment schedule and returns the NEW installment collection — not the invoice. The request body is `{ "installmentPayload": [ … ] }`; an invoice body is refused with 400. The invoice must be COMPLETE (else 409 AR-2010). Installments are matched by InstallmentSequenceNumber and updated IN PLACE, so applied receipts stay attached and APPLIED CASH IS REALLOCATED across the new amounts — it is not refused. The refusals are per INSTALLMENT, not per invoice: an installment cannot be set below what has already settled it (paid, credited or adjusted), and an installment closed BY settlement cannot have its amount or due date changed. Both answer 409 AR-2012 naming the installment. An installment closed only because it was set to zero can be changed again. An installment cannot be deleted: name every existing one and set to zero any you want emptied. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesInvoices

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | Invalid q, orderBy or finder |
| 401 | Missing or invalid bearer token |

Request:

```bash
curl --request GET \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=25&offset=0&totalResults=true" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Accept: application/json"
```

Response:

```json
{
  "items": [
    {
      "CustomerTransactionId": 300100000000001,
      "TransactionNumber": "INV-300100000000001",
      "TransactionDate": "2026-06-01",
      "BusinessUnit": "Vision Operations",
      "EnteredAmount": 1250.00,
      "InvoiceBalanceAmount": 1250.00,
      "InvoiceStatus": "Complete",
      "links": [{ "rel": "self", "href": "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001" }]
    }
  ],
  "count": 1,
  "hasMore": true,
  "limit": 25,
  "offset": 0,
  "totalResults": 80,
  "links": [{ "rel": "self", "href": "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices", "kind": "collection" }]
}
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}

Query parameters this operation implements: `fields`, `onlyData`, `links`, `expand`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | REST-01002 — CustomerTransactionId is not numeric |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 — invoice not found |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001?expand=receivablesInvoiceInstallments" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### POST /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines

| Status | Meaning |
| --- | --- |
| 201 | Created |
| 400 | Unsupported attribute, or a line not worth a positive amount |
| 401 | Missing or invalid bearer token |
| 404 | No such invoice in this environment |
| 409 | The transaction does not accept lines (a void, for example) |

Request:

```bash
curl --request POST   "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000000/child/receivablesInvoiceLines"   --header "Authorization: Bearer YOUR_ACCESS_TOKEN"   --header "Content-Type: application/json"   --data '{
    "Description": "Additional consulting",
    "Quantity": 2,
    "UnitSellingPrice": 125
  }'
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | REST-01002 — CustomerTransactionId is not numeric, or a query parameter this child does not implement was sent |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 — parent invoice not found |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines/{CustomerTransactionLineId}

Query parameters this operation implements: `fields`, `onlyData`, `links`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | REST-01002 — CustomerTransactionId or CustomerTransactionLineId is not numeric |
| 400 | REST-01003 — a query parameter this operation does not implement was sent (expand and dependency are documented by Oracle here and unimplemented) |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 / AR-7043 — invoice not found, or that line does not belong to this invoice |

##### POST /fscmRestApi/resources/11.13.18.05/receivablesInvoices

| Status | Meaning |
| --- | --- |
| 201 | Created. Carries a Location header with the canonical URI of the new invoice, and mirrors the GET response shape. |
| 400 | AR-1000 missing attributes, AR-1001 no lines, AR-1010 unknown customer, AR-1030 undefined or disabled InvoiceCurrencyCode, REST-01007 invalid JSON |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |

Request:

```bash
curl --request POST \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "BusinessUnit": "Vision Operations",
    "TransactionType": "Invoice",
    "TransactionSource": "MANUAL",
    "BillToCustomerNumber": "0001001",
    "InvoiceCurrencyCode": "USD",
    "TransactionDate": "2026-06-25",
    "PaymentTerms": "IMMEDIATE",
    "DeliveryMethod": "E-Mail",
    "BillToContact": "John Davis",
    "Email": "ap@vision-operations.example",
    "receivablesInvoiceLines": [
      { "LineNumber": 1, "Description": "Consulting", "Quantity": 10, "UnitSellingPrice": 125 }
    ]
  }'
```

Response:

```json
{
  "CustomerTransactionId": 300100000000123,
  "TransactionNumber": "INV-300100000000123",
  "InvoiceStatus": "Incomplete",
  "EnteredAmount": 1250,
  "InvoiceBalanceAmount": 1250,
  "BillToSite": "HQ — Berlin",
  "BillToContact": "John Davis",
  "DeliveryMethod": "E-Mail",
  "Email": "ap@vision-operations.example",
  "links": [{ "rel": "self", "href": "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123" }]
}
```

##### PATCH /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | AR-1020 — read-only attribute, or REST-01002 non-numeric CustomerTransactionId |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 — invoice not found |

- Updatable: InvoiceStatus, PaymentTerms, TransactionDate. Oracle 26B allows only these three; anything else returns AR-1020. Set BusinessUnit, TransactionType, TransactionSource, InvoiceCurrencyCode, BillToSite, BillToContact, DeliveryMethod and Email on create — they cannot be changed afterwards.
- Read-only: CustomerTransactionId, TransactionNumber, InvoiceBalanceAmount, EnteredAmount.
- Reassigning the bill-to customer through PATCH is not supported in this phase.
- Recipient resolution: setting Email to null with a valid BillToContact re-derives the delivery email from the contact. Setting Email explicitly always wins.
- DeliveryMethod must be one of E-Mail, Paper, XML.

Request:

```bash
curl --request PATCH \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{ "PaymentTerms": "NET30", "TransactionDate": "2026-07-25" }'
```

##### POST /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/action/complete

| Status | Meaning |
| --- | --- |
| 404 | Resource path not found — this action does not exist |

Request:

```bash
# Nothing to call. POST /receivablesInvoices already returns
# "InvoiceStatus": "Complete", with installments generated.
# The old endpoint answers 404, like any unknown action:
#
#   POST https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{id}/action/complete
#   -> 404  Resource path not found
#
# Confirm the status on the created invoice instead:
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### DELETE /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}

| Status | Meaning |
| --- | --- |
| 204 | Deleted. No response body. |
| 400 | AR_TRX_DELETE_NOT_ALLOWED — the invoice has receipt applications; or REST-01002, CustomerTransactionId is not numeric |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | REST-01003 — no such invoice in this environment |

Request:

```bash
curl --request DELETE \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | REST-01000 / REST-01002 — invalid q expression, non-queryable attribute, non-numeric CustomerTransactionId, or a query parameter this child does not implement |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 — parent invoice not found |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123/child/receivablesInvoiceInstallments" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Response:

```json
{
  "items": [
    {
      "InstallmentId": 300100000099001,
      "InstallmentSequenceNumber": 1,
      "InstallmentDueDate": "2026-07-25",
      "OriginalAmount": 500.00,
      "InstallmentBalanceDue": 0,
      "AmountPaid": 500.00,
      "InstallmentAmountAdjusted": 0,
      "InstallmentAmountCredited": 0,
      "PendingAdjustmentAmount": 0,
      "DisputeAmount": 0,
      "DisputeDate": null,
      "InstallmentStatus": "CL",
      "InstallmentClosedDate": "2026-07-10",
      "InstallmentGLClosedDate": "2026-07-10",
      "PaymentDaysLate": 0,
      "LastUpdateDate": "2026-07-10T12:00:00.000+0000"
    },
    {
      "InstallmentId": 300100000099002,
      "InstallmentSequenceNumber": 2,
      "InstallmentDueDate": "2026-08-25",
      "OriginalAmount": 500.00,
      "InstallmentBalanceDue": 500.00,
      "AmountPaid": 0,
      "InstallmentAmountAdjusted": 0,
      "InstallmentAmountCredited": 0,
      "PendingAdjustmentAmount": 0,
      "DisputeAmount": 250.00,
      "DisputeDate": "2026-07-30",
      "InstallmentStatus": "OP",
      "InstallmentClosedDate": null,
      "InstallmentGLClosedDate": null,
      "PaymentDaysLate": 0,
      "LastUpdateDate": "2026-06-25T12:00:00.000+0000"
    }
  ],
  "count": 2,
  "hasMore": false,
  "limit": 2,
  "offset": 0
}
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments/{InstallmentId}

| Status | Meaning |
| --- | --- |
| 200 | OK |
| 400 | REST-01002 — CustomerTransactionId or InstallmentId is not numeric |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 / AR-7042 — invoice or installment not found |

##### POST /fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/action/splitInstallments

| Status | Meaning |
| --- | --- |
| 200 | OK — returns the new installment collection |
| 400 | AR-1040 — invalid installment split, or a body without installmentPayload (see o:errorDetails) |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | AR-7041 — invoice not found |
| 409 | AR-2010 / AR-2012 — invalid invoice state for split |

- Sum of OriginalAmount values must equal the invoice EnteredAmount (4dp tolerance).
- Every InstallmentDueDate must be on or after the invoice TransactionDate.
- Sequence numbers must be contiguous 1..N.
- New total amount cannot be less than the amount already paid against the invoice.
- Only invoices in InvoiceStatus=Complete are eligible (AR-2010).
- Splitting is refused per INSTALLMENT rather than per invoice: an installment may not go below what has already settled it (paid, credited or adjusted), and one closed BY settlement may not change amount or due date — both 409 AR-2012, naming the installment. An invoice merely HAVING an applied receipt does not block a split; the cash is reallocated across the new amounts. This bullet said any applied receipt was refused until 2026-08-13, which was stricter than Oracle and wrong in the direction that matters: it described a guard an integrator did not need and hid the per-installment floor that actually applies.

Request:

```bash
curl --request POST \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000123/action/splitInstallments" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "installmentPayload": [
      { "InstallmentSequenceNumber": "1", "OriginalAmount": "500.00", "InstallmentDueDate": "2026-07-25" },
      { "OriginalAmount": "500.00", "InstallmentDueDate": "2026-08-25" }
    ]
  }'
```

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression (e.g. InvoiceStatus='Complete' and InvoiceBalanceAmount>0). ONLY the attributes Oracle marks queryable can be filtered: CustomerTransactionId, TransactionNumber, InvoiceStatus, InvoiceBalanceAmount, BillToPartyId, DeliveryMethod, Email, LastUpdateDate. Filtering on any other attribute is refused 400 — Oracle publishes a per-attribute queryable flag — named `queryable` in a real pod's `<resource>/describe` response, and republished here as the OpenAPI vendor extension `x-queryable` because OpenAPI requires extensions to be `x-` prefixed — and a real pod rejects the rest, so TransactionDate, DueDate, EnteredAmount, BillToCustomerNumber, InvoiceCurrencyCode, PaymentTerms, TransactionType, TransactionSource and BusinessUnit are NOT filterable here either. Supports =, !=, >, >=, <, <=, LIKE, IN and AND. Oracle documents the format as ?q=expression1;expression2 with 'and' inside an expression, and semicolon is what a real pod accepts — prefer it. OR is accepted here as a simulator extension and is NOT documented by Oracle for this resource, so a filter relying on it may not port to a real Fusion instance. A comma is not a separator in either. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered — read that rather than guessing, and note it describes THIS API: where it is narrower than Oracle the refusal message says so explicitly. | `q=InvoiceStatus='Complete';InvoiceBalanceAmount>0` |
| `fields` | Comma-separated list of fields to include in each item. | `fields=CustomerTransactionId,TransactionNumber,EnteredAmount` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=50` |
| `orderBy` | Comma-separated Field:asc\|desc list (default CustomerTransactionId:desc). | `orderBy=TransactionDate:desc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section from the response. The collection envelope stays: count, hasMore, limit, offset and totalResults are still returned. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `expand` | Comma-separated child accessors to embed. Supports `receivablesInvoiceLines` and `receivablesInvoiceInstallments`, alone or together. An unrecognised child is refused with 400 rather than silently ignored. Expanding installments is the cheapest way to tell a PAID invoice from a VOIDED one in a single call: both show InvoiceBalanceAmount 0, but only a settled invoice has AmountPaid or InstallmentAmountCredited accounting for the money. | `expand=receivablesInvoiceLines,receivablesInvoiceInstallments` |
| `finder` | Named finder. The only one implemented is PrimaryKey;CustomerTransactionId=…. Oracle documents one more on this resource, invoiceSearch, which is refused 400 naming itself as unimplemented; filter with q=TransactionNumber='…' instead. | `finder=PrimaryKey;CustomerTransactionId=300100000000001` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CustomerTransactionId` | number |  | yes | Primary key. Generated on create. |
| `TransactionNumber` | string |  | yes | Generated invoice number (INV-<CustomerTransactionId>). |
| `BusinessUnit` | string(240) | yes |  | Business unit name. Required on create. |
| `TransactionType` | string(20) | yes |  | AR transaction type name (e.g. Invoice). |
| `TransactionSource` | string(50) | yes |  | Transaction source name (e.g. MANUAL). |
| `BillToCustomerNumber` | string(30) | yes |  | Customer account number. Resolved server-side to BillToCustomerId. |
| `InvoiceCurrencyCode` | string(15) | yes |  | ISO 4217 currency code. |
| `TransactionDate` | date |  |  | yyyy-MM-dd. Defaults to today on create. |
| `PaymentTerms` | string(15) |  |  | Payment-terms name. Defaults to IMMEDIATE. |
| `DueDate` | date |  |  | yyyy-MM-dd. Optional. |
| `EnteredAmount` | number |  | yes | Sum of line extended amounts. |
| `InvoiceBalanceAmount` | number |  | yes | Equal to EnteredAmount until receipts are applied. |
| `InvoiceStatus` | string |  |  | Complete, Incomplete or Frozen. Always Complete on create - Oracle's default, and its stated rule is "Value must be Complete when creating a receivables invoice", so any other value on POST is refused. It is NOT read-only afterwards: Oracle documents it in the PATCH body, and it is the only status attribute this resource lets you change. PATCH it to any of the three values. An unrecognised value is refused rather than stored. |
| `BillToPartyId` | integer(64) |  | yes | The unique identifier of the bill-to customer assigned to the invoice. An internal identifier — never pass it as CustomerAccountNumber on a receipt. |
| `BillToCustomerName` | string(360) |  |  | The name that identifies the bill-to customer assigned to the invoice. |
| `BillToSite` | string(150) |  |  | The bill-to customer site assigned to the invoice. |
| `BillToContact` | string(360) |  |  | The contact details of the bill-to customer. This is a NAME - the resource carries no numeric contact identifier - resolved against the active contacts of the bill-to customer, and an unmatched name is rejected with AR-1031 rather than silently dropped. If omitted, an active contact on the bill-to site (or account) carrying a BILL_TO responsibility and an email address is resolved server-side. The contacts themselves are readable at /crmRestApi/resources/11.13.18.05/contacts. |
| `DeliveryMethod` | string |  |  | Invoice delivery method. Supported values: E-Mail, Paper, XML. Defaults to E-Mail when an email recipient can be resolved, otherwise Paper. |
| `Email` | string |  |  | Invoice-level delivery email override. If omitted, the resolved bill-to contact's email is used. Not required — invoices may still be created without a deliverable email (the response will reflect this). |
| `LastUpdateDate` | datetime |  | yes | Timestamp of the most recent server-side change to the invoice header or any of its child installments. Format: ISO-8601 UTC with millisecond precision and `+0000` offset (e.g. 2026-06-25T12:00:00.000+0000). Use as an incremental-sync watermark: `q=LastUpdateDate > '2026-06-25T12:00:00.000+0000'` (URL-encoded). |
| `receivablesInvoiceLines` | array<InvoiceLine> | yes |  | At least one line required on create. Each line accepts LineNumber, Description, Quantity and UnitSellingPrice. On read a line returns CustomerTransactionLineId, LineNumber, Description, Quantity, UnitSellingPrice and LineAmount (= Quantity x UnitSellingPrice, server-computed). Line-level tax is not modelled: Oracle exposes it through a receivablesInvoiceLineTaxLines child that this simulator does not implement. |
| `receivablesInvoiceInstallments` | array<InvoiceInstallment> |  | yes | The invoice's installment schedule, returned when requested with expand=receivablesInvoiceInstallments (or expand=all) and byte-identical to reading child/receivablesInvoiceInstallments. Derived from PaymentTerms on create; replace it with POST action/splitInstallments rather than by writing this array. |

Each element of `receivablesInvoiceLines`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CustomerTransactionLineId` | number |  | yes | Primary key of the line. Generated; never sent on create. |
| `LineNumber` | number |  |  | 1-based line number within the invoice. Assigned in order when omitted. |
| `Description` | string |  |  | Free-text line description. |
| `Quantity` | number |  |  | Quantity billed. |
| `UnitSellingPrice` | number |  |  | Price per unit in the invoice currency. |
| `LineAmount` | number |  | yes | Quantity x UnitSellingPrice, computed server-side. Sending it on create is refused. |

Each element of `receivablesInvoiceInstallments`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `InstallmentId` | number |  | yes | Primary key of the installment (Oracle payment_schedule_id). |
| `InstallmentSequenceNumber` | number |  | yes | 1-based installment number within the invoice. |
| `InstallmentDueDate` | date |  | yes | yyyy-MM-dd. The date this installment is due. |
| `OriginalAmount` | number |  | yes | Original installment amount. Immutable after creation. |
| `InstallmentBalanceDue` | number |  | yes | The outstanding balance on the installment: OriginalAmount less AmountPaid. NOT reduced by a dispute — see DisputeAmount. |
| `AmountPaid` | number |  | yes | Total applied to this installment from APP-status receipt applications. |
| `InstallmentAmountAdjusted` | number |  | yes | The amount that was adjusted on the installment. Always 0 here; adjustments are not implemented. |
| `InstallmentAmountCredited` | number |  | yes | The amount that was credited on the installment. This is what an approved credit memo produces, and it is a different thing from an amount in dispute. |
| `PendingAdjustmentAmount` | number |  | yes | Adjustment submitted and not yet approved. Always 0 here. |
| `DisputeAmount` | number |  | yes | The amount in dispute on the installment. May be PARTIAL, and does NOT reduce InstallmentBalanceDue: the contested money is still outstanding. Treat > 0 as a reason not to pursue collection, not as a reduction. |
| `DisputeDate` | date |  | yes | The date a dispute was recorded against the installment. Null when nothing is in dispute. |
| `InstallmentStatus` | string |  | yes | OP (open) or CL (closed). |
| `InstallmentClosedDate` | date |  | yes | Set when InstallmentBalanceDue reaches 0; cleared if a reversal re-opens it. Null while open. |
| `InstallmentGLClosedDate` | date |  | yes | General-ledger close date. Null unless the installment is closed. |
| `PaymentDaysLate` | number |  | yes | max(0, today - InstallmentDueDate) while OP; 0 once CL. Computed live on read. |
| `LastUpdateDate` | datetime |  | yes | Timestamp of the most recent server-side change to this installment. |

#### Limitations

- Receivables invoices (header, lines and installments), standard receipts and adjustments are all implemented. DISTRIBUTIONS are not exposed - accounting detail with no GL distribution model behind it. Adjustments are read-only and live on their own resource, /receivablesAdjustments, and as the transactionAdjustments child of the account-activity resources; Oracle publishes no create, update or delete for them, so that is Oracle's boundary rather than ours.
- DELETE is implemented on this resource and answers 204 with no body, as Oracle documents. An invoice carrying receipt applications is refused 400 AR_TRX_DELETE_NOT_ALLOWED rather than deleted - cascading would destroy the record of where a customer's money went. This bullet said hard delete was unsupported until 2026-08-04.
- Only the named finder PrimaryKey is implemented. Oracle documents one more on this resource, invoiceSearch, which is refused 400 naming itself as unimplemented. A third name was listed here until 2026-08-04; it was not an Oracle finder at all and has been removed - filter with q=TransactionNumber='...' instead.
- Expandable children: `receivablesInvoiceLines` and `receivablesInvoiceInstallments`, alone or together. An expanded installment is identical to one read from the dedicated child path - the same mapper produces both. An invoice with no schedule expands to an empty array rather than omitting the key, because absent and empty mean different things to a caller.
- Outbound email is not actually sent — DeliveryMethod=E-Mail is only modeled on the record. When no recipient can be resolved the response still succeeds but Email is null (the UI flags this as not deliverable).
- Installment changes are exposed only via the splitInstallments action — there are no per-installment POST / PATCH / DELETE endpoints. Closed installments cannot be modified.
- Receipt applications ARE exposed, read-only, as the standardReceiptApplications child of receivablesCustomerAccountActivities and receivablesCustomerAccountSiteActivities. There is no POST: applications are created only by Apply Receipts Using AutoMatch. This bullet said they were not exposed until 2026-08-04.

### `contacts`

Read customer contacts. Oracle Fusion FINANCIALS has no contacts resource - Oracle serves contacts from the CX family, and so does this simulator. A contact is a PERSON party with its own PartyId; email and phone are ContactPoint children, one per communication type. The Financials path /fscmRestApi/resources/.../contacts is not a resource of Oracle Financials and answers 404, exactly as a real pod does.

Base path: `/crmRestApi/resources/11.13.18.05/contacts`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/crmRestApi/resources/11.13.18.05/contacts` | supported | Returns a paged collection wrapped in the Oracle envelope (items, count, hasMore, limit, offset, links, optional totalResults). |
| GET | `/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}` | supported | Returns a single contact with its party and (if linked) customer-account context. Keyed by PartyNumber (e.g. CDRM-300100000000100), the alternate key Oracle uses on the CX item path — NOT by PartyId, which answers 404. Add ?expand=ContactPoint to embed the communication channels. |
| GET | `/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint` | supported | Returns one row per communication channel for the contact: one per EMAIL or PHONE. The same rows ?expand=ContactPoint embeds in the parent. |
| GET | `/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint/{ContactPointId}` | supported | Returns one communication channel of the contact. |

##### GET /crmRestApi/resources/11.13.18.05/contacts

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | Invalid q, finder, orderBy or other query parameter. |
| 401 | Missing or invalid bearer token, or credential issued for a different environment. |

Request:

```bash
curl --request GET \
  "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts?limit=25&totalResults=true" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Accept: application/json"
```

##### GET /crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}

Query parameters this operation implements: `fields`, `onlyData`, `links`, `expand`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 401 | Missing or invalid bearer token, or a credential issued for a different environment. |
| 404 | REST-01404 — contact not found in this environment. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/CDRM-300100000000100?expand=ContactPoint" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint

Query parameters this operation implements: `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | A query parameter this child does not implement was sent. |
| 401 | Missing or invalid bearer token, or a credential issued for a different environment. |
| 404 | REST-01404 — contact not found in this environment. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/CDRM-300100000000100/child/ContactPoint" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint/{ContactPointId}

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01400 — ContactPointId is not numeric. |
| 401 | Missing or invalid bearer token, or a credential issued for a different environment. |
| 404 | REST-01404 — contact or contact point not found in this environment. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Supported fields: PartyId, PartyNumber, ContactName, FirstName, LastName, JobTitle, EmailAddress, PartyStatus, LastUpdateDate. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered — read that rather than guessing, and note it describes THIS API: where it is narrower than Oracle the refusal message says so explicitly. | `q=PartyStatus='A'` |
| `expand` | Include the ContactPoint child inline instead of a link. | `expand=ContactPoint` |
| `fields` | Comma-separated list of fields to include in each item. | `fields=PartyNumber,ContactName,EmailAddress` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=50` |
| `orderBy` | Comma-separated Field:asc\|desc list (default PartyId:asc). | `orderBy=LastName:asc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section from the response. The collection envelope stays: count, hasMore, limit, offset and totalResults are still returned. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `finder` | Named finder, as Oracle documents them on this resource. Supported: PrimaryKey;PartyId=… and ContactPartyNumberRF;PartyNumber=…. Any other finder is refused rather than ignored. | `finder=ContactPartyNumberRF;PartyNumber=CDRM-300100000000100` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `PartyId` | number |  | yes | Primary key. The PERSON party for this contact - the contact's own party, not the customer's. |
| `PartyNumber` | string |  | yes | Alternate key, and the value the item path uses: /contacts/{PartyNumber}. NOT filterable here: Oracle marks it queryable and this simulator does not implement the filter, so q=PartyNumber=... is refused with a message saying the gap is here rather than in your query. Same for ContactName and LastUpdateDate. |
| `ContactName` | string |  | yes | Derived name of the contact. |
| `ContactUniqueName` | string |  | yes | Unique contact name shown on screens. Equal to ContactName here, because the simulator has nothing to disambiguate with. |
| `FirstName` | string |  | yes | Given name. |
| `LastName` | string |  | yes | Family name. |
| `JobTitle` | string |  | yes | Free-text job title. |
| `EmailAddress` | string |  | yes | Primary email address. The same value appears as a ContactPoint of type EMAIL. |
| `WorkPhoneNumber` | string |  | yes | Work phone. The seeded number is a work number; it also appears as a ContactPoint of type PHONE. |
| `MobileNumber` | string |  | yes | Mobile phone. Always null in this simulator - present rather than absent, because an absent attribute reads as unsupported. |
| `HomePhoneNumber` | string |  | yes | Home phone. Always null in this simulator. |
| `FaxNumber` | string |  | yes | Fax number. Always null in this simulator. |
| `PartyStatus` | string |  | yes | A (Active) or I (Inactive). An inactive contact is rejected with AR-1031 if used as BillToContact on an invoice. |
| `PartyType` | string |  | yes | Always PERSON on this resource. |
| `AccountPartyId` | number |  | yes | The customer account this person is a contact for. |
| `LastUpdateDate` | datetime |  | yes | Timestamp of the most recent server-side change to the contact. Format: ISO-8601 UTC with millisecond precision and a +0000 offset. Use as an incremental-sync watermark: q=LastUpdateDate > '2026-06-25T12:00:00.000+0000' (URL-encoded). This resource carried no watermark at all until 2026-08-05, so a consumer had to re-read every contact on every pull. |
| `ContactPoint` | array<object> |  | yes | Child collection, one row per communication channel. Present only when ?expand=ContactPoint was sent — a contact read without it carries no ContactPoint key at all. Also readable at /contacts/{PartyNumber}/child/ContactPoint. |

Each element of `ContactPoint`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ContactPointId` | number |  | yes | Primary key of the channel. This identifies the CHANNEL, not the person — the person is PartyNumber on the parent. |
| `ContactPointType` | string |  | yes | EMAIL or PHONE. |
| `EmailAddress` | string |  | yes | Populated when ContactPointType is EMAIL, otherwise null. |
| `RawPhoneNumber` | string |  | yes | Populated when ContactPointType is PHONE, otherwise null. |
| `FormattedPhoneNumber` | string |  | yes | Display form of RawPhoneNumber. Null for an EMAIL channel. |
| `PrimaryFlag` | boolean |  | yes | True when this is the primary channel of its type. |
| `Status` | string |  | yes | A (active) or I (inactive). |
| `CreatedBy` | string |  | yes | Audit user that created the row. |
| `CreationDate` | datetime |  | yes | Audit creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit user of the most recent change. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

#### Limitations

- Read-only in this phase: POST/PATCH/DELETE are not implemented.
- Only the named finders PrimaryKey and ContactPartyNumberRF are implemented. Oracle documents four more on this resource — MyContacts, MyBusinessContacts, MyFavoriteContacts and SourceSystemReferenceAltKey — and each is refused 400 naming the finder rather than ignored.
- The ContactPoint child IS exposed: GET https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint and .../ContactPoint/{ContactPointId}, and ?expand=ContactPoint embeds it in the parent. This bullet said no child collections were exposed until 2026-08-04 - it predates the move to the CX base, where the channels ARE the child. It is the only child on this resource.

### `standardReceipts`

Record a payment collected outside the application. The external platform creates a Standard Receipt carrying remittance references that identify the transaction being paid; a separate asynchronous process, Apply Receipts Using AutoMatch, decides what it applies to. Creating a receipt never applies it.

Base path: `/fscmRestApi/resources/11.13.18.05/standardReceipts`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| POST | `/fscmRestApi/resources/11.13.18.05/standardReceipts` | supported | Validates the request, creates the receipt and any nested remittance references, commits, and returns. The receipt is left UNAPPLIED, or UNIDENTIFIED when no customer information was supplied, and becomes eligible for the next Apply Receipts Using AutoMatch run. No application is made during this request. |
| GET | `/fscmRestApi/resources/11.13.18.05/standardReceipts` | supported | Returns a paginated collection with the standard Oracle envelope: items, count, hasMore, limit, offset, links. |
| GET | `/fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}` | supported | Returns a single receipt. The remittanceReferences child is a LINK by default and is embedded only when ?expand=remittanceReferences is sent, as on the collection. This said the item read returns the receipt "with its remittance references", which described the behaviour before the unconditional inlining was removed — a real pod returns a link. |
| PATCH | `/fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}` | supported | Updates customer detail attributes only: CustomerAccountNumber, CustomerBankAccountNumber, CustomerName, CustomerSite. Any other attribute is rejected. Assigning a customer to an UNIDENTIFIED receipt moves the amount from unidentified to unapplied and makes it eligible for AutoMatch. |
| DELETE | `/fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}` | supported | Deletes a receipt that is still eligible for deletion. |
| POST | `/fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}/child/remittanceReferences` | supported | Adds a remittance reference to an existing receipt, and returns the created reference with a Location header. The same objects can be supplied nested inside the original receipt POST under `remittanceReferences`. Adding one makes the receipt eligible for the next Apply Receipts Using AutoMatch run; it does not apply anything itself. |
| GET | `/fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}/child/remittanceReferences` | supported | Returns the remittance references on a receipt, in RemittanceReferenceId order. |
| GET | `/fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}/child/remittanceReferences/{RemittanceReferenceId}` | supported | Returns a single remittance reference of the parent receipt. |

##### POST /fscmRestApi/resources/11.13.18.05/standardReceipts

| Status | Meaning |
| --- | --- |
| 201 | Created. State is UNAPPLIED, or UNIDENTIFIED when no customer information was supplied. |
| 400 | Validation failure. See o:errorCode for the Oracle condition. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | Missing the AR_CREATE_RECEIVABLES_RECEIPT_PRIV privilege. |

- Requires the AR_CREATE_RECEIVABLES_RECEIPT_PRIV privilege.
- A duplicate receipt number, date, amount and customer returns AR_RCP_DUP_NUM. Send Upsert-Mode: true to receive the existing receipt instead.
- InstallmentId, PaymentScheduleId and InstallmentNumber are not part of the request and are rejected.
- Provider-specific attributes such as externalPaymentId or paymentId are rejected. Carry your reference in ReceiptNumber, StructuredPaymentReference, Comments or a flexfield.

Request:

```bash
curl -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
  "ReceiptNumber": "PAY-20260728-001",
  "ReceiptMethod": "Manual",
  "BusinessUnit": "Vision Operations",
  "CustomerAccountNumber": "0001001",
  "CustomerSite": "HQ — Berlin",
  "Amount": 500.00,
  "Currency": "USD",
  "ReceiptDate": "2026-07-28",
  "AccountingDate": "2026-07-28",
  "StructuredPaymentReference": "pi_3ABC123",
  "remittanceReferences": [
    {
      "ReceiptMatchBy": "Transaction Number",
      "ReferenceNumber": "INV-300100000000001",
      "ReferenceAmount": 500.00
    }
  ]
}'
```

Response:

```json
{
  "StandardReceiptId": 300100169169023,
  "ReceiptNumber": "PAY-20260728-001",
  "ReceiptMethod": "Manual",
  "BusinessUnit": "Vision Operations",
  "CustomerAccountNumber": "0001001",
  "CustomerSite": "HQ — Berlin",
  "Amount": 500.00,
  "Currency": "USD",
  "ReceiptDate": "2026-07-28",
  "State": "UNAPPLIED",
  "Status": "CONFIRMED",
  "UnappliedAmount": 500.00,
  "StructuredPaymentReference": "pi_3ABC123",
  "remittanceReferences": [
    {
      "RemittanceReferenceId": 300100153164605,
      "ReceiptMatchBy": "Transaction Number",
      "ReferenceNumber": "INV-300100000000001",
      "ReferenceAmount": 500.00
    }
  ],
  "links": []
}
```

##### GET /fscmRestApi/resources/11.13.18.05/standardReceipts

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | Malformed q expression or unknown field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |

##### GET /fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}

Query parameters this operation implements: `fields`, `onlyData`, `links`, `expand`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | REST-01400 — StandardReceiptId is not numeric. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |
| 404 | No such receipt in this environment. |

##### PATCH /fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}

| Status | Meaning |
| --- | --- |
| 200 | Updated. |
| 400 | Attribute not updatable, or the receipt is in a state that blocks customer updates. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |
| 404 | No such receipt. |

- Blocked on applied, approved, reversed, automatic, AP/AR netting, bill-to receivables, frozen and unaccounted receipts. Note the sequencing this implies: a receipt whose remittance reference matches an open transaction is applied by the next AutoMatch sweep, which can happen within seconds of the POST. "Create a receipt then PATCH its customer details" therefore reads as safe and is not — patch it before it is applied, or create it without a matching reference.
- Amount, State, Status, UnappliedAmount and StandardReceiptId are never client-writable.

Request:

```bash
curl -X PATCH "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts/300100169169023" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{
  "CustomerAccountNumber": "0001001",
  "CustomerSite": "HQ — Berlin"
}'
```

##### DELETE /fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}

| Status | Meaning |
| --- | --- |
| 204 | Deleted. No response body. |
| 400 | The receipt is not eligible for deletion. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |
| 404 | No such receipt. |

- A receipt with applications, or one that is accounted, frozen, reversed or automatic, cannot be deleted.
- The receipt is never silently reversed or unapplied to make it deletable.

##### POST /fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}/child/remittanceReferences

| Status | Meaning |
| --- | --- |
| 201 | Created. Carries a Location header with the canonical URI of the new reference. |
| 400 | Validation failure, for example ReferenceNumber longer than 50 characters. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_CREATE_RECEIVABLES_RECEIPT_PRIV. |
| 404 | No such receipt. |

Request:

```bash
curl -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts/300100169169023/child/remittanceReferences" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{
  "ReceiptMatchBy": "Transaction Number",
  "ReferenceNumber": "INV-300100000000001",
  "ReferenceAmount": 500.00
}'
```

##### GET /fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}/child/remittanceReferences

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | Malformed q expression, a non-queryable attribute, or a query parameter this child does not implement. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |
| 404 | No such receipt. |

##### GET /fscmRestApi/resources/11.13.18.05/standardReceipts/{StandardReceiptId}/child/remittanceReferences/{RemittanceReferenceId}

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | REST-01400 — StandardReceiptId or RemittanceReferenceId is not numeric. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_MANAGE_RECEIVABLES_RECEIPT_PRIV. |
| 404 | No such reference. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Filter expression. ONLY the attributes Oracle marks queryable can be filtered: StandardReceiptId, ReceiptNumber, ReceiptDate, CustomerAccountNumber, CustomerName, CustomerSite, BusinessUnit — all seven Oracle marks. The last three are NAMES on the wire and identifiers in the column, so each is resolved before it filters; an unknown name yields an empty collection rather than an error, and none of the three may be combined with OR. Anything else is refused 400 — Oracle publishes a per-attribute queryable flag — named `queryable` in a real pod's `<resource>/describe` response, and republished here as the OpenAPI vendor extension `x-queryable` because OpenAPI requires extensions to be `x-` prefixed — and a real pod rejects the rest, so State, Status, Amount, Currency, UnappliedAmount, ReceiptMethod, AccountingDate, Comments, DocumentNumber, MaturityDate, PostmarkDate, CreationDate, StructuredPaymentReference and LastUpdateDate are NOT filterable. Note the asymmetry with invoices: LastUpdateDate IS queryable there and is not here, so receipts have no watermark-based incremental sync in Oracle. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered — read that rather than guessing, and note it describes THIS API: where it is narrower than Oracle the refusal message says so explicitly. | `q=CustomerAccountNumber='0001001'` |
| `finder` | Named finder, as documented by Oracle for this resource. PrimaryKey;StandardReceiptId=<id> finds one receipt by key. StandardReceiptsFinder;<var>=<val>[,<var>=<val>] searches; supported variables here are ReceiptNumber, ReceiptDate and CustomerAccountNumber. Oracle also documents BusinessUnit, CustomerName and CustomerSite on that finder — those are not implemented here and are rejected by name rather than ignored. An unsupported finder or variable returns 400, never a silently unfiltered collection. | `finder=StandardReceiptsFinder;ReceiptNumber=FIN-0001` |
| `fields` | Comma-separated attribute projection. | `fields=StandardReceiptId,ReceiptNumber,State` |
| `expand` | Expand the remittanceReferences child collection. | `expand=remittanceReferences` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=50` |
| `orderBy` | Sort specification. | `orderBy=ReceiptDate:desc` |
| `onlyData` | Strip links and envelope metadata. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `totalResults` | Include the total row count. | `totalResults=true` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `StandardReceiptId` | integer(64) |  | yes | System-generated receipt identifier. |
| `ReceiptNumber` | string(30) |  |  | Receipt number. Optional; derive a stable unique value from your payment reference so a retry is detected as a duplicate. |
| `ReceiptMethod` | string | yes |  | Configured receipt method name. |
| `BusinessUnit` | string(240) | yes |  | Configured business unit name. |
| `Amount` | number | yes |  | Receipt amount in Currency. Must be positive. |
| `Currency` | string(3) | yes |  | Configured currency code. |
| `ReceiptDate` | date | yes |  | Date the payment was received (YYYY-MM-DD). |
| `AccountingDate` | date |  |  | Accounting date; defaults to ReceiptDate. |
| `CustomerAccountNumber` | string(30) |  |  | Customer account. Omit to create an unidentified receipt. |
| `CustomerName` | string(360) |  |  | Customer name. |
| `CustomerSite` | string(150) |  |  | Customer site (bill-to location). |
| `CustomerBankAccountNumber` | string(30) |  |  | Customer bank account number. |
| `State` | string |  | yes | Application dimension: APPLIED, UNAPPLIED, UNIDENTIFIED, INSUFFICIENT FUNDS, REVERSE PAYMENT, STOP PAYMENT. |
| `Status` | string |  | yes | Lifecycle dimension: CONFIRMED, CLEARED, APPROVED, REMITTED. Separate from State: CONFIRMED does not mean the invoice is paid. |
| `UnappliedAmount` | number |  | yes | Amount not yet applied to any transaction. |
| `StructuredPaymentReference` | string |  |  | Structured payment reference. A common place to carry an external payment identifier. |
| `DocumentNumber` | string(30) |  |  | Document number. |
| `Comments` | string |  |  | Free-text comments. |
| `MaturityDate` | date |  |  | Maturity date. |
| `PostmarkDate` | date |  |  | Postmark date. |
| `ConversionDate` | date |  |  | Currency conversion date. |
| `ConversionRate` | number |  |  | Currency conversion rate. |
| `ConversionRateType` | string(30) |  |  | Currency conversion rate type. |
| `RemittanceBankAccountNumber` | string |  |  | Remittance bank account number. Writable: it is how you name the account, and the bank and branch names below are resolved from it. |
| `RemittanceBankName` | string(360) |  | yes | The remittance bank's name, RESOLVED from RemittanceBankAccountNumber rather than sent. Read-only in Oracle and here - supply the account number and read this back. Null when the receipt names no remittance account, or names one this environment has not configured. |
| `RemittanceBankBranch` | string(360) |  | yes | The remittance bank's branch name, resolved the same way as RemittanceBankName and equally read-only. |
| `RemittanceBankAllowOverride` | boolean |  |  | Whether the remittance bank may be overridden. |
| `RemittanceBankDepositDate` | date |  |  | Remittance bank deposit date. |
| `CardHolderFirstName` | string |  |  | Card holder first name. |
| `CardHolderLastName` | string |  |  | Card holder last name. |
| `CreditCardTokenNumber` | string |  |  | Tokenised card reference. Never send a full card number. |
| `CreditCardExpirationDate` | date |  |  | Card expiration date. |
| `CreditCardIssuerCode` | string(30) |  |  | Card issuer code. |
| `CreditCardAuthorizationRequestIdentifier` | integer |  |  | Card authorization request identifier. Oracle types this as an integer, so it holds a numeric authorization request id — not a payment-processor reference. A processor identifier such as a Stripe ch_/pi_ value is not numeric and real Oracle rejects it: put it in StructuredPaymentReference instead. This simulator's column is text and will accept a non-numeric value, which is laxer than Oracle; do not rely on that. |
| `VoiceAuthorizationCode` | string(30) |  |  | Voice authorization code. |
| `standardReceiptDFF` | object |  |  | Descriptive flexfield payload. |
| `standardReceiptGdf` | object |  |  | Global descriptive flexfield payload. |
| `remittanceReferences` | array<RemittanceReference> |  |  | Remittance references identifying what the payment is for. Accepted nested on create, and returned inline when ?expand=remittanceReferences is sent. A receipt with no reference can still be created; AutoMatch will have nothing to match it on. Also writable afterwards at /standardReceipts/{StandardReceiptId}/child/remittanceReferences. |
| `CreatedBy` | string |  | yes | Audit: creating principal. |
| `CreationDate` | datetime |  | yes | Audit: creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit: last updating principal. |
| `LastUpdateDate` | datetime |  | yes | Audit: last update timestamp. |

Each element of `remittanceReferences`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `RemittanceReferenceId` | number |  | yes | Primary key of the reference. Generated; read-only, and sending it is refused 400. |
| `ReceiptMatchBy` | string |  |  | What ReferenceNumber names. One of: Transaction Number, Balance Forward Billing Number, Contract Number, Purchase Order, Sales Order, Shipping Reference. Defaults to Transaction Number when omitted; any other value is refused 400. Only Transaction Number is resolved against invoices by AutoMatch. |
| `ReferenceNumber` | string |  |  | The customer's reference, e.g. the invoice number being paid. Max 50 characters. AutoMatch matches on this; a reference without it can never match. |
| `ReferenceAmount` | number |  |  | Amount the payer attributed to this reference, in the parent receipt's currency. Omit to let AutoMatch allocate from the receipt amount. An amount the currency cannot express is refused 400. |
| `CustomerReason` | string |  |  | Free-text reason supplied by the payer. |
| `CustomerReference` | string |  |  | Free-text reference supplied by the payer. |
| `CreatedBy` | string |  | yes | Audit user that created the row. |
| `CreationDate` | datetime |  | yes | Audit creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit user of the most recent change. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

#### Limitations

- Creating a receipt does not apply it. Applications appear only after Apply Receipts Using AutoMatch has run.
- The request cannot target a specific installment; that is not a supported Oracle 26B REST capability.
- PATCH and DELETE are not offered on remittanceReferences: not confirmed as supported by Oracle 26B.
- The Oracle 26C /standardReceipts/{id}/action/applyReceipt action is intentionally not implemented and returns 404.

### `receivablesCreditMemos`

Oracle's credit memos. Read-only here. Credit memos share the {CustomerTransactionId} id space with invoices and live alongside them, but Oracle serves them as a SEPARATE resource with its own attribute names - so a credit memo never appears under /receivablesInvoices, and reading one there answers 404. If you are reconciling a customer's balance, sync both resources.

Base path: `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos` | supported | Creates a credit memo. Oracle marks three attributes required - BusinessUnit, TransactionDate and TransactionNumber - and the last is worth noting: a credit memo carries a number the CALLER supplies, where /receivablesInvoices generates one. BillToCustomerNumber is required here although Oracle marks it optional, because every transaction in this simulator is owned by a customer account and neither BillToCustomerName nor a site is modelled as a way to find one. Lines arrive as receivablesCreditMemoLines and each needs a positive LineAmountCredit. Note the names: a credit memo line is NOT an invoice line renamed - it is LineDescription where an invoice has Description, LineAmountCredit where an invoice has LineAmount, and LineQuantityCredit where an invoice has Quantity. Only LineNumber is required. EnteredAmount is derived from the lines and is read-only, exactly as an invoice's total is, and the header and its lines are written in one transaction so a memo can never exist without what its amount is made of. CreditMemoStatus is Complete on creation, which is Oracle's documented default. The memo is created UNAPPLIED and nothing here applies it to an invoice - Oracle publishes no REST operation that does, so there is no attribute for it in this body or in Oracle's. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos` | supported | Returns a paged collection wrapped in the Oracle envelope (items, count, hasMore, limit, offset, links, optional totalResults). Only credit memos - invoices are served by /receivablesInvoices and the two collections do not overlap. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}` | supported | Returns a single credit memo. An INVOICE id answers 404 here rather than returning the row under credit memo attribute names - the id space is shared, the resources are not. `expand=receivablesCreditMemoLines` (or `expand=all`) embeds the lines, and an unrecognised child is refused by name rather than dropped; a memo with no lines expands to an empty array, because absent and empty mean different things to a caller. |
| PATCH | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}` | supported | Updates CreditMemoStatus, RecipientEmail or TransactionType. Unlike receivablesInvoices, Oracle states no "you can update only ..." restriction here; its request body also lists AllowCompletion and ControlCompletionReason, which belong to a transaction approval workflow this simulator does not model and are refused BY NAME rather than stored - a value nothing acts on reads back as though it took effect. CreditMemoStatus accepts Complete, Incomplete or Frozen and refuses anything else. TransactionType must stay Credit Memo: credit memos and invoices are one table split by that column, so changing it would move the row into /receivablesInvoices and out of this resource. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines` | supported | The lines of one credit memo, in LineNumber order, wrapped in the Oracle envelope. Attribute names are the credit memo's own: LineDescription, LineAmountCredit and LineQuantityCredit, not the invoice resource's Description, LineAmount and Quantity. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines/{CustomerTransactionLineId}` | supported | One line by its key, returning exactly the row the child collection would return for it. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines` | supported | Adds lines to an existing credit memo. Oracle's own wording is "create a SET of lines", and the body is an array; a single object is accepted as a set of one. The credit memo's EnteredAmount is re-derived from every line afterwards, in the same statement, so the header cannot drift from what it is made of. Oracle publishes no update and no delete on this child, and neither does this simulator. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/action/approve` | not_supported | Oracle documents approve and rework actions for credit memos pending approval. No approval workflow is modelled here, so both answer 404 naming the action. The seven child collections Oracle documents (lines, distributions, attachments, notes and three flexfield children) are likewise not modelled and answer 404. |

##### POST /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos

| Status | Meaning |
| --- | --- |
| 201 | Created. |
| 400 | Missing or unsupported attribute, or a line without a positive Amount. |
| 401 | Missing or invalid bearer token. |

Request:

```bash
curl --request POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos"   --header "Authorization: Bearer YOUR_ACCESS_TOKEN"   --header "Content-Type: application/json"   --data '{
    "BusinessUnit": "Vision Operations",
    "TransactionDate": "2026-08-12",
    "TransactionNumber": "CM-EXTERNAL-1001",
    "BillToCustomerNumber": "0001001",
    "CreditMemoCurrency": "USD",
    "CreditReason": "Damaged goods",
    "receivablesCreditMemoLines": [
      { "LineNumber": 1, "LineAmountCredit": 250, "LineDescription": "Damaged goods" }
    ]
  }'
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `orderBy`, `totalResults`, `onlyData`, `links`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | Invalid q, finder or orderBy, or a filter on an attribute that is not queryable. |
| 401 | Missing or invalid bearer token. |

Request:

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos"   --data-urlencode "q=BillToCustomerNumber='1004'"   --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}

Query parameters this operation implements: `fields`, `onlyData`, `links`, `expand`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | CustomerTransactionId is not numeric. |
| 401 | Missing or invalid bearer token. |
| 404 | No credit memo with that id in this tenant - including when the id is a valid invoice. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/300100000000073"   --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### PATCH /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}

| Status | Meaning |
| --- | --- |
| 200 | Updated. The response is the credit memo as a GET would return it. |
| 400 | Unsupported attribute, an unmodelled workflow attribute, or an unrecognised status. |
| 401 | Missing or invalid bearer token. |
| 404 | No such credit memo in this environment. |

Request:

```bash
curl --request PATCH "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/300100000000073" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{ "CreditMemoStatus": "Incomplete" }'
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines

Query parameters this operation implements: `limit`, `offset`, `totalResults`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 401 | Missing or invalid bearer token. |
| 404 | No such credit memo in this environment. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines/{CustomerTransactionLineId}

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 401 | Missing or invalid bearer token. |
| 404 | No such credit memo, or no such line on it. |

##### POST /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/child/receivablesCreditMemoLines

| Status | Meaning |
| --- | --- |
| 201 | Created. |
| 400 | Unsupported attribute, or a line without a positive LineAmountCredit. |
| 401 | Missing or invalid bearer token. |
| 404 | No such credit memo in this environment. |

Request:

```bash
curl --request POST \
  "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/300100000000073/child/receivablesCreditMemoLines" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '[{ "LineNumber": 2, "LineAmountCredit": 40, "LineDescription": "Freight credit" }]'
```

##### POST /fscmRestApi/resources/11.13.18.05/receivablesCreditMemos/{CustomerTransactionId}/action/approve

| Status | Meaning |
| --- | --- |
| 404 | Documented by Oracle, not implemented here. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Nine attributes are filterable here: CustomerTransactionId, TransactionNumber, TransactionDate, TransactionType, TransactionSource, BusinessUnit, CreditMemoCurrency, BillToCustomerNumber and BillToSite. Oracle marks fifteen, and the six this simulator does not model - AllowCompletion, CrossReference, DocumentNumber, PrimarySalesperson, PurchaseOrder and PurchaseOrderDate - are refused by name with the reason. Note that EnteredAmount, TransactionBalanceDue and CreditMemoCurrency are NOT symmetrical: the currency filters, the two amounts do not, because Oracle does not mark them queryable. Filtering on BillToCustomerNumber or BillToSite matches on the value you see on the wire - the account number and the site name - not on an internal id. | `q=BillToCustomerNumber='1004'` |
| `fields` | Comma-separated list of fields to include in each item. | `fields=CustomerTransactionId,TransactionNumber,TransactionBalanceDue` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 - read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. Page by adding the returned `limit` until `hasMore` is false. | `offset=25` |
| `orderBy` | Comma-separated Field:asc\|desc list (default CustomerTransactionId:desc). BillToCustomerNumber and BillToSite are refused as sort keys: they are resolved from other tables on read, so sorting would order by the underlying id while showing you a name. | `orderBy=TransactionDate:desc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array. A relation the response does not carry is simply absent. | `links=self` |
| `finder` | Named finder. PrimaryKey;CustomerTransactionId=... is implemented. Oracle also documents creditMemosFinder, which this simulator does not implement - it is refused by name rather than reported as unknown, so you can tell a missing feature from a typo. | `finder=PrimaryKey;CustomerTransactionId=300100000000073` |
| `expand` | Comma-separated child accessors to embed on the ITEM read. `receivablesCreditMemoLines` is the one child this resource models, and `all` is accepted for it. An unrecognised child is refused 400 rather than silently ignored, because accepted-and-dropped is indistinguishable from honoured when all you see is a 200. A credit memo with no lines expands to an empty array rather than omitting the key. | `expand=receivablesCreditMemoLines` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CustomerTransactionId` | number |  | yes | Primary key. Shared id space with invoices: an id is either an invoice or a credit memo, never both. |
| `TransactionNumber` | string(20) |  | yes | The credit memo number. This is the identifier to reconcile on. |
| `TransactionDate` | date |  | yes | The credit memo date, YYYY-MM-DD. |
| `TransactionType` | string(20) |  | yes | The transaction type. Always 'Credit Memo' on this resource - it is queryable in Oracle and therefore filterable here, but it cannot select anything else. |
| `TransactionSource` | string(50) |  | yes | The batch source the credit memo was created under. |
| `BusinessUnit` | string(240) |  | yes | The business unit name. |
| `CreditMemoCurrency` | string(15) |  | yes | Currency code. Oracle's name for it on THIS resource; the invoice resource calls the same concept InvoiceCurrencyCode. |
| `EnteredAmount` | number |  | yes | The credit memo amount, stored POSITIVE. The crediting sense lives in the application, exactly as receipt applications work - do not assume a negative number. |
| `TransactionBalanceDue` | number |  | yes | The unapplied balance remaining on the credit memo. Zero once fully applied against transactions. |
| `BillToCustomerNumber` | string(30) |  | yes | The bill-to customer's ACCOUNT NUMBER, resolved on read. This is the value you pass back as CustomerAccountNumber when recording a receipt. |
| `BillToCustomerName` | string(360) |  | yes | The bill-to customer's account name, resolved on read. Not queryable in Oracle. |
| `BillToSite` | string(150) |  | yes | The bill-to site name, resolved on read. Null when the credit memo sits at the account level rather than a site. |
| `BillToContact` | string(160) |  | yes | The bill-to contact's name, resolved on read from the contact recorded on the transaction. Null when no contact is set. |
| `CreditMemoStatus` | string |  | yes | The level of completion of the credit memo. Oracle documents exactly three values, and this resource emits them: Complete, Incomplete, Frozen (default Complete). Not filterable - Oracle does not mark it queryable here, unlike InvoiceStatus on receivablesInvoices. |
| `RecipientEmail` | string(1000) |  | yes | Email address of the customer contact who receives printed transactions. The invoice resource calls the same value Email; this resource's name for it is RecipientEmail. |
| `CreditReason` | string(255) |  |  | Oracle: "Reason the credit memo was created or applied." Sent on create and returned on read. Oracle documents no allowed-value list, so any text is accepted rather than validated against a set this simulator would have invented. |
| `DeliveryMethod` | string(30) |  | yes | The delivery method recorded on the transaction. |
| `CreationDate` | datetime |  | yes | When the credit memo was created. Oracle wire format. |
| `LastUpdateDate` | datetime |  | yes | When the credit memo was last updated. Oracle wire format. Maintained by the database, not settable. |

#### Limitations

- POST, PATCH and the receivablesCreditMemoLines child are implemented. The approve/rework actions and the other six children Oracle documents are not, each refused by name rather than reported as unknown. Applying a credit memo to an invoice is absent because Oracle publishes no REST operation for it - not because it was skipped.
- Fifty-one of the attributes Oracle documents are not emitted - freight, tax registration, printing, conversion rates, ship-to and the five child collections. Each is declared with its reason in the attribute-coverage module rather than left as an unexplained absence.
- Six attributes Oracle marks queryable are not modelled: AllowCompletion, CrossReference, DocumentNumber, PrimarySalesperson, PurchaseOrder and PurchaseOrderDate. A filter on any of them is refused with the reason.
- The amount is stored positive. Whether Oracle carries a credit memo amount as a negative number could not be confirmed, so the crediting sense lives in the application rather than in the sign.

### `receivablesAdjustments`

Oracle's receivables adjustments - a manual increase or decrease applied to a transaction or one of its installments. READ-ONLY, and that is Oracle's design rather than a gap here: Oracle publishes only Get all and Get one, with no create, update or delete. Read together with the fact that Oracle publishes no operation to APPLY a credit memo, it means there is no published REST call that lowers a transaction's balance - here or on a real pod. Adjustments are Receivables processing that the REST surface reports and does not accept. The same rows are also visible per customer through the transactionAdjustments child of the account-activity resources, which is a narrower window on the same entity.

Base path: `/fscmRestApi/resources/11.13.18.05/receivablesAdjustments`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesAdjustments` | supported | Returns a paged collection wrapped in the Oracle envelope (items, count, hasMore, limit, offset, links, optional totalResults). Scoped to your tenant. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesAdjustments/{AdjustmentId}` | supported | Returns a single adjustment. One belonging to another tenant is indistinguishable from one that does not exist: both answer 404. |
| POST | `/fscmRestApi/resources/11.13.18.05/receivablesAdjustments` | not_supported | Oracle documents no create, update or delete operation for adjustments. This is not a gap in the simulator: op-receivablesadjustments-post.html does not exist, while the GET page on the identical URL shape does, so the absence is Oracle's. Anything other than GET answers 405 naming the two operations that exist. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesAdjustments

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | Invalid q, finder or orderBy, or a filter on a non-queryable attribute. |
| 401 | Missing or invalid bearer token. |

Request:

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesAdjustments" \
  --data-urlencode "q=TransactionClass='Invoice'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesAdjustments/{AdjustmentId}

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | AdjustmentId is not numeric, or expand names a child that cannot be expanded. |
| 401 | Missing or invalid bearer token. |
| 404 | No adjustment with that id in this tenant. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesAdjustments/300100000000002" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### POST /fscmRestApi/resources/11.13.18.05/receivablesAdjustments

| Status | Meaning |
| --- | --- |
| 405 | Oracle publishes only Get all and Get one on this resource. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Supported fields are exactly the six Oracle marks x-queryable: AdjustmentId, AdjustmentNumber, BillToSiteUseId, CustomerTransactionId, TransactionClass, TransactionNumber. A filter on any other attribute is refused 400 by name with the reason - including attributes this resource emits, such as Status and AdjustmentType, which Oracle does not mark queryable and which a real pod refuses too. | `q=TransactionClass='Invoice'` |
| `finder` | Oracle documents one finder on this resource: PrimaryKey;AdjustmentId=<id>. Any other finder is refused 400. | `finder=PrimaryKey;AdjustmentId=300100000000002` |
| `orderBy` | Sort key and direction. AdjustmentId, AdjustmentNumber, BillToSiteUseId and CustomerTransactionId sort. TransactionNumber and TransactionClass FILTER but do not SORT: they live on the adjusted transaction, and ordering on a joined column does not reorder adjustments. Asking to sort by one is refused rather than silently ignored. | `orderBy=AdjustmentId:desc` |
| `fields` | Comma-separated list of fields to include in each item. | `fields=AdjustmentId,AdjustmentAmount,Status` |
| `limit` | Page size. Default 25. | `limit=50` |
| `offset` | Zero-based row offset for paging. | `offset=25` |
| `totalResults` | Set true to include totalResults in the envelope. | `totalResults=true` |
| `onlyData` | Set true to omit the links section. | `onlyData=true` |
| `links` | Comma-separated link relations to keep. | `links=self` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `AdjustmentId` | number |  | yes | Primary key. The identifier of the adjustment. |
| `AdjustmentNumber` | string(20) |  | yes | The number assigned to the adjustment. |
| `AdjustmentAmount` | number |  | yes | The amount adjusted. |
| `AdjustmentType` | string(80) |  | yes | What part of the transaction is adjusted. Oracle's values: Charges, Freight, Invoice (transaction header), Line, Tax. |
| `AdjustmentReason` | string(80) |  | yes | The reason code assigned to the adjustment. Oracle publishes no fixed list - reason codes are customer-defined lookups. |
| `AdjustmentDate` | date |  | yes | The date of the adjustment. |
| `AccountingDate` | date |  | yes | The accounting date of the adjustment. |
| `Status` | string(80) |  | yes | The adjustment's approval status. Oracle's values: Pending Approval, Approved, Rejected, More Research - decided by the approval limits for the item's currency. Only an Approved adjustment moves a transaction balance. |
| `CustomerTransactionId` | number |  | yes | The adjusted transaction. |
| `TransactionNumber` | string |  | yes | The adjusted transaction's number. |
| `TransactionClass` | string |  | yes | The transaction class of the adjusted transaction. Oracle's values: Invoice, Debit Memo, Credit Memo. Null where the transaction's type is not one of those three - a voided transaction has no Oracle class, and emitting one would teach a value a real pod never sends. |
| `BillToSiteUseId` | number |  | yes | The bill-to site business purpose associated with the adjustment. |
| `Currency` | string(15) |  | yes | The adjustment's currency code. |
| `BusinessUnit` | string(240) |  | yes | The business unit of the adjusted transaction. |
| `InstallmentNumber` | number |  | yes | The adjusted installment's number. Null for a header-level adjustment. |
| `InstallmentBalance` | number |  | yes | The adjusted installment's remaining balance. |
| `CreatedBy` | string |  | yes | Who created the adjustment. |
| `CreationDate` | datetime |  | yes | When it was created. Oracle wire format. |
| `LastUpdatedBy` | string |  | yes | Who last updated it. |
| `LastUpdateDate` | datetime |  | yes | When it was last updated. Oracle wire format. |

#### Limitations

- Six of the twenty-six attributes Oracle documents are not emitted: AccountCombination, AccountedAmount, ApprovedBy, Comments, ReceivablesActivity and the receivablesAdjustmentDFF child. Each is declared with its reason in the attribute-coverage module.
- The one child Oracle documents, receivablesAdjustmentDFF, is not implemented: no descriptive flexfield contexts are defined anywhere in this simulator. Asking to expand it is refused rather than answered with an empty array, because empty would assert the adjustment genuinely has no flexfield values.
- This resource is not privilege-gated. Oracle guards its resources with named functional privileges and does not state which one guards this resource; gating on a plausible name would be an invented requirement that answers 403 where a real pod may answer 200.

### `receiptMethods`

Oracle's receipt methods. Read-only. Use it to discover the exact values accepted as ReceiptMethod when creating a standard receipt - posting a method that is not configured for your tenant is rejected with AR_INVAL_RECEIPT_MTH_ID, and this resource is how you find the accepted set.

Base path: `/fscmRestApi/resources/11.13.18.05/receiptMethods`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/fscmRestApi/resources/11.13.18.05/receiptMethods` | supported | Returns a paged collection wrapped in the Oracle envelope (items, count, hasMore, limit, offset, links, optional totalResults). Every configured method is listed, active or not - see the limitation note below. |
| GET | `/fscmRestApi/resources/11.13.18.05/receiptMethods/{ReceiptMethodId}` | supported | Returns a single receipt method. A method belonging to another tenant is indistinguishable from one that does not exist: both answer 404. |
| POST | `/fscmRestApi/resources/11.13.18.05/receiptMethods` | not_supported | Oracle documents only the two GET operations on this resource; receipt methods are Receivables SETUP, not something this API creates. Anything other than GET answers 405. Add methods for your tenant on the ERP simulator settings page. |

##### GET /fscmRestApi/resources/11.13.18.05/receiptMethods

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | Invalid q, finder or orderBy. |
| 401 | Missing or invalid bearer token. |

Request:

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receiptMethods"   --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receiptMethods/{ReceiptMethodId}

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | ReceiptMethodId is not numeric. |
| 401 | Missing or invalid bearer token. |
| 404 | No receipt method with that id in this tenant. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receiptMethods/300100000000000"   --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### POST /fscmRestApi/resources/11.13.18.05/receiptMethods

| Status | Meaning |
| --- | --- |
| 405 | Method not allowed - this resource is read-only in Oracle too. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Supported fields: ReceiptMethodId and Name — exactly the two Oracle marks x-queryable. Filtering on ReceiptClass is refused 400, as a real pod refuses it. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered — read that rather than guessing, and note it describes THIS API: where it is narrower than Oracle the refusal message says so explicitly. | `q=Name='Manual'` |
| `fields` | Comma-separated list of fields to include in each item. | `fields=ReceiptMethodId,Name` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=25` |
| `orderBy` | Comma-separated Field:asc\|desc list (default ReceiptMethodId:asc). Same fields as q. | `orderBy=Name:asc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `finder` | Named finder. PrimaryKey;ReceiptMethodId=... is the only finder Oracle documents on this resource; filter by name with q instead. | `finder=PrimaryKey;ReceiptMethodId=300100000000000` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ReceiptMethodId` | number |  | yes | Primary key. The identifier of the receipt method. |
| `Name` | string(30) |  | yes | The receipt method name. THIS is the value to send as ReceiptMethod on a standard receipt - the API matches by name, not by id. |
| `ReceiptClass` | string(30) |  | yes | The name of the receipt class, which identifies the steps involved in processing receipts created with this method. |
| `CreationDate` | datetime |  | yes | When the receipt method was created. Oracle wire format. |
| `LastUpdateDate` | datetime |  | yes | When the receipt method was last updated. Oracle wire format. |
| `CreatedBy` | string(64) |  | yes | Documented by Oracle. This simulator records no user attribution on setup rows, so it is always null rather than a fabricated user name. |
| `LastUpdatedBy` | string(64) |  | yes | Documented by Oracle. Always null here, for the same reason as CreatedBy. |

#### Limitations

- There is NO status, start-date or end-date attribute - Oracle does not publish one on this resource. So you cannot tell an active method from a retired one by reading this collection. A retired method is still rejected when you post a receipt, with AR_BOE_OBSOLETE rather than AR_INVAL_RECEIPT_MTH_ID, so the two failure modes remain distinguishable at the point of use.
- Every configured method is listed, active or not. Filtering to active rows would make this collection disagree with the errors standardReceipts returns - a method could be rejected as obsolete while being invisible here, which is worse than being visible without a status.
- CreatedBy and LastUpdatedBy are always null. The simulator records no user attribution on setup rows, and a stand-in value would put a fabricated user name where an integrator may expect a real one.
- The receiptMethodDFF child is not implemented. Descriptive flexfields are unsupported across this simulator.

### `customerAccountSitesLOV`

Oracle's customer-account-sites list of values. One row per customer account SITE USE, keyed by SiteUseId. Use it to discover the site names that may be passed as BillToSite when creating an invoice.

Base path: `/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV` | supported | Returns a paged collection wrapped in the Oracle envelope (items, count, hasMore, limit, offset, links, optional totalResults). Only active site uses are listed. |
| GET | `/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV/{SiteUseId}` | supported | Returns a single site use. |

##### GET /fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | Invalid q, finder or orderBy. |
| 401 | Missing or invalid bearer token. |

Request:

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV" \
  --data-urlencode "q=CustomerAccountId=300100000001000" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV/{SiteUseId}

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | SiteUseId is not numeric. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 404 | No customer account site with that SiteUseId. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Supported fields: SiteUseId, SiteName, PrimarySite, CustomerAccountId, AccountNumber, CustomerName, PartyNumber. The four attributes this tenant does not populate are not filterable. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered — read that rather than guessing, and note it describes THIS API: where it is narrower than Oracle the refusal message says so explicitly. | `q=CustomerAccountId=300100000001000` |
| `fields` | Comma-separated list of fields to include in each item. | `fields=SiteUseId,SiteName,PrimarySite` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=50` |
| `orderBy` | Comma-separated Field:asc\|desc list (default SiteUseId:asc). Same fields as q. | `orderBy=SiteName:asc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `finder` | Named finder. Only PrimaryKey;SiteUseId=... is supported; filter by account with q instead. | `finder=PrimaryKey;SiteUseId=300100000002001` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `SiteUseId` | number |  | yes | Primary key. Identifies the customer account site use. |
| `SiteName` | string |  | yes | Site name. This is the value to pass as BillToSite when creating an invoice. |
| `PrimarySite` | string |  | yes | Y when this is the customer's primary site use, otherwise N. Oracle types it as a single character, not a boolean. A customer may have Y on more than one purpose. |
| `CustomerAccountId` | number |  | yes | Owning customer account. |
| `AccountNumber` | string |  | yes | Customer account number. |
| `CustomerName` | string |  | yes | Customer name. |
| `PartyNumber` | string |  | yes | Trading Community party number. |
| `AccountDescription` | string |  | yes | Account description. Documented by Oracle; not populated in this tenant, so always null. |
| `SetName` | string |  | yes | Reference data set name. Documented by Oracle; this simulator models no reference data sets, so always null. |
| `TaxpayerIdentificationNumber` | string |  | yes | Taxpayer identification number. Documented by Oracle; not populated in this tenant, so always null. |
| `TaxRegistrationNumber` | string |  | yes | Tax registration number. Documented by Oracle; not populated in this tenant, so always null. |

#### Limitations

- Read-only. Oracle documents only GET on this resource.
- No address attributes. Oracle's list of values has no City, Country, PostalCode, Address1 or LocationId, so address data is not reachable through this API. It remains in the simulator data and is visible in the workspace UI.
- No SiteUseCode. A BILL_TO use and a SHIP_TO use cannot be told apart here, and both may be flagged PrimarySite=Y. To bill an invoice to a customer primary bill-to site, omit BillToSite on create and it is resolved server-side.
- No Status attribute, because Oracle resource has none. Only active site uses are returned.
- This resource replaced an earlier, non-Oracle customerAccountSites resource that was site-keyed and carried a siteUses child. That path is not an Oracle resource and returns 404, the same as any unknown resource - which is what a real pod does.

### `receivablesCustomerAccountActivities`

Read a customer's receivables position — one row per customer ACCOUNT — and, through the standardReceiptApplications child, the individual receipt applications behind it. This is the only external route to receipt applications, and therefore the way to confirm that a payment landed on the invoice you expected.

Base path: `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities` | supported | Returns a paged collection wrapped in the Oracle envelope. One row per customer ACCOUNT. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}` | supported | Returns the activity row for one customer account. Keyed by AccountId. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/transactionAdjustments` | supported | Adjustments made against this account's transactions - a manual increase or decrease to a transaction or one of its installments. Read-only, like every activity child. Oracle documents two finders here and both are honoured: PrimaryKey;AdjustmentId=<id>, and TransactionAdjustmentsFinder;AdjustmentLimitByDays=<n>,ReferenceTransactionStatus=<Open\|Closed> (the day limit counts back from the adjustment date and defaults to 90). Seventeen of Oracle's eighteen attributes are emitted; ProcessStatus is not modelled and a filter on it is refused by name rather than dropped. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/transactionsPaidByOtherCustomers` | supported | This account's transactions that SOMEONE ELSE paid - receipt applications whose receipt belongs to a different customer from the transaction it settles. Read-only, like every activity child. Seventeen of Oracle's nineteen attributes are emitted; IsLatestApplication and ProcessStatus are not modelled and a filter on either is refused by name rather than dropped. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/creditMemoApplications` | supported | Returns where each credit memo's value went — which transaction and installment it settled. The counterpart of standardReceiptApplications, for credit rather than cash. Read-only: applications are created by the settlement process, not by a caller. Twelve of Oracle's twenty-two attributes are emitted. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/creditMemos` | supported | Returns the credit memos raised against this customer. A credit memo is a TRANSACTION in Oracle's model and in this simulator, so it carries a transaction id, number and currency. Read-only. Ten of Oracle's eighteen attributes are emitted. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/transactionPaymentSchedules` | supported | Returns this customer's installments across all their transactions — what they still OWE, as against the standardReceipts child (what they paid) and standardReceiptApplications (where it went). Read-only. Twelve of Oracle's twenty-three attributes are emitted; AccountingDate, BillToSiteNumber, CreatedBy, CreationDate, LastUpdatedBy, PaymentDaysLate, PurchaseOrder, ReceiptMethod, StructuredPaymentReference, TransactionClass and TransactionSourceName are not modelled here. None of them is queryable in Oracle, so none costs a filter - this is the only child of these resources whose filterable set is 1:1 with Oracle's. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/standardReceipts` | supported | Returns the receipts belonging to this customer — what they PAID, as opposed to the standardReceiptApplications child beside it, which is where each receipt's money went. Read-only. Nine of Oracle's nineteen attributes are emitted; AccountingDate, AvailableAmount, BusinessUnit, CreatedBy, CreationDate, CustomerSite, DocumentNumber, LastUpdatedBy, LegalEntity and ProcessStatus are not modelled here and are ABSENT rather than null - a null would claim the value is unset, which is a different statement from not tracking it. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/standardReceiptApplications` | supported | Returns each application of receipt cash against this customer's invoices — the row that proves a payment landed and says which invoice and installment it settled. READ-ONLY: applications are created only by the Apply Receipts Using AutoMatch process, and there is no POST here. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01003 / REST-01005 / REST-01006 — a non-queryable attribute in q, an unknown finder, or an unknown orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |

Request:

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities" \
  --data-urlencode "q=AccountNumber='0001001'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}

Query parameters this operation implements: `fields`, `onlyData`, `links`, `expand`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01400 — AccountId is not numeric, or REST-01003 when expand names a child this resource does not have. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 — no such activity row in this environment. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/transactionAdjustments

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | A filter, sort or finder this child does not support. |
| 401 | Missing or invalid bearer token. |
| 403 | The credential lacks the account-activity privilege. Declared because the child ANSWERS it — a status a caller can receive and the document omits is the same defect as an attribute we emit and never declare. |
| 404 | REST-01102 - no such activity row in this environment. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/transactionAdjustments?finder=TransactionAdjustmentsFinder;AdjustmentLimitByDays=180,ReferenceTransactionStatus=Open" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/transactionsPaidByOtherCustomers

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | A filter or sort on an attribute this child does not support. |
| 401 | Missing or invalid bearer token. |
| 403 | The credential lacks the account-activity privilege. Declared because the child ANSWERS it — a status a caller can receive and the document omits is the same defect as an attribute we emit and never declare. |
| 404 | REST-01102 - no such activity row in this environment. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/transactionsPaidByOtherCustomers" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/creditMemoApplications

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01000 / REST-01003 / REST-01005 / REST-01006 — an OR on a derived status, a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown/unsortable orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or an application whose credit memo does not belong to this account or site. |

- Ownership runs through the CREDIT MEMO. An application row carries no customer of its own — it names a credit memo and the transaction that memo credits — and it is the memo's account and site that place it under a parent.
- Three attributes Oracle documents are NOT emitted, each for a stated reason. ActivityName: receivables activities are not modelled, the same gap as on standardReceiptApplications. IsLatestApplication: Oracle does not say whether 'latest' is per credit memo, per transaction or per installment, and the three differ. TransactionType: Oracle publishes it outside the ReferenceTransaction* group, which suggests it describes the credit memo rather than the credited transaction, but the page does not say so and the two readings give different values — emitting either would publish a guess as a fact on an attribute Oracle also marks queryable.
- Queryable attributes: ApplicationId, ApplicationStatus, CreditMemoId, CreditMemoNumber, CreditMemoStatus, ReferenceInstallmentId, ReferenceTransactionId, ReferenceTransactionNumber, ReferenceTransactionStatus. The three unemitted ones above are queryable in Oracle and are refused here by name.
- CreditMemoStatus and ReferenceTransactionStatus are BOTH derived from open balances — on two different transactions. Each filters as a predicate and neither sorts, and neither can be combined with OR, because a separate condition preserves the meaning of an AND only.
- Finders: PrimaryKey;ApplicationId=… and CreditMemoApplicationsFinder with CreditMemoStatus, ReferenceTransactionStatus (both Open/Closed) and ApplicationLimitByDays (Oracle's documented default is 90, counted from the application date).

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/creditMemoApplications" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/creditMemos

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01000 / REST-01003 / REST-01005 / REST-01006 — an OR on CreditMemoStatus, a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown/unsortable orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or a credit memo that does not belong to this account or site. |

- AvailableAmount is documented by Oracle and is NOT emitted here. Oracle publishes both AvailableAmount ('remaining credit memo amount') and TotalBalanceAmount ('remaining balance amount') and states no rule distinguishing them. Emitting the same figure for both would make one attribute a duplicate of the other, and Oracle does not publish two attributes with the same meaning — so rather than guess which is which, only TotalBalanceAmount is emitted. Recorded as unverified.
- Also not emitted: AccountingDate, BillToSiteNumber, CreatedBy, CreationDate, LastUpdatedBy, PurchaseOrder and TransactionClass. None is queryable in Oracle, so none costs a filter.
- Queryable attributes: CreditMemoId, CreditMemoNumber, CreditMemoStatus, InstallmentId, TransactionType — all five Oracle marks queryable, all emitted.
- CreditMemoStatus is derived from the open balance and InstallmentId comes from the payment schedule. Both FILTER; neither SORTS, because ordering on a computed value or a joined column does not reorder the credit memos, and a sort that does not sort is worse than a refused one. CreditMemoStatus also cannot be combined with OR: it is applied as a separate condition, which preserves the meaning of an AND only.
- Finders: PrimaryKey;CreditMemoId=… and CreditMemosFinder with CreditMemoStatus (Open/Closed) and CreditMemoLimitByDays (Oracle's documented default is 90, counted from the credit memo date).

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/creditMemos?q=CreditMemoStatus='Open'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/transactionPaymentSchedules

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01000 / REST-01003 / REST-01005 / REST-01006 — an OR on InstallmentStatus, a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown/unsortable orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or an installment that does not belong to this account or site. |

- InstallmentStatus is Open or Closed here. The receivablesInvoiceInstallments child publishes the SAME underlying state as OP or CL — each resource uses Oracle's vocabulary for itself. Filtering uses this resource's spelling: q=InstallmentStatus='Open', not 'OP'.
- Queryable attributes: InstallmentId, InstallmentStatus, TransactionId, TransactionNumber, TransactionType — all five Oracle marks queryable, all emitted.
- Finders: PrimaryKey;InstallmentId=… and TransactionPaymentSchedulesFinder with InstallmentStatus (Open/Closed) and TransactionLimitByDays (Oracle's documented default is 90, counted from the TRANSACTION date, not the due date).
- Sortable attributes are the seven stored on the installment itself. TransactionId, TransactionNumber, TransactionDate, TransactionType and EnteredCurrency are resolved from the transaction and are refused for orderBy by name — sorting on a related column would not reorder the installments.
- InstallmentStatus cannot be combined with OR in q: the value is translated to the stored spelling and applied as a separate condition, which preserves the meaning of an AND only.

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/transactionPaymentSchedules?q=InstallmentStatus='Open'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/standardReceipts

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01003 / REST-01005 / REST-01006 — a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or a receipt that does not belong to this account or site. |

- Queryable attributes: ReceiptMethod, ReceiptNumber, StandardReceiptId. This is a DIFFERENT set from the top-level standardReceipts resource, where ReceiptDate and CustomerAccountNumber are queryable and ReceiptMethod is not. Two resources over the same rows do not share a filter contract.
- Oracle also marks BusinessUnit and ProcessStatus queryable here. Neither is emitted by this simulator, so a filter on either is refused by name rather than ignored — an ignored filter returns every receipt and is indistinguishable from one that matched them all.
- Finders: PrimaryKey;StandardReceiptId=… and StandardReceiptsFinder;ReceiptLimitByDays=… (Oracle's documented default is 90 days, counted from the receipt date). StandardReceiptsFinder's ProcessStatus variable is refused by name for the same reason.
- Every emitted attribute is sortable. The parent resources expand this child too: expand=standardReceipts, or expand=all.

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/standardReceipts?orderBy=ReceiptDate:desc" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/{AccountId}/child/standardReceiptApplications

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01003 / REST-01005 / REST-01006 — a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 — unknown parent, or a child Oracle documents that this simulator does not implement (it is named in the message). |

- Queryable attributes: ApplicationId, StandardReceiptId, ApplicationStatus, ReferenceTransactionId, ReferenceInstallmentId. ApplicationAmount, ApplicationDate and LastUpdateDate are NOT queryable in Oracle and are refused here.
- Finders: PrimaryKey;ApplicationId=… and StandardReceiptApplicationsFinder with ApplicationLimitByDays or ReferenceTransactionStatus. StandardReceiptApplicationsFinder's ProcessStatus variable is documented by Oracle and not implemented here; it is refused by name rather than ignored.
- Only ApplicationStatus APP rows reduce an invoice balance. A REV row is a reversal and is history.

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/300100000000000/child/standardReceiptApplications" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Queryable attributes, per Oracle's x-queryable flag: AccountId, AccountNumber, CustomerId, CustomerName, TaxpayerIdentificationNumber, TaxRegistrationNumber, CreatedBy, CreationDate, LastUpdatedBy, LastUpdateDate. The two totals are NOT queryable — they are derived figures and Oracle refuses to filter on them, so "every account that owes something" is not a server-side query: read the collection and select locally. An attribute outside the list is refused 400, never ignored. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered. That flag is Oracle's: this API is 1:1 with Oracle on every attribute it emits, so a filter that works here works on a real pod. | `q=AccountNumber='0001001'` |
| `fields` | Comma-separated attribute projection. | `fields=AccountId,AccountNumber,TotalOpenReceivablesForAccount` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=50` |
| `orderBy` | Comma-separated Field:asc\|desc list (default AccountId:asc). Sortable on any attribute the resource emits, including the two totals — Oracle's queryable flag restricts FILTERING, not sorting. An unknown field is refused 400. | `orderBy=TotalOpenReceivablesForAccount:desc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `finder` | This resource has no named finders in Oracle, so any finder is refused 400 rather than ignored. Filter with q. | `q=AccountNumber='0001001'` |
| `expand` | Item read only. Embeds the standardReceiptApplications child in the payload instead of a link: expand=standardReceiptApplications, or expand=all. An expanded application is byte-identical to one read from the child endpoint, and an account with none comes back as an empty array rather than omitting the key. A child this resource does not have is refused 400 REST-01003, never ignored. Until 2026-08-05 this parameter was accepted and SILENTLY DROPPED here — 200, no child, nothing to say the request had not been honoured. | `expand=standardReceiptApplications` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `AccountId` | number |  | yes | Customer account identifier. The key of the item path on this resource, for BOTH the account and the site variant. |
| `AccountNumber` | string |  | yes | Customer account number, the value you pass as CustomerAccountNumber on a receipt. |
| `CustomerId` | number |  | yes | Trading Community party id of the customer. |
| `CustomerName` | string |  | yes | Customer name. |
| `TaxpayerIdentificationNumber` | string |  | yes | Documented by Oracle; not populated in this simulator, so always null. |
| `TaxRegistrationNumber` | string |  | yes | Documented by Oracle; not populated in this simulator, so always null. |
| `TotalOpenReceivablesForAccount` | number |  | yes | Total Transaction Due Amount LESS Pending Application Amount. Expressed in the LEDGER currency (USD here), NOT the invoice currency — this resource carries no currency attribute because Oracle defines none. Can be NEGATIVE when a customer has unapplied cash exceeding what they owe. Voided transactions are excluded. |
| `TotalTransactionsDueForAccount` | number |  | yes | Total amount due across the customer's open transactions, in the LEDGER currency. This is an AMOUNT, not a past-due filter — it is not restricted to overdue items. |
| `CreatedBy` | string |  | yes | Audit user that created the account. |
| `CreationDate` | datetime |  | yes | Audit creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit user of the most recent change. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |
| `standardReceipts` | array<AccountStandardReceipt> |  | yes | The account's receipts. Returned when requested with expand=standardReceipts (or expand=all), and identical to reading the child collection directly. |
| `standardReceiptApplications` | array<StandardReceiptApplication> |  | yes | Receipt applications against the account's transactions. Returned with expand=standardReceiptApplications (or expand=all). |
| `transactionPaymentSchedules` | array<TransactionPaymentSchedule> |  | yes | Installment-level payment schedules for the account's transactions. Returned with expand=transactionPaymentSchedules (or expand=all). |
| `creditMemos` | array<AccountCreditMemo> |  | yes | Credit memos belonging to the account. Returned with expand=creditMemos (or expand=all). |
| `creditMemoApplications` | array<CreditMemoApplication> |  | yes | Applications of the account's credit memos against transactions. Returned with expand=creditMemoApplications (or expand=all). |
| `transactionsPaidByOtherCustomers` | array<TransactionPaidByOtherCustomer> |  | yes | This account's transactions that someone else paid. Returned with expand=transactionsPaidByOtherCustomers (or expand=all). |
| `transactionAdjustments` | array<TransactionAdjustment> |  | yes | Adjustments made against this account's transactions. Returned with expand=transactionAdjustments (or expand=all). |

Each element of `standardReceipts`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `StandardReceiptId` | number |  | yes | Primary key of the receipt. The full record is at /standardReceipts/{StandardReceiptId}. |
| `ReceiptNumber` | string |  | yes | The receipt number as supplied when the receipt was created. |
| `ReceiptDate` | date |  | yes | yyyy-MM-dd date of the receipt. |
| `ReceiptMethod` | string |  | yes | Name of the receipt method the payment arrived by. |
| `Amount` | number |  | yes | Total amount received, in Currency. |
| `Currency` | string |  | yes | ISO 4217 currency of the receipt. |
| `State` | string |  | yes | APPLIED, UNAPPLIED, UNIDENTIFIED, REVERSE PAYMENT, INSUFFICIENT FUNDS or STOP PAYMENT. This child publishes State and NOT Status, unlike the top-level standardReceipts resource. |
| `UnappliedAmount` | number |  | yes | Cash on this receipt not yet applied to any transaction. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `standardReceiptApplications`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ApplicationId` | number |  | yes | Primary key of the application. |
| `StandardReceiptId` | number |  | yes | The receipt whose cash was applied. Read it at /standardReceipts/{StandardReceiptId}. |
| `ReceiptNumber` | string |  | yes | Receipt number of that receipt. |
| `ReferenceTransactionId` | number |  | yes | CustomerTransactionId of the invoice the cash was applied to. |
| `ReferenceTransactionNumber` | string |  | yes | TransactionNumber of that invoice. |
| `ReferenceInstallmentId` | number |  | yes | InstallmentId the application settled. Null once a reversal has detached it. |
| `ApplicationAmount` | number |  | yes | Amount applied, in EnteredCurrency. |
| `EnteredCurrency` | string |  | yes | ISO 4217 currency of the receipt this application came from. |
| `ApplicationDate` | date |  | yes | yyyy-MM-dd date the application was made. |
| `AccountingDate` | date |  | yes | yyyy-MM-dd accounting date of the application. |
| `ApplicationStatus` | string |  | yes | APP for an application in force, REV once reversed. Only APP rows reduce an invoice balance; a REV row is history. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed — whether the invoice still carries a balance. |
| `CreatedBy` | string |  | yes | Audit user that created the row. |
| `CreationDate` | datetime |  | yes | Audit creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit user of the most recent change. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `transactionPaymentSchedules`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `InstallmentId` | number |  | yes | Primary key of the installment (payment schedule). |
| `InstallmentNumber` | number |  | yes | Sequence of this installment within its transaction. |
| `InstallmentStatus` | string |  | yes | Open or Closed. Note the receivablesInvoiceInstallments child publishes the same underlying state as OP or CL — each resource uses Oracle's vocabulary for itself, so do not carry a value across. |
| `PaymentScheduleDueDate` | date |  | yes | yyyy-MM-dd date this installment falls due. |
| `TotalOriginalAmount` | number |  | yes | Original amount of the installment, in EnteredCurrency. |
| `TotalBalanceAmount` | number |  | yes | Amount still outstanding on the installment. |
| `TransactionId` | number |  | yes | CustomerTransactionId of the transaction this installment belongs to. |
| `TransactionNumber` | string |  | yes | Transaction number of that transaction. |
| `TransactionDate` | date |  | yes | yyyy-MM-dd date the transaction bears. |
| `TransactionType` | string(20) |  | yes | Transaction type — Invoice, Credit Memo, and so on. |
| `EnteredCurrency` | string |  | yes | ISO 4217 currency the transaction was entered in. |
| `TransactionSourceName` | string |  | yes | Batch source the transaction was created under. Oracle's name for it on THIS child; the receivablesInvoices resource calls the same value TransactionSource. Not filterable and not sortable here - it is resolved from the transaction, not stored on the schedule row. |
| `PaymentDaysLate` | number |  | yes | Days this installment is past its due date, floored at zero, and zero for a closed installment. Computed on read from the same rule the receivablesInvoiceInstallments child uses, so the two agree. Not usable as a sort key for that reason. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `creditMemos`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CreditMemoId` | number |  | yes | Primary key of the credit memo. A credit memo is a transaction, so this is its CustomerTransactionId. |
| `CreditMemoNumber` | string |  | yes | Transaction number of the credit memo. |
| `CreditMemoDate` | date |  | yes | yyyy-MM-dd date the credit memo bears. |
| `CreditMemoCurrency` | string |  | yes | ISO 4217 currency of the credit memo. |
| `CreditMemoStatus` | string |  | yes | Open or Closed — whether the credit memo still carries a balance. Derived from the open balance rather than stored, so it can never disagree with TotalBalanceAmount. |
| `TotalOriginalAmount` | number |  | yes | Original amount of the credit memo, in CreditMemoCurrency. |
| `TotalBalanceAmount` | number |  | yes | Amount still remaining on the credit memo. |
| `TransactionType` | string(20) |  | yes | Always Credit Memo on this child. |
| `InstallmentId` | number |  | yes | The credit memo installment. Oracle publishes one; where a credit memo carries several schedules this reports the lowest installment number. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `creditMemoApplications`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ApplicationId` | number |  | yes | Primary key of the credit memo application. |
| `ApplicationAmount` | number |  | yes | Amount of the credit memo applied, in EnteredCurrency. |
| `ApplicationDate` | date |  | yes | yyyy-MM-dd date the credit memo was applied. |
| `ApplicationStatus` | string |  | yes | Whether the application is in force or has been reversed. The VALUE VOCABULARY for this attribute is not confirmed against Oracle — its page gives the attribute a length but no allowed-value list, and the sibling standardReceiptApplications child uses a different pair — so branch on the value you observe on your own instance rather than on a list published here. Recorded as unverified in the conformance ledger. |
| `CreditMemoId` | number |  | yes | The credit memo whose value was applied. Read it on the creditMemos child. |
| `CreditMemoNumber` | string |  | yes | Transaction number of that credit memo. |
| `CreditMemoStatus` | string |  | yes | Open or Closed — whether the credit memo still carries a balance. Derived from its open balance rather than stored. |
| `EnteredCurrency` | string |  | yes | ISO 4217 currency of the credit memo. |
| `ReferenceTransactionId` | number |  | yes | CustomerTransactionId of the transaction the credit memo was applied to. |
| `ReferenceTransactionNumber` | string |  | yes | Transaction number of that transaction. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed — whether the credited transaction still carries a balance. Derived, like CreditMemoStatus, but from a DIFFERENT transaction. |
| `ReferenceInstallmentId` | number |  | yes | The installment the application settled. Null once a reversal has detached it. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change, Oracle wire format. Maintained by the database and not settable. Use it as an incremental-sync watermark for credit memo applications - before migration 0084 this table had no such column and there was no watermark at this grain. |

Each element of `transactionsPaidByOtherCustomers`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ApplicationId` | number |  | yes | Primary key of the application. |
| `StandardReceiptId` | number |  | yes | The receipt that paid. |
| `ReceiptNumber` | string |  | yes | That receipt's number. |
| `ReceiptMethod` | string |  | yes | The receipt method used. The one attribute this child publishes that the sibling standardReceiptApplications child does not. |
| `ReferenceTransactionId` | number |  | yes | The transaction that was paid. |
| `ReferenceTransactionNumber` | string |  | yes | That transaction's number. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed - the status of the transaction the receipt was applied against, derived from its live open balance rather than stored. Not the invoice's completion status. |
| `ReferenceInstallmentId` | number |  | yes | The installment settled. |
| `ApplicationAmount` | number |  | yes | How much of the receipt landed here. |
| `ApplicationDate` | date |  | yes | When it was applied. |
| `AccountingDate` | date |  | yes | The accounting date of the application. |
| `ApplicationStatus` | string |  | yes | The application's status. |
| `EnteredCurrency` | string |  | yes | The receipt's currency. |
| `CreatedBy` | string |  | yes | Who created the application. |
| `CreationDate` | datetime |  | yes | When it was created. Oracle wire format. |
| `LastUpdatedBy` | string |  | yes | Who last updated it. |
| `LastUpdateDate` | datetime |  | yes | When it was last updated. Oracle wire format. |

Each element of `transactionAdjustments`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `AdjustmentId` | number |  | yes | Primary key of the adjustment. |
| `AdjustmentNumber` | string |  | yes | The number assigned to the adjustment. Oracle publishes a maximum length of 20. |
| `AdjustmentAmount` | number |  | yes | The amount adjusted. |
| `AdjustmentType` | string |  | yes | What part of the transaction is adjusted. Oracle's values: Charges, Freight, Invoice (transaction header), Line, Tax. |
| `AdjustmentReason` | string |  | yes | The reason code assigned to the adjustment. Oracle publishes no fixed list — reason codes are customer-defined lookups. |
| `ReferenceTransactionId` | number |  | yes | The adjusted transaction. |
| `ReferenceTransactionNumber` | string |  | yes | That transaction's number. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed — the status of the transaction the adjustment is made against, derived from its live open balance rather than stored. |
| `ReferenceInstallmentId` | number |  | yes | The adjusted installment. Null for a header-level adjustment. |
| `BillToSiteNumber` | string |  | yes | The name of the customer bill-to site. |
| `AccountingDate` | date |  | yes | The accounting date of the adjustment. |
| `ApplicationDate` | date |  | yes | The application date of the adjustment. |
| `EnteredCurrency` | string |  | yes | The adjustment's currency code. |
| `CreatedBy` | string |  | yes | Who created the adjustment. |
| `CreationDate` | datetime |  | yes | When it was created. Oracle wire format. |
| `LastUpdatedBy` | string |  | yes | Who last updated it. |
| `LastUpdateDate` | datetime |  | yes | When it was last updated. Oracle wire format. |

#### Limitations

- Read-only. GET is the only method; anything else is refused 405.
- Oracle documents seven children here — creditMemoApplications, creditMemos, standardReceipts, standardReceiptApplications, transactionAdjustments, transactionPaymentSchedules and transactionsPaidByOtherCustomers. ALL SEVEN are implemented, on both the account and the site grain, and each is also embeddable with expand. Each child has its own attribute names, its own queryable set and its own finders — read the operation you are calling rather than assuming the parent's. Where an attribute Oracle publishes is not modelled here it is refused BY NAME with the reason, never accepted and ignored.
- Both totals are in the LEDGER currency, and the resource carries no currency attribute because Oracle defines none. Converting back to an invoice currency is the caller's problem.
- TotalOpenReceivablesForAccount can be negative. That is not an error — it means unapplied cash exceeds what the customer owes.

### `receivablesCustomerAccountSiteActivities`

Read a customer's receivables position — one row per customer account SITE (bill-to site use), so a customer with three bill-to sites has three rows — and, through the standardReceiptApplications child, the individual receipt applications behind it. This is the only external route to receipt applications, and therefore the way to confirm that a payment landed on the invoice you expected.

Base path: `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities` | supported | Returns a paged collection wrapped in the Oracle envelope. One row per customer account SITE (bill-to site use), so a customer with three bill-to sites has three rows. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}` | supported | Returns the activity row for one bill-to site use. Keyed by BillToSiteUseId — NOT by AccountId, which answers 404. Both attributes are on the row; take BillToSiteUseId. On the first seeded account the two values coincide, so a test written against that row alone cannot tell them apart. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/transactionAdjustments` | supported | Adjustments made against this account's transactions - a manual increase or decrease to a transaction or one of its installments. Read-only, like every activity child. Oracle documents two finders here and both are honoured: PrimaryKey;AdjustmentId=<id>, and TransactionAdjustmentsFinder;AdjustmentLimitByDays=<n>,ReferenceTransactionStatus=<Open\|Closed> (the day limit counts back from the adjustment date and defaults to 90). Seventeen of Oracle's eighteen attributes are emitted; ProcessStatus is not modelled and a filter on it is refused by name rather than dropped. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/transactionsPaidByOtherCustomers` | supported | This account's transactions that SOMEONE ELSE paid - receipt applications whose receipt belongs to a different customer from the transaction it settles. Read-only, like every activity child. Seventeen of Oracle's nineteen attributes are emitted; IsLatestApplication and ProcessStatus are not modelled and a filter on either is refused by name rather than dropped. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/creditMemoApplications` | supported | Returns where each credit memo's value went — which transaction and installment it settled. The counterpart of standardReceiptApplications, for credit rather than cash. Read-only: applications are created by the settlement process, not by a caller. Twelve of Oracle's twenty-two attributes are emitted. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/creditMemos` | supported | Returns the credit memos raised against this customer. A credit memo is a TRANSACTION in Oracle's model and in this simulator, so it carries a transaction id, number and currency. Read-only. Ten of Oracle's eighteen attributes are emitted. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/transactionPaymentSchedules` | supported | Returns this customer's installments across all their transactions — what they still OWE, as against the standardReceipts child (what they paid) and standardReceiptApplications (where it went). Read-only. Twelve of Oracle's twenty-three attributes are emitted; AccountingDate, BillToSiteNumber, CreatedBy, CreationDate, LastUpdatedBy, PaymentDaysLate, PurchaseOrder, ReceiptMethod, StructuredPaymentReference, TransactionClass and TransactionSourceName are not modelled here. None of them is queryable in Oracle, so none costs a filter - this is the only child of these resources whose filterable set is 1:1 with Oracle's. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/standardReceipts` | supported | Returns the receipts belonging to this customer — what they PAID, as opposed to the standardReceiptApplications child beside it, which is where each receipt's money went. Read-only. Nine of Oracle's nineteen attributes are emitted; AccountingDate, AvailableAmount, BusinessUnit, CreatedBy, CreationDate, CustomerSite, DocumentNumber, LastUpdatedBy, LegalEntity and ProcessStatus are not modelled here and are ABSENT rather than null - a null would claim the value is unset, which is a different statement from not tracking it. |
| GET | `/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/standardReceiptApplications` | supported | Returns each application of receipt cash against this customer's invoices — the row that proves a payment landed and says which invoice and installment it settled. READ-ONLY: applications are created only by the Apply Receipts Using AutoMatch process, and there is no POST here. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01003 / REST-01005 / REST-01006 — a non-queryable attribute in q, an unknown finder, or an unknown orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |

Request:

```bash
curl --get "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities" \
  --data-urlencode "q=AccountNumber='0001001'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}

Query parameters this operation implements: `fields`, `onlyData`, `links`, `expand`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01400 — BillToSiteUseId is not numeric, or REST-01003 when expand names a child this resource does not have. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 — no such activity row in this environment. |

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/transactionAdjustments

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | A filter, sort or finder this child does not support. |
| 401 | Missing or invalid bearer token. |
| 403 | The credential lacks the account-activity privilege. Declared because the child ANSWERS it — a status a caller can receive and the document omits is the same defect as an attribute we emit and never declare. |
| 404 | REST-01102 - no such activity row in this environment. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/transactionAdjustments?finder=TransactionAdjustmentsFinder;AdjustmentLimitByDays=180,ReferenceTransactionStatus=Open" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/transactionsPaidByOtherCustomers

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | OK. |
| 400 | A filter or sort on an attribute this child does not support. |
| 401 | Missing or invalid bearer token. |
| 403 | The credential lacks the account-activity privilege. Declared because the child ANSWERS it — a status a caller can receive and the document omits is the same defect as an attribute we emit and never declare. |
| 404 | REST-01102 - no such activity row in this environment. |

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/transactionsPaidByOtherCustomers" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/creditMemoApplications

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01000 / REST-01003 / REST-01005 / REST-01006 — an OR on a derived status, a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown/unsortable orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or an application whose credit memo does not belong to this account or site. |

- Ownership runs through the CREDIT MEMO. An application row carries no customer of its own — it names a credit memo and the transaction that memo credits — and it is the memo's account and site that place it under a parent.
- Three attributes Oracle documents are NOT emitted, each for a stated reason. ActivityName: receivables activities are not modelled, the same gap as on standardReceiptApplications. IsLatestApplication: Oracle does not say whether 'latest' is per credit memo, per transaction or per installment, and the three differ. TransactionType: Oracle publishes it outside the ReferenceTransaction* group, which suggests it describes the credit memo rather than the credited transaction, but the page does not say so and the two readings give different values — emitting either would publish a guess as a fact on an attribute Oracle also marks queryable.
- Queryable attributes: ApplicationId, ApplicationStatus, CreditMemoId, CreditMemoNumber, CreditMemoStatus, ReferenceInstallmentId, ReferenceTransactionId, ReferenceTransactionNumber, ReferenceTransactionStatus. The three unemitted ones above are queryable in Oracle and are refused here by name.
- CreditMemoStatus and ReferenceTransactionStatus are BOTH derived from open balances — on two different transactions. Each filters as a predicate and neither sorts, and neither can be combined with OR, because a separate condition preserves the meaning of an AND only.
- Finders: PrimaryKey;ApplicationId=… and CreditMemoApplicationsFinder with CreditMemoStatus, ReferenceTransactionStatus (both Open/Closed) and ApplicationLimitByDays (Oracle's documented default is 90, counted from the application date).

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/creditMemoApplications" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/creditMemos

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01000 / REST-01003 / REST-01005 / REST-01006 — an OR on CreditMemoStatus, a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown/unsortable orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or a credit memo that does not belong to this account or site. |

- AvailableAmount is documented by Oracle and is NOT emitted here. Oracle publishes both AvailableAmount ('remaining credit memo amount') and TotalBalanceAmount ('remaining balance amount') and states no rule distinguishing them. Emitting the same figure for both would make one attribute a duplicate of the other, and Oracle does not publish two attributes with the same meaning — so rather than guess which is which, only TotalBalanceAmount is emitted. Recorded as unverified.
- Also not emitted: AccountingDate, BillToSiteNumber, CreatedBy, CreationDate, LastUpdatedBy, PurchaseOrder and TransactionClass. None is queryable in Oracle, so none costs a filter.
- Queryable attributes: CreditMemoId, CreditMemoNumber, CreditMemoStatus, InstallmentId, TransactionType — all five Oracle marks queryable, all emitted.
- CreditMemoStatus is derived from the open balance and InstallmentId comes from the payment schedule. Both FILTER; neither SORTS, because ordering on a computed value or a joined column does not reorder the credit memos, and a sort that does not sort is worse than a refused one. CreditMemoStatus also cannot be combined with OR: it is applied as a separate condition, which preserves the meaning of an AND only.
- Finders: PrimaryKey;CreditMemoId=… and CreditMemosFinder with CreditMemoStatus (Open/Closed) and CreditMemoLimitByDays (Oracle's documented default is 90, counted from the credit memo date).

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/creditMemos?q=CreditMemoStatus='Open'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/transactionPaymentSchedules

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01000 / REST-01003 / REST-01005 / REST-01006 — an OR on InstallmentStatus, a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown/unsortable orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or an installment that does not belong to this account or site. |

- InstallmentStatus is Open or Closed here. The receivablesInvoiceInstallments child publishes the SAME underlying state as OP or CL — each resource uses Oracle's vocabulary for itself. Filtering uses this resource's spelling: q=InstallmentStatus='Open', not 'OP'.
- Queryable attributes: InstallmentId, InstallmentStatus, TransactionId, TransactionNumber, TransactionType — all five Oracle marks queryable, all emitted.
- Finders: PrimaryKey;InstallmentId=… and TransactionPaymentSchedulesFinder with InstallmentStatus (Open/Closed) and TransactionLimitByDays (Oracle's documented default is 90, counted from the TRANSACTION date, not the due date).
- Sortable attributes are the seven stored on the installment itself. TransactionId, TransactionNumber, TransactionDate, TransactionType and EnteredCurrency are resolved from the transaction and are refused for orderBy by name — sorting on a related column would not reorder the installments.
- InstallmentStatus cannot be combined with OR in q: the value is translated to the stored spelling and applied as a separate condition, which preserves the meaning of an AND only.

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/transactionPaymentSchedules?q=InstallmentStatus='Open'" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/standardReceipts

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01003 / REST-01005 / REST-01006 — a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 / REST-01404 — unknown parent, or a receipt that does not belong to this account or site. |

- Queryable attributes: ReceiptMethod, ReceiptNumber, StandardReceiptId. This is a DIFFERENT set from the top-level standardReceipts resource, where ReceiptDate and CustomerAccountNumber are queryable and ReceiptMethod is not. Two resources over the same rows do not share a filter contract.
- Oracle also marks BusinessUnit and ProcessStatus queryable here. Neither is emitted by this simulator, so a filter on either is refused by name rather than ignored — an ignored filter returns every receipt and is indistinguishable from one that matched them all.
- Finders: PrimaryKey;StandardReceiptId=… and StandardReceiptsFinder;ReceiptLimitByDays=… (Oracle's documented default is 90 days, counted from the receipt date). StandardReceiptsFinder's ProcessStatus variable is refused by name for the same reason.
- Every emitted attribute is sortable. The parent resources expand this child too: expand=standardReceipts, or expand=all.

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/standardReceipts?orderBy=ReceiptDate:desc" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

##### GET /fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/{BillToSiteUseId}/child/standardReceiptApplications

Query parameters this operation implements: `q`, `fields`, `limit`, `offset`, `totalResults`, `onlyData`, `links`, `orderBy`, `finder`. Anything else is refused.

| Status | Meaning |
| --- | --- |
| 200 | Success. |
| 400 | REST-01003 / REST-01005 / REST-01006 — a non-queryable attribute in q, an unknown or unimplemented finder variable, or an unknown orderBy field. |
| 401 | REST-01401 — missing or invalid bearer token, or a credential issued for a different environment |
| 403 | FND_SECURITY_INSUFFICIENT_PRIVILEGE — the credential's scope list does not include AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV. |
| 404 | REST-01102 — unknown parent, or a child Oracle documents that this simulator does not implement (it is named in the message). |

- Queryable attributes: ApplicationId, StandardReceiptId, ApplicationStatus, ReferenceTransactionId, ReferenceInstallmentId. ApplicationAmount, ApplicationDate and LastUpdateDate are NOT queryable in Oracle and are refused here.
- Finders: PrimaryKey;ApplicationId=… and StandardReceiptApplicationsFinder with ApplicationLimitByDays or ReferenceTransactionStatus. StandardReceiptApplicationsFinder's ProcessStatus variable is documented by Oracle and not implemented here; it is refused by name rather than ignored.
- Only ApplicationStatus APP rows reduce an invoice balance. A REV row is a reversal and is history.

Request:

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountSiteActivities/300100000000000/child/standardReceiptApplications" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `q` | Oracle q filter expression. Queryable attributes, per Oracle's x-queryable flag: AccountId, AccountNumber, CustomerId, CustomerName, TaxpayerIdentificationNumber, TaxRegistrationNumber, CreatedBy, CreationDate, LastUpdatedBy, LastUpdateDate. The two totals are NOT queryable — they are derived figures and Oracle refuses to filter on them, so "every account that owes something" is not a server-side query: read the collection and select locally. An attribute outside the list is refused 400, never ignored. Every attribute carries an `x-queryable` flag in the OpenAPI schema saying whether it can be filtered. That flag is Oracle's: this API is 1:1 with Oracle on every attribute it emits, so a filter that works here works on a real pod. | `q=AccountNumber='0001001'` |
| `fields` | Comma-separated attribute projection. | `fields=AccountId,AccountNumber,TotalOpenReceivablesForSite` |
| `limit` | Page size. Valid range 1-500, default 25. A value above 500 is CLAMPED to 500 and one at or below 0 falls back to 25 — neither is refused, so read `limit` back off the response envelope rather than assuming you got what you asked for. | `limit=50` |
| `offset` | Zero-based row offset, default 0. A negative value falls back to 0 rather than being refused. Page by adding the returned `limit` until `hasMore` is false. | `offset=50` |
| `orderBy` | Comma-separated Field:asc\|desc list (default BillToSiteUseId:asc). Sortable on any attribute the resource emits, including the two totals — Oracle's queryable flag restricts FILTERING, not sorting. An unknown field is refused 400. | `orderBy=TotalOpenReceivablesForSite:desc` |
| `totalResults` | Set to true to include a totalResults count in the envelope. | `totalResults=true` |
| `onlyData` | When true, strips the links section. | `onlyData=true` |
| `links` | Comma-separated list of link RELATIONS to keep in the links array, e.g. links=self or links=self,parent. Oracle: "This parameter can be used to show only certain links while accessing a singular resource or a resource collection." A relation the response does not carry is simply absent. Combining it with onlyData=true leaves no links at all, because onlyData strips the section outright. | `links=self` |
| `finder` | This resource has no named finders in Oracle, so any finder is refused 400 rather than ignored. Filter with q. | `q=AccountNumber='0001001'` |
| `expand` | Item read only. Embeds the standardReceiptApplications child in the payload instead of a link: expand=standardReceiptApplications, or expand=all. An expanded application is byte-identical to one read from the child endpoint, and an account with none comes back as an empty array rather than omitting the key. A child this resource does not have is refused 400 REST-01003, never ignored. Until 2026-08-05 this parameter was accepted and SILENTLY DROPPED here — 200, no child, nothing to say the request had not been honoured. | `expand=standardReceiptApplications` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `AccountId` | number |  | yes | Customer account identifier. The key of the item path on this resource, for BOTH the account and the site variant. |
| `AccountNumber` | string |  | yes | Customer account number, the value you pass as CustomerAccountNumber on a receipt. |
| `CustomerId` | number |  | yes | Trading Community party id of the customer. |
| `CustomerName` | string |  | yes | Customer name. |
| `BillToSiteUseId` | number |  | yes | The bill-to site use this row aggregates. Present only on the site-grained resource. |
| `TaxpayerIdentificationNumber` | string |  | yes | Documented by Oracle; not populated in this simulator, so always null. |
| `TaxRegistrationNumber` | string |  | yes | Documented by Oracle; not populated in this simulator, so always null. |
| `TotalOpenReceivablesForSite` | number |  | yes | Total Transaction Due Amount LESS Pending Application Amount for the bill-to site. Expressed in the LEDGER currency (USD here), NOT the invoice currency — this resource carries no currency attribute because Oracle defines none. Can be NEGATIVE when a customer has unapplied cash exceeding what they owe. Voided transactions are excluded. |
| `TotalTransactionsDueForSite` | number |  | yes | Total amount due across the site's open transactions, in the LEDGER currency. This is an AMOUNT, not a past-due filter — it is not restricted to overdue items. |
| `CreatedBy` | string |  | yes | Audit user that created the account. |
| `CreationDate` | datetime |  | yes | Audit creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit user of the most recent change. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |
| `standardReceipts` | array<AccountStandardReceipt> |  | yes | The account's receipts. Returned when requested with expand=standardReceipts (or expand=all), and identical to reading the child collection directly. |
| `standardReceiptApplications` | array<StandardReceiptApplication> |  | yes | Receipt applications against the account's transactions. Returned with expand=standardReceiptApplications (or expand=all). |
| `transactionPaymentSchedules` | array<TransactionPaymentSchedule> |  | yes | Installment-level payment schedules for the account's transactions. Returned with expand=transactionPaymentSchedules (or expand=all). |
| `creditMemos` | array<AccountCreditMemo> |  | yes | Credit memos belonging to the account. Returned with expand=creditMemos (or expand=all). |
| `creditMemoApplications` | array<CreditMemoApplication> |  | yes | Applications of the account's credit memos against transactions. Returned with expand=creditMemoApplications (or expand=all). |
| `transactionsPaidByOtherCustomers` | array<TransactionPaidByOtherCustomer> |  | yes | This account's transactions that someone else paid. Returned with expand=transactionsPaidByOtherCustomers (or expand=all). |
| `transactionAdjustments` | array<TransactionAdjustment> |  | yes | Adjustments made against this account's transactions. Returned with expand=transactionAdjustments (or expand=all). |

Each element of `standardReceipts`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `StandardReceiptId` | number |  | yes | Primary key of the receipt. The full record is at /standardReceipts/{StandardReceiptId}. |
| `ReceiptNumber` | string |  | yes | The receipt number as supplied when the receipt was created. |
| `ReceiptDate` | date |  | yes | yyyy-MM-dd date of the receipt. |
| `ReceiptMethod` | string |  | yes | Name of the receipt method the payment arrived by. |
| `Amount` | number |  | yes | Total amount received, in Currency. |
| `Currency` | string |  | yes | ISO 4217 currency of the receipt. |
| `State` | string |  | yes | APPLIED, UNAPPLIED, UNIDENTIFIED, REVERSE PAYMENT, INSUFFICIENT FUNDS or STOP PAYMENT. This child publishes State and NOT Status, unlike the top-level standardReceipts resource. |
| `UnappliedAmount` | number |  | yes | Cash on this receipt not yet applied to any transaction. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `standardReceiptApplications`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ApplicationId` | number |  | yes | Primary key of the application. |
| `StandardReceiptId` | number |  | yes | The receipt whose cash was applied. Read it at /standardReceipts/{StandardReceiptId}. |
| `ReceiptNumber` | string |  | yes | Receipt number of that receipt. |
| `ReferenceTransactionId` | number |  | yes | CustomerTransactionId of the invoice the cash was applied to. |
| `ReferenceTransactionNumber` | string |  | yes | TransactionNumber of that invoice. |
| `ReferenceInstallmentId` | number |  | yes | InstallmentId the application settled. Null once a reversal has detached it. |
| `ApplicationAmount` | number |  | yes | Amount applied, in EnteredCurrency. |
| `EnteredCurrency` | string |  | yes | ISO 4217 currency of the receipt this application came from. |
| `ApplicationDate` | date |  | yes | yyyy-MM-dd date the application was made. |
| `AccountingDate` | date |  | yes | yyyy-MM-dd accounting date of the application. |
| `ApplicationStatus` | string |  | yes | APP for an application in force, REV once reversed. Only APP rows reduce an invoice balance; a REV row is history. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed — whether the invoice still carries a balance. |
| `CreatedBy` | string |  | yes | Audit user that created the row. |
| `CreationDate` | datetime |  | yes | Audit creation timestamp. |
| `LastUpdatedBy` | string |  | yes | Audit user of the most recent change. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `transactionPaymentSchedules`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `InstallmentId` | number |  | yes | Primary key of the installment (payment schedule). |
| `InstallmentNumber` | number |  | yes | Sequence of this installment within its transaction. |
| `InstallmentStatus` | string |  | yes | Open or Closed. Note the receivablesInvoiceInstallments child publishes the same underlying state as OP or CL — each resource uses Oracle's vocabulary for itself, so do not carry a value across. |
| `PaymentScheduleDueDate` | date |  | yes | yyyy-MM-dd date this installment falls due. |
| `TotalOriginalAmount` | number |  | yes | Original amount of the installment, in EnteredCurrency. |
| `TotalBalanceAmount` | number |  | yes | Amount still outstanding on the installment. |
| `TransactionId` | number |  | yes | CustomerTransactionId of the transaction this installment belongs to. |
| `TransactionNumber` | string |  | yes | Transaction number of that transaction. |
| `TransactionDate` | date |  | yes | yyyy-MM-dd date the transaction bears. |
| `TransactionType` | string(20) |  | yes | Transaction type — Invoice, Credit Memo, and so on. |
| `EnteredCurrency` | string |  | yes | ISO 4217 currency the transaction was entered in. |
| `TransactionSourceName` | string |  | yes | Batch source the transaction was created under. Oracle's name for it on THIS child; the receivablesInvoices resource calls the same value TransactionSource. Not filterable and not sortable here - it is resolved from the transaction, not stored on the schedule row. |
| `PaymentDaysLate` | number |  | yes | Days this installment is past its due date, floored at zero, and zero for a closed installment. Computed on read from the same rule the receivablesInvoiceInstallments child uses, so the two agree. Not usable as a sort key for that reason. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `creditMemos`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CreditMemoId` | number |  | yes | Primary key of the credit memo. A credit memo is a transaction, so this is its CustomerTransactionId. |
| `CreditMemoNumber` | string |  | yes | Transaction number of the credit memo. |
| `CreditMemoDate` | date |  | yes | yyyy-MM-dd date the credit memo bears. |
| `CreditMemoCurrency` | string |  | yes | ISO 4217 currency of the credit memo. |
| `CreditMemoStatus` | string |  | yes | Open or Closed — whether the credit memo still carries a balance. Derived from the open balance rather than stored, so it can never disagree with TotalBalanceAmount. |
| `TotalOriginalAmount` | number |  | yes | Original amount of the credit memo, in CreditMemoCurrency. |
| `TotalBalanceAmount` | number |  | yes | Amount still remaining on the credit memo. |
| `TransactionType` | string(20) |  | yes | Always Credit Memo on this child. |
| `InstallmentId` | number |  | yes | The credit memo installment. Oracle publishes one; where a credit memo carries several schedules this reports the lowest installment number. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change. |

Each element of `creditMemoApplications`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ApplicationId` | number |  | yes | Primary key of the credit memo application. |
| `ApplicationAmount` | number |  | yes | Amount of the credit memo applied, in EnteredCurrency. |
| `ApplicationDate` | date |  | yes | yyyy-MM-dd date the credit memo was applied. |
| `ApplicationStatus` | string |  | yes | Whether the application is in force or has been reversed. The VALUE VOCABULARY for this attribute is not confirmed against Oracle — its page gives the attribute a length but no allowed-value list, and the sibling standardReceiptApplications child uses a different pair — so branch on the value you observe on your own instance rather than on a list published here. Recorded as unverified in the conformance ledger. |
| `CreditMemoId` | number |  | yes | The credit memo whose value was applied. Read it on the creditMemos child. |
| `CreditMemoNumber` | string |  | yes | Transaction number of that credit memo. |
| `CreditMemoStatus` | string |  | yes | Open or Closed — whether the credit memo still carries a balance. Derived from its open balance rather than stored. |
| `EnteredCurrency` | string |  | yes | ISO 4217 currency of the credit memo. |
| `ReferenceTransactionId` | number |  | yes | CustomerTransactionId of the transaction the credit memo was applied to. |
| `ReferenceTransactionNumber` | string |  | yes | Transaction number of that transaction. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed — whether the credited transaction still carries a balance. Derived, like CreditMemoStatus, but from a DIFFERENT transaction. |
| `ReferenceInstallmentId` | number |  | yes | The installment the application settled. Null once a reversal has detached it. |
| `LastUpdateDate` | datetime |  | yes | Audit timestamp of the most recent change, Oracle wire format. Maintained by the database and not settable. Use it as an incremental-sync watermark for credit memo applications - before migration 0084 this table had no such column and there was no watermark at this grain. |

Each element of `transactionsPaidByOtherCustomers`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ApplicationId` | number |  | yes | Primary key of the application. |
| `StandardReceiptId` | number |  | yes | The receipt that paid. |
| `ReceiptNumber` | string |  | yes | That receipt's number. |
| `ReceiptMethod` | string |  | yes | The receipt method used. The one attribute this child publishes that the sibling standardReceiptApplications child does not. |
| `ReferenceTransactionId` | number |  | yes | The transaction that was paid. |
| `ReferenceTransactionNumber` | string |  | yes | That transaction's number. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed - the status of the transaction the receipt was applied against, derived from its live open balance rather than stored. Not the invoice's completion status. |
| `ReferenceInstallmentId` | number |  | yes | The installment settled. |
| `ApplicationAmount` | number |  | yes | How much of the receipt landed here. |
| `ApplicationDate` | date |  | yes | When it was applied. |
| `AccountingDate` | date |  | yes | The accounting date of the application. |
| `ApplicationStatus` | string |  | yes | The application's status. |
| `EnteredCurrency` | string |  | yes | The receipt's currency. |
| `CreatedBy` | string |  | yes | Who created the application. |
| `CreationDate` | datetime |  | yes | When it was created. Oracle wire format. |
| `LastUpdatedBy` | string |  | yes | Who last updated it. |
| `LastUpdateDate` | datetime |  | yes | When it was last updated. Oracle wire format. |

Each element of `transactionAdjustments`:

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `AdjustmentId` | number |  | yes | Primary key of the adjustment. |
| `AdjustmentNumber` | string |  | yes | The number assigned to the adjustment. Oracle publishes a maximum length of 20. |
| `AdjustmentAmount` | number |  | yes | The amount adjusted. |
| `AdjustmentType` | string |  | yes | What part of the transaction is adjusted. Oracle's values: Charges, Freight, Invoice (transaction header), Line, Tax. |
| `AdjustmentReason` | string |  | yes | The reason code assigned to the adjustment. Oracle publishes no fixed list — reason codes are customer-defined lookups. |
| `ReferenceTransactionId` | number |  | yes | The adjusted transaction. |
| `ReferenceTransactionNumber` | string |  | yes | That transaction's number. |
| `ReferenceTransactionStatus` | string |  | yes | Open or Closed — the status of the transaction the adjustment is made against, derived from its live open balance rather than stored. |
| `ReferenceInstallmentId` | number |  | yes | The adjusted installment. Null for a header-level adjustment. |
| `BillToSiteNumber` | string |  | yes | The name of the customer bill-to site. |
| `AccountingDate` | date |  | yes | The accounting date of the adjustment. |
| `ApplicationDate` | date |  | yes | The application date of the adjustment. |
| `EnteredCurrency` | string |  | yes | The adjustment's currency code. |
| `CreatedBy` | string |  | yes | Who created the adjustment. |
| `CreationDate` | datetime |  | yes | When it was created. Oracle wire format. |
| `LastUpdatedBy` | string |  | yes | Who last updated it. |
| `LastUpdateDate` | datetime |  | yes | When it was last updated. Oracle wire format. |

#### Limitations

- Read-only. GET is the only method; anything else is refused 405.
- Oracle documents seven children here — creditMemoApplications, creditMemos, standardReceipts, standardReceiptApplications, transactionAdjustments, transactionPaymentSchedules and transactionsPaidByOtherCustomers. ALL SEVEN are implemented, on both the account and the site grain, and each is also embeddable with expand. Each child has its own attribute names, its own queryable set and its own finders — read the operation you are calling rather than assuming the parent's. Where an attribute Oracle publishes is not modelled here it is refused BY NAME with the reason, never accepted and ignored.
- Both totals are in the LEDGER currency, and the resource carries no currency attribute because Oracle defines none. Converting back to an invoice currency is the caller's problem.
- TotalOpenReceivablesForSite can be negative. That is not an error — it means unapplied cash exceeds what the customer owes.

## SOAP services

### InvoiceService

Endpoint: `https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService`

WSDL: `https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService?WSDL`

SOAP 1.1. Authentication: WS-Security UsernameToken (PasswordText profile).

#### createSimpleInvoice — supported

Creates an INCOMPLETE Receivables invoice with one or more invoice lines, using the same business rules as the REST create operation.

Request:

```xml
POST https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "createSimpleInvoice"

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken>
        <wsse:Username>YOUR_SOAP_USERNAME</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">YOUR_SOAP_PASSWORD</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>
  <soap:Body>
    <createSimpleInvoice xmlns="http://xmlns.oracle.com/apps/financials/receivables/transactions/invoices/invoiceService/">
      <invoiceHeaderInformation>
        <BusinessUnit>Vision Operations</BusinessUnit>
        <TransactionSource>MANUAL</TransactionSource>
        <TransactionType>Invoice</TransactionType>
        <TrxDate>2026-06-25</TrxDate>
        <BillToAccountNumber>0001001</BillToAccountNumber>
        <InvoiceCurrencyCode>USD</InvoiceCurrencyCode>
        <PaymentTermsName>IMMEDIATE</PaymentTermsName>
        <InvoiceLine>
          <LineNumber>1</LineNumber>
          <Description>Consulting</Description>
          <Quantity>10</Quantity>
          <UnitSellingPrice>125</UnitSellingPrice>
        </InvoiceLine>
      </invoiceHeaderInformation>
    </createSimpleInvoice>
  </soap:Body>
</soap:Envelope>
```

Response:

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <createSimpleInvoiceResponse xmlns="http://xmlns.oracle.com/apps/financials/receivables/transactions/invoices/invoiceService/">
      <result>
        <CustomerTrxId>300100000000123</CustomerTrxId>
        <ServiceStatus>SUCCESS</ServiceStatus>
        <TransactionNumber>INV-300100000000123</TransactionNumber>
      </result>
    </createSimpleInvoiceResponse>
  </soap:Body>
</soap:Envelope>
```

- The payload is Oracle's Receivables Invoice Header SDO, wrapped in invoiceHeaderInformation, and its attribute names are NOT the REST names. Where they differ: BillToAccountNumber (REST: BillToCustomerNumber), TrxDate (TransactionDate), PaymentTermsName (PaymentTerms), BillToLocation (BillToSite), InvoiceLine (receivablesInvoiceLines). TransactionType, TransactionSource, BusinessUnit, InvoiceCurrencyCode and BillToContact are spelled the same on both. This inconsistency is Oracle's own.
- DeliveryMethod and Email do not exist on the SOAP header SDO — they are REST-only attributes. A SOAP-created invoice takes the delivery method the server resolves.
- The response is Oracle's Receivables Invoice Result SDO: CustomerTrxId, ServiceStatus and TransactionNumber, and nothing else. Read the invoice back over REST for its amounts or status.
- DTDs and external entities are rejected (env:Client.DtdForbidden) to prevent XXE.

## Errors

Branch on the stable error CODE field shown in the example bodies below; message text is prose and may be reworded.

### Invalid bearer token (401)

**Means:** Token missing, malformed, expired or revoked. Also returned when the client_id belongs to a different environment. Every REST and SOAP call answers this without a valid bearer.

**Do:** Re-mint a token using a client_id that was created in THIS environment.

```json
{
  "title": "Unauthorized",
  "status": 401,
  "detail": "Bearer token required",
  "type": "https://docs.oracle.com/error/REST-01401",
  "o:errorCode": "REST-01401"
}
```

### Invalid OAuth client (401)

**Means:** client_id unknown, client_secret wrong, client revoked, or credential issued for another tenant's environment.

**Do:** Verify the client_id and client_secret. Confirm they were created in the simulator environment you are calling.

```json
{ "error": "invalid_client" }
```

### Missing required attributes — AR-1000 (invoices), FND_CMN_REQ_ATTRIB_API_SERV (receipts) (400)

**Means:** A required attribute was absent on a create. The two resources use DIFFERENT codes, which is Oracle's own inconsistency and not ours: receivablesInvoices answers AR-1000 and lists every missing attribute in o:errorDetails, while standardReceipts answers FND_CMN_REQ_ATTRIB_API_SERV — a shared Fusion framework code — and reports the FIRST missing attribute only, so a receipt missing three required values takes three round trips. Branch on both.

**Do:** Add every attribute named under o:errorPath and retry. On a receipt, expect to repeat: only one is reported at a time.

```json
{
  "title": "Bad Request",
  "status": 400,
  "o:errorCode": "AR-1000",
  "detail": "Missing required attributes",
  "o:errorDetails": [
    { "detail": "Attribute BusinessUnit is required", "o:errorPath": "/BusinessUnit" }
  ]
}
```

### Invalid q expression (400)

**Means:** Could not parse the q filter expression or it references an unknown field.

**Do:** Check operator names, quoting and field casing (Oracle fields are PascalCase).

```json
{ "title": "Bad Request", "status": 400, "o:errorCode": "REST-01000", "detail": "Invalid q expression: …" }
```

### Invoice not found (404)

**Means:** No receivables invoice with that CustomerTransactionId exists in this tenant.

**Do:** Verify the CustomerTransactionId and the environment URL.

```json
{ "title": "Not Found", "status": 404, "o:errorCode": "AR-7041", "detail": "Receivables invoice 300100000000123 not found" }
```

### Invalid state for the requested action (409)

**Means:** splitInstallments was called on an invoice that is not Complete, or one of whose installments is already closed.

**Do:** Split only a Complete invoice with no closed installment. Until 2026-08-04 this entry described a 409 from /action/complete instead; that action does not exist, and the code it named was emitted nowhere in the implementation.

```json
{ "title": "Conflict", "status": 409, "o:errorCode": "AR-2010", "detail": "Cannot split installments: invoice is not Complete" }
```

### Read-only attribute (400)

**Means:** PATCH attempted to modify a server-managed field.

**Do:** Remove the read-only field from the PATCH body.

```json
{ "title": "Bad Request", "status": 400, "o:errorCode": "AR-1020", "detail": "Attempt to update read-only attributes" }
```

### Method not allowed — REST-01001, REST-01405 (405)

**Means:** The HTTP method is not offered on that path. REST-01001 comes from a resource that offers other methods (PUT on receivablesInvoices, PATCH on receiptMethods); REST-01405 from one that is read-only or whose child accepts fewer methods (any write on contacts, PUT on a receipt, PATCH or DELETE on a remittance reference). The two are the same class and both are final — there is no variant of the request that succeeds.

**Do:** Read the capability matrix for the methods that resource offers. Neither code means 'try again'.

```json
{
  "title": "Method Not Allowed",
  "status": 405,
  "detail": "Method PUT not allowed on receivablesInvoices",
  "type": "https://docs.oracle.com/error/REST-01001",
  "o:errorCode": "REST-01001"
}
```

### Path, resource or child not implemented — REST-01100, REST-01101, REST-01102, REST-01004, REST-01005 (400 / 404)

**Means:** REST-01100: the URL root is neither fscmRestApi nor crmRestApi. REST-01101 (400): the API version segment is missing. REST-01102: the resource, child or action does not exist here — when Oracle DOES document it, the message says so by name, which is how you tell 'Oracle does not have this' from 'this simulator has not implemented it'. REST-01004: an unrecognised path under a child. REST-01005: an unknown or unimplemented named finder.

**Do:** Compare the path against the OpenAPI document. When the message names the thing as documented-by-Oracle, the gap is this simulator's and your code would work against a real pod.

```json
{
  "title": "Not Found",
  "status": 404,
  "detail": "creditMemos is documented by Oracle on receivablesCustomerAccountActivities but is not implemented in this simulator. Implemented child: standardReceiptApplications.",
  "type": "https://docs.oracle.com/error/REST-01102",
  "o:errorCode": "REST-01102"
}
```

### Receipt setup validation — AR_RAPI_BU_INVALID, AR_RAPI_CURR_CODE_INVALID, AR_INVAL_RECEIPT_MTH_ID, AR_BOE_OBSOLETE, AR_RCP_DUP_NUM (400)

**Means:** The receipt names a business unit, currency or receipt method the environment does not have, names a method that has been retired (AR_BOE_OBSOLETE), or repeats a receipt number with the same date, amount and customer (AR_RCP_DUP_NUM). These are Oracle's own message names.

**Do:** Discover the valid values first: GET /receiptMethods for methods, and the capability matrix for business units and currencies. A duplicate is a signal your retry already succeeded — read the existing receipt back rather than forcing a new one.

```json
{
  "title": "Bad Request",
  "status": 400,
  "detail": "The business unit Vision Ops is not valid.",
  "type": "https://docs.oracle.com/error/AR_RAPI_BU_INVALID",
  "o:errorCode": "AR_RAPI_BU_INVALID"
}
```

### Refused by lifecycle state — AR_RCP_UPDATE_NOT_ALLOWED, AR_RCP_DELETE_NOT_ALLOWED, AR_TRX_DELETE_NOT_ALLOWED, AR_TERMS_UPDATE_NOT_ALLOWED (400)

**Means:** The object exists and the request is well-formed; its current state forbids the change. A receipt with applications, or one accounted, frozen, reversed or automatic, cannot be updated or deleted. An invoice with receipt applications cannot be deleted. Payment terms cannot be changed once there is activity against an installment, once the invoice is posted to the GL, or when the customer profile disables term overrides. `detail` names which condition applied.

**Do:** Unapply or reverse first, or accept that the object is final. Nothing is silently undone to make the request succeed. AR_RCP_UPDATE_NOT_ALLOWED and AR_RCP_DELETE_NOT_ALLOWED are structural placeholders rather than confirmed Oracle message names — see the conformance notes.

```json
{
  "title": "Bad Request",
  "status": 400,
  "detail": "An invoice with receipt applications cannot be deleted.",
  "type": "https://docs.oracle.com/error/AR_TRX_DELETE_NOT_ALLOWED",
  "o:errorCode": "AR_TRX_DELETE_NOT_ALLOWED",
  "o:errorDetails": [
    { "detail": "Invoice 300100000000123 has 2 receipt application(s). Unapply them before deleting the invoice; it is never silently unapplied to make the delete succeed." }
  ]
}
```

### Attribute value not in the allowed set — AR-1021, AR-1030, AR-1031, AR-1034 (400)

**Means:** AR-1021: InvoiceStatus is not one of Complete, Incomplete, Frozen. AR-1030: the currency or payment terms are not defined or not enabled here. AR-1031: BillToContact did not match an active contact of the bill-to customer — it is a NAME, and an id returns this. AR-1034: BillToSite did not match an active bill-to site use of the account. `o:errorDetails[].o:errorPath` names the attribute.

**Do:** Read the allowed values from the resource reference, or list the relevant resource (/crmRestApi/.../contacts, /customerAccountSitesLOV) and use a value from it. None of these is silently defaulted.

```json
{
  "title": "Bad Request",
  "status": 400,
  "detail": "InvoiceStatus must be one of Complete, Incomplete, Frozen",
  "type": "https://docs.oracle.com/error/AR-1021",
  "o:errorCode": "AR-1021",
  "o:errorDetails": [
    { "detail": "Invalid InvoiceStatus: Posted", "o:errorPath": "/InvoiceStatus" }
  ]
}
```

### Server error — REST-50000 (500)

**Means:** A failure on this side, not in your request, reported as REST-50000. It is not caused by anything in the payload — caller mistakes are mapped to 400 REST-01002 rather than surfacing as a 500.

**Do:** Retry with backoff. If it persists the request is not at fault; the detail is safe to report verbatim, as no internal identifier is included in it.

```json
{
  "title": "Internal Server Error",
  "status": 500,
  "detail": "The receipt could not be read.",
  "type": "https://docs.oracle.com/error/REST-50000",
  "o:errorCode": "REST-50000"
}
```

### WS-Security authentication failed (401)

**Means:** Missing UsernameToken, wrong password, or credential belongs to another environment.

**Do:** Verify the SOAP username and password were minted in THIS environment.

```xml
<soap:Fault>
  <faultcode>env:Client.AuthFailed</faultcode>
  <faultstring>Invalid credentials</faultstring>
</soap:Fault>
```

### Malformed SOAP / DTD forbidden (400)

**Means:** Body is not a valid SOAP 1.1 envelope, or contains a DTD/external entity (rejected for XXE protection).

**Do:** Send a well-formed SOAP envelope with no DOCTYPE declaration.

```xml
<soap:Fault>
  <faultcode>env:Client.DtdForbidden</faultcode>
  <faultstring>DOCTYPE declarations are not permitted</faultstring>
</soap:Fault>
```

### Unknown environment (404)

**Means:** The {environmentKey} segment in the URL does not match any simulator environment.

**Do:** Re-copy the environment URL from ERP simulator → Environment key.

```json
{ "title": "Not Found", "status": 404, "detail": "Unknown environment" }
```

## External provider integration guide

This guide is a self-contained, step-by-step reference for an external application that needs to connect to a deployed Oracle Fusion Cloud ERP simulator tenant and exercise every implemented capability. It covers connection details, authentication (OAuth 2.0 client credentials for REST, WS-Security UsernameToken for SOAP), every REST resource and SOAP operation, the q filter grammar, pagination, error handling, the receipts/installments lifecycle and a production-readiness checklist. Every URL, header, field and code sample reflects the deployed simulator behavior. Replace YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, SOAP_USERNAME and SOAP_PASSWORD with credentials you mint from ERP simulator settings.

### 1. Simulator overview

The simulator implements the externally observable patterns of Oracle Fusion Cloud ERP Financials. Every tenant has its own isolated dataset and its own immutable environment key. A request can only reach the data of the tenant whose environment key appears in the URL; credentials minted for tenant A cannot authenticate against tenant B's URL.

Implemented surfaces: OAuth 2.0 token endpoint, REST resources receivablesInvoices (full CRUD + actions + child collections), contacts (read-only), customerAccountSitesLOV (read-only), and one SOAP service InvoiceService with the createSimpleInvoice operation. Standard receipts and receipt applications exist in the data model and the in-app UI but are NOT exposed as external REST/SOAP endpoints in this phase.

- API version segment in every REST URL: 11.13.18.05.
- All payloads are UTF-8; REST is JSON, SOAP is XML 1.0.
- Identifiers (CustomerTransactionId, ContactPointId, CustomerAccountSiteId, etc.) are decimal integer strings; preserve them as strings or 64-bit integers — JavaScript Number loses precision beyond 2^53.
- Dates are ISO-8601 (YYYY-MM-DD for date fields, full timestamp for LastUpdateDate).

### 1b. Default seeded dataset

Every Oracle Fusion tenant is provisioned with the same deterministic, idempotent dataset. The same dataset is recreated whenever a tenant performs a destructive ERP reset and provisions Oracle Fusion again, so external integrations can rely on the scenario coverage below.

Customer accounts: 25 accounts (mix of ORGANIZATION and PERSON parties), each with one party site, a primary BILL_TO and SHIP_TO site use, and 1–3 contacts (the first contact is primary and BILL_TO).

Receivables invoices: 27 in total — 24 across the scenario matrix below, plus three coverage rows described after it (the four credit memos that settle scenario 6 are separate transactions and are NOT returned by receivablesInvoices) — exactly 6 per currency for each of ILS, USD, GBP and EUR. The per-currency breakdown is identical and covers the full Oracle Fusion invoice lifecycle:

  | # | InvoiceStatus | Installments | Payment scenario                                       |
  | - | ----------------- | ------------ | ------------------------------------------------------ |
  | 1 | COMPLETE          | 1            | Fully open (single installment, due in the future)     |
  | 2 | COMPLETE          | 1            | Fully paid (single installment closed, InvoiceBalanceAmount=0)  |
  | 3 | COMPLETE          | 2            | Partially paid (installment 1 closed, installment 2 OP)|
  | 4 | COMPLETE          | 3            | Overdue (all three installments OP, due dates in past) |
  | 5 | INCOMPLETE        | 0            | Draft, no installments yet                             |
  | 6 | COMPLETE          | 1            | Credited to zero by a credit memo - never paid  |

Receipts and applications fully reconcile: every paid or partially paid invoice has a corresponding standardReceipts record with State APPLIED and a matching Standard Receipt Application linked to the correct installment. The simulator also seeds a small mix of UNAPPLIED and UNIDENTIFIED receipts so the receipts list has realistic variety. Every seeded receipt carries Status CONFIRMED — State and Status are independent dimensions, so an APPLIED receipt is not automatically CLEARED.

Coverage rows (3 more, beyond the 24 above), added because an integrator's money handling and cancellation logic cannot be exercised by 2-decimal invoices alone:
• One JPY invoice, 150000 JPY. JPY carries precision 0, so a consumer that assumes two decimals reports this 100x wrong — silently, because the amount is otherwise valid.
• One KWD invoice, 1234.567 KWD. KWD carries precision 3, and the third decimal is deliberately non-zero so a 2-decimal conversion cannot pass by accident.
• One voided transaction: TransactionType 'Void', InvoiceBalanceAmount 0, and it is NOT an open receivable. WARNING for any consumer that DERIVES an installment when an invoice has no payment schedule: a voided transaction now has none, so that rule would synthesise an installment carrying the full original amount for a cancelled transaction. Gate it on collectibility (InvoiceStatus Complete AND InvoiceBalanceAmount > 0). It has NO installments — Oracle deletes the payment schedule when a transaction is voided, so there is nothing left to collect against. Collectibility follows the TRANSACTION TYPE and the header balance, never a scan of installments. (Until August 2026 this simulator kept the schedule, so the row reported InvoiceBalanceAmount 0 beside an 'OP' installment with a non-zero balance. That contradiction was ours, not Oracle's, and is gone.)

Determinism: amounts, dates and the choice of customer for each invoice are derived from the tenant id, so re-running provisioning never produces a different dataset and never creates duplicates. Tenant isolation is enforced at every level — credentials, environment key and data are scoped to the tenant that provisioned them.

- Total invoices per tenant: 24 (4 currencies × 6 scenarios).
- Per currency: 5 COMPLETE + 1 INCOMPLETE. The sixth is completed and then credited to zero by a credit memo, so the dataset covers an invoice that owes nothing without anyone having paid it.
- Per currency installment distribution across the 4 COMPLETE invoices: [1, 1, 2, 3].
- Every COMPLETE invoice satisfies InvoiceBalanceAmount == SUM(installments.InstallmentBalanceDue).
- INCOMPLETE invoices have zero installments — installments are only created once an invoice reaches COMPLETE.
- A reset followed by re-provisioning produces the same dataset (idempotent by tenant id).
- Every seeded contact email uses the deterministic pattern `ido.dubovi+erplab{N}@gmail.com`, where N is a per-tenant running number starting at 1 (unique across all seeded contacts). The invoice `Email` field inherits from the resolved primary bill-to contact, so seeded invoice delivery emails follow the same pattern.

### 2. Connection details

All URLs are derived from one instance URL. The environment key (env_…) is part of the path, not a credential. Copy the four base URLs below into your integration configuration:

| Name | Description |
| --- | --- |
| `Instance URL` | https://erplab.cloud/sim/{environmentKey} |
| `REST base URL` | https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05 |
| `SOAP base URL` | https://erplab.cloud/sim/{environmentKey}/soap |
| `OAuth token URL` | https://erplab.cloud/sim/{environmentKey}/oauth/token |
| `Environment key` | {environmentKey} (immutable; rotating it requires a full ERP reset) |
| `API version` | 11.13.18.05 |

EXAMPLES THAT USE $TOKEN ASSUME YOU RAN THE TOKEN STEP IN THE SAME SHELL. The authentication section assigns TOKEN=$(...); every later example that sends "Authorization: Bearer $TOKEN" depends on that assignment still being in your environment. Copy a later block on its own and it sends an empty bearer and answers 401. IDENTIFIERS IN EXAMPLES ARE ILLUSTRATIVE. Every numeric id shown in this document - CustomerTransactionId, StandardReceiptId, AccountId and the rest - is a sample value, not a row in your tenant, and pasting one verbatim returns 404. Obtain real ids from the corresponding list endpoint first: GET the collection, read the id from the response, then substitute it. The Full lifecycle example in the integration guide does exactly this end to end and is the one to copy if you want something that runs unchanged. Placeholders in braces, such as {environmentKey}, are different: substitute those from the connection table above. If you reset the ERP simulator from the Danger zone, all environment keys, OAuth clients, SOAP credentials, tokens and seed data are regenerated. Update your integration with the new values before reconnecting.

### 3. REST authentication — OAuth 2.0 client credentials

Mint an OAuth client from ERP simulator settings → OAuth 2.0 clients → New client. The client secret is shown exactly once at creation time; store it in your secret manager immediately. The simulator only implements the client_credentials grant.

Request the token with Content-Type: application/x-www-form-urlencoded. You may pass client_id and client_secret in the form body, OR as HTTP Basic auth (base64(client_id:client_secret) in the Authorization header). Tokens are opaque bearer values, valid for 3600 seconds, and must be sent on every REST call as Authorization: Bearer <token>.

scope is REQUIRED. Oracle marks it required on the client_credentials grant - the same marker it puts on grant_type, with one carve-out that does not apply here ("For the refresh_token grant type, scope is optional") - and this endpoint refuses a request without it with 400 invalid_request. It was optional here until 2026-08-04, which let code be written against this simulator that a real environment rejects. Send urn:opc:resource:consumer::all against the simulator. Against a real Oracle environment send the value configured on the resource application in your identity domain, which is environment-specific (Oracle's own form is urn:opc:resource:fa:<instanceid>=<podname>). Two refusals to know about, both 400 invalid_scope: a scope wider than the one granted to your client, and urn:opc:resource:consumer::all combined with any other scope - Oracle requires the all-resources scope to be requested on its own.

**curl — form body**

```bash
curl --request POST "https://erplab.cloud/sim/{environmentKey}/oauth/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=urn:opc:resource:consumer::all" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
```

**curl — HTTP Basic**

```bash
curl --request POST "https://erplab.cloud/sim/{environmentKey}/oauth/token" \
  --user "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=urn:opc:resource:consumer::all"
```

**Node.js (fetch)**

```javascript
const tokenRes = await fetch("https://erplab.cloud/sim/{environmentKey}/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "client_credentials",
    scope: "urn:opc:resource:consumer::all",
    client_id: process.env.ORACLE_CLIENT_ID,
    client_secret: process.env.ORACLE_CLIENT_SECRET,
  }),
});
if (!tokenRes.ok) throw new Error(`OAuth failed: ${tokenRes.status}`);
const { access_token, expires_in } = await tokenRes.json();
```

**Python (requests)**

```python
import os, requests

resp = requests.post(
    "https://erplab.cloud/sim/{environmentKey}/oauth/token",
    data={
        "grant_type": "client_credentials",
        "scope": "urn:opc:resource:consumer::all",
        "client_id": os.environ["ORACLE_CLIENT_ID"],
        "client_secret": os.environ["ORACLE_CLIENT_SECRET"],
    },
    headers={"Content-Type": "application/x-www-form-urlencoded"},
    timeout=10,
)
resp.raise_for_status()
access_token = resp.json()["access_token"]
```

### 4. Token caching and refresh

Tokens are valid for 3600 seconds. Cache the token in memory (or in a shared cache for multi-instance deployments) and re-mint when it is within ~5 minutes of expiry. The simulator does NOT implement RFC 7662 token introspection, refresh tokens or token revocation endpoints; just request a new token when the old one expires or any call returns 401 REST-01401.

**Minimal token cache**

```javascript
let cached = { token: null, expiresAt: 0 };

async function getToken() {
  const now = Date.now();
  if (cached.token && now < cached.expiresAt - 300_000) return cached.token;
  const r = await fetch("https://erplab.cloud/sim/{environmentKey}/oauth/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "client_credentials",
      scope: "urn:opc:resource:consumer::all",
      client_id: process.env.ORACLE_CLIENT_ID,
      client_secret: process.env.ORACLE_CLIENT_SECRET,
    }),
  });
  if (!r.ok) throw new Error(`OAuth ${r.status}`);
  const j = await r.json();
  cached = { token: j.access_token, expiresAt: now + j.expires_in * 1000 };
  return cached.token;
}
```

### 5. SOAP authentication — WS-Security UsernameToken

Mint a SOAP credential from ERP simulator settings → SOAP credentials. The password is shown once at creation and bcrypt-hashed before it ever reaches the server. SOAP calls must carry a wsse:Security header with a wsse:UsernameToken using the PasswordText profile. PasswordDigest and SAML are NOT supported — using PasswordDigest returns env:Client.PasswordTypeUnsupported.

**Security header template**

```xml
<soapenv:Header>
  <wsse:Security soapenv:mustUnderstand="1"
                 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken>
      <wsse:Username>SOAP_USERNAME</wsse:Username>
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SOAP_PASSWORD</wsse:Password>
    </wsse:UsernameToken>
  </wsse:Security>
</soapenv:Header>
```

### 6. Your first request — list receivables invoices

After minting a token, confirm connectivity by listing the first page of receivables invoices. A successful response is HTTP 200 with an items array.

**curl**

```bash
TOKEN=$(curl -s "https://erplab.cloud/sim/{environmentKey}/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET" \
  | jq -r .access_token)

curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=5" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

### 7. Resource: receivablesInvoices — pull, create and maintain invoices

This section explains how to pull, create and maintain Receivables Invoices (Oracle Fusion "customer transactions") from the deployed simulator. It reflects actual implemented behavior — not planned functionality.

Concepts

A receivablesInvoices row represents one AR customer transaction (TransactionType = 'Invoice'). Every invoice has:
  • Header fields (customer, currency, payment terms, delivery method, dates).
  • One or more receivablesInvoiceLines (child collection) whose extended amounts sum to EnteredAmount.
  • InvoiceStatus is one of Oracle's three values - Complete, Incomplete, Frozen. A CREATED invoice is always Complete: the attribute defaults to Complete and Oracle requires that value on create. Incomplete and Frozen are legitimate stored states (the seeded dataset contains both). Neither is reachable through POST, but BOTH are reachable through PATCH - InvoiceStatus is the one status attribute Oracle lets you change. There is no /action/complete; it returns 404.
  • A server-maintained InvoiceBalanceAmount equal to SUM(InstallmentBalanceDue) across all installments.
  • At least one receivablesInvoiceInstallments row once COMPLETE (see section 13).

Lifecycle status table:
  | InvoiceStatus | Meaning                                                       |
  | ----------------- | ------------------------------------------------------------- |
  | INCOMPLETE        | Draft. POST cannot create one, but PATCH can set it. No installments - Oracle creates payment schedules when a transaction is COMPLETED, so an Incomplete invoice has nothing to collect against. |
  | COMPLETE          | Posted. Installments are active. PATCH is still allowed on the same three attributes as when Incomplete (InvoiceStatus, PaymentTerms, TransactionDate) - Oracle does not restrict its PATCH surface by status, and neither does this simulator. Lines are fixed. |

Endpoint

  GET    https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices                                                 — list (paginated)
  POST   https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices                                                 — create (requires ≥1 receivablesInvoiceLines)
  GET    https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}                                 — retrieve
  PATCH  https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}                                 — partial update of mutable fields
  DELETE https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}                                — delete an invoice (204, no body)
  POST   https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/action/splitInstallments        — replace payment schedule
  GET    https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceLines              — list invoice lines
  GET    https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments  — list installments

No PUT. DELETE is implemented and answers 204 with no body, as Oracle documents; an invoice that already has receipt applications is refused rather than silently unapplied. EnteredAmount and InvoiceBalanceAmount are server-computed; you cannot set them.

Authentication

Use OAuth 2.0 Bearer (see sections 3-4). Send Authorization: Bearer <access_token> on every call.

| Name | Description |
| --- | --- |
| `CustomerTransactionId` | number — Primary key. Generated server-side, read-only. |
| `TransactionNumber` | string — Auto-generated as INV-<CustomerTransactionId> on create. Read-only. |
| `TransactionDate` | YYYY-MM-DD — Transaction (accounting) date. Defaults to today on create. |
| `BusinessUnit` | string — Required on create. |
| `TransactionType` | string — Required on create (e.g. 'Invoice'). |
| `TransactionSource` | string — tenant configuration, not an Oracle constant: a real pod has whatever batch sources its implementers defined. This tenant seeds exactly one, MANUAL, and every seeded invoice uses it. string — Required on create (e.g. 'MANUAL'). |
| `InvoiceCurrencyCode` | string — Required on create (ISO 4217). |
| `PaymentTerms` | string — Defaults to 'IMMEDIATE' when omitted. |
| `DueDate` | YYYY-MM-DD — Header-level due date. Per-installment due dates live on receivablesInvoiceInstallments. |
| `EnteredAmount` | number — Server-computed = SUM(receivablesInvoiceLines.extendedAmount). Read-only. |
| `InvoiceBalanceAmount` | number — Server-maintained = SUM(installments.InstallmentBalanceDue). Read-only. 0 means the invoice is fully paid; > 0 means there is still amount due. |
| `InvoiceStatus` | Complete on create - Oracle requires that value. Updatable afterwards: PATCH accepts InvoiceStatus, PaymentTerms and TransactionDate, and InvoiceStatus takes any of Complete, Incomplete or Frozen. |
| `BillToCustomerNumber` | string(30) — the bill-to customer's ACCOUNT NUMBER. Required on create, and returned on read. This is the value to pass back as CustomerAccountNumber when recording a receipt. |
| `BillToCustomerName` | string(360) — the bill-to customer name. Read-only. |
| `BillToSite` | string(150) — the bill-to customer site. Read-only. |
| `BillToContact` | string(360) — the bill-to contact. Read-only. |
| `BillToPartyId` | number — the internal party identifier. Read-only. Not an account number; do not send it as CustomerAccountNumber. |
| `BillToContact` | string(360) — Optional. The contact NAME, not an identifier. Must belong to the resolved account and be active; an unmatched or inactive name is rejected with AR-1031. |
| `DeliveryMethod` | 'E-Mail' \| 'Paper' \| 'XML' — Validated. Default 'Paper'. |
| `Email` | string — Override delivery email. Delivery email override, set on create. |
| `LastUpdateDate` | timestamptz — Last server-side change. Use for change-detection / sync watermarks. |
| `links` | array — HATEOAS links: self, canonical, child (receivablesInvoiceLines, receivablesInvoiceInstallments), action (complete, splitInstallments). |

**Pull one page of invoices**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=25&offset=0&orderBy=CustomerTransactionId:asc" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

**Pull a single invoice with its lines and installments**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000008" -H "Authorization: Bearer $TOKEN" | jq .
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000008/child/receivablesInvoiceLines" -H "Authorization: Bearer $TOKEN" | jq .
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000008/child/receivablesInvoiceInstallments" -H "Authorization: Bearer $TOKEN" | jq .
```

**Example response — single invoice**

```json
{
  "CustomerTransactionId": 300100000000008,
  "TransactionNumber": "INV-300100000000008",
  "TransactionDate": "2026-05-28",
  "DueDate": "2026-06-28",
  "BusinessUnit": "Vision Operations",
  "TransactionType": "Invoice",
  "TransactionSource": "MANUAL",
  "InvoiceCurrencyCode": "USD",
  "PaymentTerms": "NET30",
  "EnteredAmount": 577.00,
  "InvoiceBalanceAmount": 577.00,
  "InvoiceStatus": "Complete",
  "BillToCustomerNumber": "0001001",
  "BillToCustomerName": "Globex Corporation #1",
  "BillToPartyId": 300100000000000,
  "BillToSite": "HQ — Berlin",
  "BillToContact": "John Davis",
  "DeliveryMethod": "E-Mail",
  "Email": null,
  "LastUpdateDate": "2026-06-26T21:26:13.877839+00:00",
  "links": [
    { "rel": "self",      "href": ".../receivablesInvoices/300100000000008" },
    { "rel": "canonical", "href": ".../receivablesInvoices/300100000000008" },
    { "rel": "child",     "href": ".../receivablesInvoices/300100000000008/child/receivablesInvoiceLines" },
    { "rel": "child",     "href": ".../receivablesInvoices/300100000000008/child/receivablesInvoiceInstallments" },
    { "rel": "action",    "href": ".../receivablesInvoices/300100000000008/action/splitInstallments" }
  ]
}
```

**Pull all open invoices for a customer (q filter)**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=BillToPartyId=300100000000021;InvoiceStatus='Complete';InvoiceBalanceAmount>0" \
  --data-urlencode "fields=CustomerTransactionId,TransactionNumber,DueDate,EnteredAmount,InvoiceBalanceAmount" \
  --data-urlencode "orderBy=DueDate:asc"
```

**Create an invoice**

```bash
curl -s -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "BusinessUnit": "Vision Operations",
    "TransactionType": "Invoice",
    "TransactionSource": "MANUAL",
    "BillToCustomerNumber": "0001001",
    "InvoiceCurrencyCode": "USD",
    "PaymentTerms": "NET30",
    "DeliveryMethod": "E-Mail",
    "receivablesInvoiceLines": [
      { "LineNumber": 1, "Description": "Consulting", "Quantity": 10, "UnitSellingPrice": 150.00 }
    ]
  }'
```

**No completion step - the invoice is already Complete**

```bash
# POST /receivablesInvoices returns an invoice with InvoiceStatus "Complete"
# and its installments already generated. Oracle has no complete action and
# neither does this simulator: /action/complete answers 404.
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001" \
  -H "Authorization: Bearer $TOKEN" | jq '.InvoiceStatus'
```

**Patch an updatable field (PaymentTerms, TransactionDate, InvoiceStatus)**

```bash
curl -s -X PATCH "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "PaymentTerms": "Net 30", "TransactionDate": "2026-08-15" }'
```

Pagination, filtering, field selection

limit (default 25, max 500), offset (default 0), totalResults=true, onlyData=true, orderBy=Field:asc|desc, fields=Col1,Col2. q-filterable fields are exactly those Oracle marks x-queryable: CustomerTransactionId, TransactionNumber, InvoiceStatus, InvoiceBalanceAmount, BillToPartyId, DeliveryMethod, Email, LastUpdateDate. Anything else is refused 400, including TransactionDate, DueDate, EnteredAmount, BillToCustomerNumber, InvoiceCurrencyCode, PaymentTerms, TransactionType, TransactionSource and BusinessUnit — a real pod rejects those too, so a filter that works here works there. Filter a customer's invoices by BillToPartyId, and sync incrementally on LastUpdateDate.

How to determine what is open / paid / due
  • Open invoices: q=InvoiceStatus='Complete';InvoiceBalanceAmount>0
  • Fully paid invoices: q=InvoiceStatus='Complete';InvoiceBalanceAmount=0
  • Overdue today: combine InvoiceBalanceAmount>0 with DueDate<=<today>, OR query installments (section 13) for per-installment precision.
  • Total amount due now for a customer: SUM(InvoiceBalanceAmount) over the query above.

Integration patterns for an external collection/payment provider
  1. Re-read the invoice before quoting an amount: an InvoiceBalanceAmount of 0 means "nothing left to collect."
  2. Prefer the installments collection (section 13) over the header InvoiceBalanceAmount when offering per-due-date payment.
  3. Cap any collection at InvoiceBalanceAmount — over-application of a future receipt is rejected server-side.
  4. Use LastUpdateDate as a sync watermark: q=LastUpdateDate>'<ISO8601>'  (URL-encode).

Limitations
  • PATCH updates only InvoiceStatus, PaymentTerms and TransactionDate; every other attribute is rejected with 400 AR-1020.
  • DELETE is implemented, matching Oracle's documented operation: 204 with no response body. One restriction that Oracle's page does NOT state and this simulator adds deliberately - an invoice carrying receipt applications is refused with 400 AR_TRX_DELETE_NOT_ALLOWED rather than deleted, because cascading would destroy the record of where a customer's money went. Unapply first. Oracle documents no preconditions at all, which is an absence of documentation rather than a documented absence, so verify against a real instance before relying on either behaviour. Oracle also documents the approve and rework actions, which are not implemented here.
  • Only TransactionType='Invoice' is exercised; credit memos, debit memos, deposits and guarantees are present in the data model but not creatable via this endpoint.
  • There is no /action/complete: an invoice is Complete when POST returns, and the endpoint answers 404. Oracle documents approve, rework and splitInstallments; only splitInstallments is implemented.

### 8. Resource: contacts (read-only) — on the CX base, keyed by PartyNumber

This section describes the contacts resource as it is actually served. It was rewritten on 2026-08-04: every endpoint, key, attribute and sample below had drifted from the implementation when contacts moved to Oracle's CX base, and the old text pointed at a path that answers 404.

Where contacts live

Oracle Financials has NO contacts resource. Contacts are served where Oracle serves them, on the CX base:
  GET  https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts                                    - list (paginated, q-filter or finder)
  GET  https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}                      - retrieve one, keyed by PartyNumber
  GET  https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint   - the person's channels
  GET  https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/{PartyNumber}/child/ContactPoint/{ContactPointId}

The Financials path answers a plain 404, exactly as a real pod does for a resource it does not have. Add ?expand=ContactPoint to embed the channels in the parent instead of making a second call.

What a row is

A contact IS a person party. Its key is PartyId, with PartyNumber as the public identifier used in the item path. The channels (EMAIL, PHONE) are a child collection, not columns on the parent - that is Oracle's shape, and it is why there is no ContactPointId, PhoneNumber or PrimaryFlag on a contact here.

There is no customer-account finder and no customer-account filter

Oracle documents six named finders on this resource - PrimaryKey, ContactPartyNumberRF, MyContacts, MyBusinessContacts, MyFavoriteContacts and SourceSystemReferenceAltKey - and none of them selects by customer account. Oracle's own route to a customer's contacts is accounts/{PartyNumber}/child/accountContact, which this simulator does not implement. This page previously published a customer-account finder and a q=CustomerAccountId= filter. Neither exists in Oracle and neither has ever worked here - both return 400.

How to set BillToContact on an invoice

BillToContact is a NAME, not an id. Read ContactName from this resource and pass that string. A name that does not resolve to an active contact of the bill-to customer is rejected with AR-1031 rather than silently dropped, and sending a numeric contact identifier is rejected with AR-1031. Omitting BillToContact is usually the better choice: an active bill-to contact carrying an email address is resolved server-side.

Authentication

OAuth 2.0 Bearer - same flow as section 3.

| Name | Description |
| --- | --- |
| `PartyId` | number - Primary key. The person party. |
| `PartyNumber` | string - Public identifier. This is the key in the item path, not PartyId. |
| `ContactName` | string \| null - Full display name. This is the value to pass as BillToContact. |
| `ContactUniqueName` | string \| null - Oracle carries a disambiguator here; this simulator has nothing to disambiguate with, so it repeats ContactName. |
| `FirstName` | string \| null - Given name when known. |
| `LastName` | string \| null - Family name when known. |
| `JobTitle` | string \| null - Free-text job title. |
| `EmailAddress` | string \| null - Lowercased on storage. Required for DeliveryMethod='E-Mail'. |
| `WorkPhoneNumber` | string \| null - Oracle splits phones by purpose. The seeded number is a work number. |
| `MobileNumber` | null - Present and null rather than absent: an absent attribute reads as unsupported. |
| `HomePhoneNumber` | null - As above. |
| `FaxNumber` | null - As above. |
| `PartyStatus` | 'A' \| 'I' - Active / Inactive. An inactive contact used on invoice create is rejected with AR-1031 — the lookup only considers active contacts, so it is reported as 'not an active contact', not as a separate inactive code. |
| `PartyType` | 'PERSON' - Constant. Organisation parties are not surfaced here. |
| `AccountPartyId` | number \| null - The customer account this person is a contact for. Readable, but NOT filterable - see above. |
| `links` | array - HATEOAS: self, canonical, and a child link to ContactPoint. |

**List contacts, with their channels embedded**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "expand=ContactPoint" \
  --data-urlencode "limit=25"
```

**Filter on the attributes that are actually queryable**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=PartyStatus='A'" \
  --data-urlencode "fields=PartyNumber,ContactName,EmailAddress,PartyStatus"
```

**The two finders this simulator implements**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts?finder=PrimaryKey;PartyId=100100000000007" \
  -H "Authorization: Bearer $TOKEN" | jq .

curl -s "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts?finder=ContactPartyNumberRF;PartyNumber=CDRM-300100000000100" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

**Retrieve one contact, by PartyNumber**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts/CDRM-300100000000100?expand=ContactPoint" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

**Example response — one contact, channels expanded**

```json
{
  "PartyId": 100100000000007,
  "PartyNumber": "CDRM-300100000000100",
  "ContactName": "Jane Doe",
  "ContactUniqueName": "Jane Doe",
  "FirstName": "Jane",
  "LastName": "Doe",
  "JobTitle": "AP Manager",
  "EmailAddress": "jane.doe@vision.example",
  "WorkPhoneNumber": "+1-415-555-0143",
  "MobileNumber": null,
  "HomePhoneNumber": null,
  "FaxNumber": null,
  "PartyStatus": "A",
  "PartyType": "PERSON",
  "AccountPartyId": 200100000000001,
  "ContactPoint": [
    {
      "ContactPointId": 400100000000003,
      "ContactPointType": "EMAIL",
      "PrimaryFlag": true
    }
  ],
  "links": [
    { "rel": "self", "href": ".../contacts/CDRM-300100000000100" }
  ]
}
```

Pagination, filtering, field selection

limit (default 25, max 500), offset, totalResults=true, onlyData=true, orderBy=Field:asc|desc, fields=Col1,Col2, expand=ContactPoint, links=self.

q-filterable attributes are exactly: PartyId, FirstName, LastName, JobTitle, EmailAddress, PartyStatus. Anything else is refused 400 rather than ignored. This list once advertised eight attributes the handler does not support - ContactPointId, CustomerAccountId, CustomerAccountNumber, ContactName, PhoneNumber, PrimaryFlag, Status and LastUpdateDate - and four of those are not queryable in Oracle either. Filter a person's channels through the ContactPoint child.

Finders
  Implemented:  PrimaryKey;PartyId=<id>  and  ContactPartyNumberRF;PartyNumber=<number>
  Documented by Oracle, not implemented here: MyContacts, MyBusinessContacts, MyFavoriteContacts, SourceSystemReferenceAltKey. Each is refused 400 naming the finder.
  One more name was published on this page and is not an Oracle finder at all; it has never worked and has been removed.

How to find the right contact for an invoice
  1. List contacts and read ContactName - there is no customer-account filter, here or in Oracle.
  2. Pass that NAME as BillToContact on POST /receivablesInvoices. Not an id: a numeric value returns AR-1031.
  3. Or omit BillToContact and let the server resolve an active bill-to contact carrying an email address.
  4. If DeliveryMethod='E-Mail', confirm EmailAddress is non-null, or the invoice has no resolvable recipient.

Limitations
  - Read-only. POST/PATCH/PUT/DELETE return 405.
  - LastUpdateDate IS emitted and filterable, so this resource supports incremental sync. It carried no watermark until 2026-08-05, which forced a full re-read on every pull.
  - EMAIL and PHONE are the only channel types surfaced, and only a work phone is populated.
  - Soft-deleted party rows are filtered out; you will never see them here.

### 9. Resource: customerAccountSitesLOV (read-only) — discover a customer site names

This section explains how to list a customer account sites from the deployed simulator. It reflects actual implemented behavior - not planned functionality.

What this resource is

customerAccountSitesLOV is Oracle customer-account-sites LIST OF VALUES. One row per customer account SITE USE, keyed by SiteUseId. Its purpose is to let you discover the site names that can be passed as BillToSite when creating an invoice.

It is deliberately narrow, and it is narrow in Oracle too:
  - No address. There is no City, Country, PostalCode, Address1 or LocationId on this resource, so address data is not reachable through this API at all. It exists in the simulator and is visible in the workspace UI.
  - No SiteUseCode. You cannot tell a BILL_TO use from a SHIP_TO use here, and a customer may have PrimarySite=Y on more than one of them.
  - No Status. Only active site uses are returned.

How to bill an invoice to the right site

Omit BillToSite on POST /receivablesInvoices. The primary bill-to site use is resolved server-side, which is the reliable route now that BILL_TO and SHIP_TO are indistinguishable through this resource. BillToSite is optional in Oracle too.

If you do pass BillToSite, pass a SiteName value from this resource - the invoice resource identifies the site by NAME, not by id. There is no BillToSiteUseId attribute on receivablesInvoices in Oracle, and sending one is rejected with 400 AR-1020 naming BillToSite instead. It used to be silently ignored, which meant a caller who asked for a specific address quietly got a different one. A name that does not resolve to an active bill-to site use on that account is rejected with 400 AR-1034 rather than silently ignored.

Endpoint

  GET  https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV                 - list (paginated, q-filterable)
  GET  https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV/{SiteUseId}     - retrieve one

No POST, PATCH, PUT or DELETE: Oracle documents only GET.

Authentication

OAuth 2.0 Bearer - same flow as section 3.

Migration note

This replaced a non-Oracle customerAccountSites resource that was keyed by CustomerAccountSiteId, flattened the address columns onto each row, and exposed a siteUses child. No such resource is documented in Fusion Financials. The old path returns 404, the same as any unknown resource, because that is what a real Oracle pod returns.

| Name | Description |
| --- | --- |
| `SiteUseId` | number — Primary key. The customer account site use. |
| `SiteName` | string — Site name. Pass this as BillToSite on invoice create. |
| `PrimarySite` | 'Y' \| 'N' — Single character, not a boolean. May be Y on more than one purpose for the same customer. |
| `CustomerAccountId` | number — Owning customer account. |
| `AccountNumber` | string — Customer account number. |
| `CustomerName` | string — Customer name. |
| `PartyNumber` | string — Trading Community party number. |
| `AccountDescription` | null — Documented by Oracle, not populated here. |
| `SetName` | null — Reference data sets are not modelled. |
| `TaxpayerIdentificationNumber` | null — Documented by Oracle, not populated here. |
| `TaxRegistrationNumber` | null — Documented by Oracle, not populated here. |
| `links` | array — HATEOAS: self, canonical. No child links: this resource has no children. |

**List every site use for a customer account**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=CustomerAccountId=300100000000000" | jq .
```

**Find the site names you may pass as BillToSite**

```bash
# There is no SiteUseCode on this resource, so this lists BILL_TO and
# SHIP_TO uses alike. If you need certainty, omit BillToSite on create.
curl -G "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=CustomerAccountId=300100000000000;PrimarySite='Y'" \
  --data-urlencode "fields=SiteUseId,SiteName,PrimarySite"
```

**Retrieve one site use**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV/300100000000000" -H "Authorization: Bearer $TOKEN" | jq .
```

**Example response**

```json
{
  "items": [
    {
      "SiteUseId": 300100000000000,
      "SiteName": "HQ — Berlin",
      "PrimarySite": "Y",
      "CustomerAccountId": 300100000000000,
      "AccountNumber": "0001001",
      "CustomerName": "Globex Corporation #1",
      "PartyNumber": "CDRM_300100000000000",
      "AccountDescription": null,
      "SetName": null,
      "TaxpayerIdentificationNumber": null,
      "TaxRegistrationNumber": null,
      "links": [
        { "rel": "self",      "href": ".../customerAccountSitesLOV/300100000000000" },
        { "rel": "canonical", "href": ".../customerAccountSitesLOV/300100000000000" }
      ]
    }
  ],
  "count": 1,
  "hasMore": false,
  "limit": 25,
  "offset": 0
}
```

Pagination, filtering, field selection

limit (default 25, max 500), offset, totalResults=true, onlyData=true, orderBy=Field:asc|desc, fields=Col1,Col2. q-filterable and sortable fields: SiteUseId, SiteName, PrimarySite, CustomerAccountId, AccountNumber, CustomerName, PartyNumber. The four attributes this tenant does not populate are not filterable, because filtering on a column that is always null cannot do anything useful. Finder: PrimaryKey;SiteUseId=<id> only - filter by account with q.

What is deliberately not here

  - Addresses. Oracle list of values has no address attributes, so there is no City, Country, PostalCode, Address1 or LocationId, and no /locations resource either. Address data is not reachable through this API.
  - SiteUseCode, so BILL_TO and SHIP_TO cannot be distinguished, and PrimarySite=Y can appear on both for one customer.
  - Status, so only active site uses are returned.
  - Any child collection. Each row already IS a site use.

Integration patterns

  - Invoice billing: omit BillToSite and let the primary bill-to resolve server-side. That is the only reliable route through this resource, and BillToSite is optional in Oracle as well.
  - Name lookup: use this resource to show a user the site names available on an account.
  - Address sync: not possible through the API. The addresses exist in the simulator and are visible in the workspace UI.

### 10. The q filter grammar

Most list endpoints accept a q query parameter implementing a subset of Oracle's expression grammar. Join conditions with ; - this is AND, and it is the separator Oracle's own examples use. A comma is NOT an OR operator: it is only the separator inside an IN list, and a top-level comma is refused with 400 REST-01000. This page said ", (OR)" until 2026-08-04, so a caller who followed it received a 400. Use the OR keyword if you need disjunction. Operators: = != > >= < <= LIKE IN, with parentheses to group.

LIKE uses % as the wildcard. String literals are wrapped in single quotes; numbers and booleans are bare. Attribute names must come from the resource's q-filterable set. Oracle publishes a per-attribute queryable flag - named `queryable` in a real pod's `<resource>/describe` response, and republished in this API's OpenAPI schema as the vendor extension `x-queryable` because OpenAPI requires an `x-` prefix - and refuses a filter on one marked false. So does this simulator: a filter outside that set is a 400 here and on a real pod. Each resource's set is listed in its own section, and they genuinely differ from one another, so do not carry one resource's set over to the next.

**AND filter**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=InvoiceStatus='Complete';InvoiceBalanceAmount>0"
```

**LIKE filter**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=TransactionNumber LIKE 'INV-%';InvoiceBalanceAmount>0"
```

### 11. Pagination, ordering and field selection

Defaults: limit=25, max=500. Use offset to page. Add totalResults=true when you need the exact count (more expensive). Use onlyData=true to strip the HATEOAS links section. It does NOT remove the collection envelope - count, hasMore, limit, offset and totalResults are still returned, and this page wrongly promised "{ items: [...] } only" until 2026-08-04. Oracle scopes onlyData the same way: "the resource item payload will be filtered in order to contain only data (no links section, for example)". Order with orderBy=Field:asc|desc, comma-separated for multi-key sort. Use fields=Col1,Col2 to project a subset.

CHILD COLLECTIONS IMPLEMENT FEWER PARAMETERS THAN THEIR PARENTS, and the OpenAPI document is authoritative per operation - read the parameter list on the operation you are about to call rather than assuming the parent's. Every child here implements limit, offset, totalResults, onlyData and fields. Beyond that: receivablesInvoiceInstallments and remittanceReferences also implement q; receivablesInvoiceLines and ContactPoint do not. Every child also implements orderBy and finder=PrimaryKey. No child implements expand, because none of them has a child of its own to expand. Sorting is NOT restricted to the filterable attributes - Oracle's queryable flag is about filtering, and narrowing the sort set to match it would invent a restriction Oracle does not state, so remittanceReferences sorts on ReferenceNumber which it cannot filter on. An attribute computed on read cannot be a sort key at all: PaymentDaysLate is refused by name, saying it is computed, rather than reported as unknown.

What is not implemented is REFUSED with 400 REST-01003 naming the parameter, not ignored. That is deliberate and it is a change from earlier behaviour: until 2026-08-04 these parameters were accepted and silently dropped, so orderBy=InstallmentDueDate:desc returned the schedule in sequence order with a 200 and nothing to distinguish it from a sort that had worked. A caller cannot detect a dropped sort by looking at the response, which makes silence the more dangerous answer. Refusing was the honest fix; implementing them, on 2026-08-05, is the correct one - Oracle supports both, so refusing left this simulator narrower than the thing it simulates.

**Page through every invoice**

```python
import requests

BASE = "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05"
headers = {"Authorization": f"Bearer {access_token}"}
limit, offset = 200, 0
while True:
    r = requests.get(
        f"https://erplab.cloud/sim/{environmentKey}/receivablesInvoices",
        params={"limit": limit, "offset": offset, "orderBy": "CustomerTransactionId:asc"},
        headers=headers,
        timeout=30,
    )
    r.raise_for_status()
    body = r.json()
    for inv in body["items"]:
        process(inv)
    if not body.get("hasMore"):
        break
    offset += limit
```

### 12. SOAP: InvoiceService.createSimpleInvoice

The only SOAP operation implemented. Use it when you must integrate from a SOAP-only client.

Oracle names this service InvoiceService, in the namespace http://xmlns.oracle.com/apps/financials/receivables/transactions/invoices/invoiceService/, and publishes its WSDL at /fscmService/RecInvoiceService?WSDL on a real pod. This simulator serves it at https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService.

The request payload is Oracle Receivables Invoice Header service data object, wrapped in invoiceHeaderInformation. Its attribute names are NOT the same as the REST resource - this is Oracle inconsistency, not ours:

  | SOAP header SDO       | REST equivalent        |
  | --------------------- | ---------------------- |
  | BillToAccountNumber   | BillToCustomerNumber    |
  | TransactionType       | TransactionType         |
  | TrxDate               | TransactionDate         |
  | InvoiceCurrencyCode   | InvoiceCurrencyCode     |
  | PaymentTermsName      | PaymentTerms            |
  | BillToContact         | BillToContact           |
  | BillToLocation        | BillToSite              |
  | InvoiceLine           | receivablesInvoiceLines |

BillToContact is a NAME, not an id, exactly as on the REST resource. BillToLocation is the bill-to address name and behaves like BillToSite: omit it and the primary bill-to is resolved server-side.

There is no DeliveryMethod and no Email on this SDO - those are REST-only attributes. A SOAP-created invoice takes whatever delivery method the server resolves.

The response is Oracle Receivables Invoice Result SDO, which has exactly three attributes: CustomerTrxId, ServiceStatus and TransactionNumber. Read the invoice back over REST for anything else.

The invoice is created COMPLETE, with the same business rules as the REST create operation - Oracle's InvoiceStatus defaults to Complete and its stated rule is "Value must be Complete when creating a receivables invoice". No completion step is required or available: /action/complete does not exist and returns 404. This section previously described a create-then-complete flow; that flow was a simulator invention and code written against it fails on a real pod at the second call.

**SOAP envelope**

```xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:typ="http://xmlns.oracle.com/apps/financials/receivables/transactions/invoices/invoiceService/">
  <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1"
                   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken>
        <wsse:Username>SOAP_USERNAME</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SOAP_PASSWORD</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body>
    <typ:createSimpleInvoice>
      <invoiceHeaderInformation>
        <BusinessUnit>Vision Operations</BusinessUnit>
        <TransactionSource>MANUAL</TransactionSource>
        <TransactionType>Invoice</TransactionType>
        <BillToAccountNumber>0001001</BillToAccountNumber>
        <InvoiceCurrencyCode>USD</InvoiceCurrencyCode>
        <PaymentTermsName>NET30</PaymentTermsName>
        <InvoiceLine>
          <LineNumber>1</LineNumber>
          <Description>Consulting</Description>
          <Quantity>10</Quantity>
          <UnitSellingPrice>150.00</UnitSellingPrice>
        </InvoiceLine>
      </invoiceHeaderInformation>
    </typ:createSimpleInvoice>
  </soapenv:Body>
</soapenv:Envelope>
```

**Invoke with curl (save the envelope above as envelope.xml first)**

```bash
# Save the SOAP envelope shown above to a file named envelope.xml, then:
curl -s "https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService" \
  -H "Content-Type: text/xml; charset=utf-8" \
  -H "SOAPAction: createSimpleInvoice" \
  --data-binary @envelope.xml
```

### 13. Resource: receivablesInvoiceInstallments — pull payment schedules

This section explains how to pull Receivables Invoice Installments (Oracle Fusion "payment schedules") from the deployed simulator. It reflects actual implemented behavior — not planned functionality.

Concepts

Every completed receivablesInvoices row (InvoiceStatus='Complete') has at least one payment-schedule installment.
  • A standard invoice has exactly one installment whose OriginalAmount equals EnteredAmount and whose DueDate is derived from the invoice payment terms.
  • A split-payment invoice (one for which /action/splitInstallments has been called) has multiple installments whose OriginalAmount values sum to EnteredAmount.
  • An Incomplete invoice has no installments. It gains them when its InvoiceStatus is PATCHed to Complete - there is no completion ACTION, and /action/complete answers 404.

Each installment carries its own balance and lifecycle:
  | Status | Meaning                                       |
  | ------ | --------------------------------------------- |
  | OP     | Open — InstallmentBalanceDue > 0                 |
  | CL     | Closed — InstallmentBalanceDue = 0, ClosedDate set |

Disputes

An installment may carry a DisputeAmount, with a DisputeDate. Both are read-only, both are Oracle attributes of this child, and the seeded dataset contains one installment with a PARTIAL dispute (250.00 of 1000.00, still fully outstanding, invoice Complete and past due) so a collection rule that must not chase disputed money has something real to run against.

What a dispute does NOT do: it does not reduce InstallmentBalanceDue. The contested amount is still owed. Oracle publishes DisputeAmount and InstallmentAmountCredited as separate attributes, and it is the second that records a reduction - a dispute in Oracle submits a credit memo REQUEST for approval, and the reduction is what approval produces. So an installment with 250 disputed out of 1000 still shows InstallmentBalanceDue 1000.

What is NOT modelled here: there is no way to raise, amend or resolve a dispute through this API, and no credit-memo approval action. DisputeAmount is seeded and read; it never changes. Whether a real Oracle environment clears DisputeAmount automatically when a credit memo is approved, or leaves it for a collector to clear by hand, is NOT stated on any Oracle page we could reach - it is recorded as unverified rather than guessed at. If you block collection on DisputeAmount > 0, do not assume the block lifts by itself.

Server-authoritative invariants (maintained by DB triggers):
  • Invoice.InvoiceBalanceAmount == SUM(InstallmentBalanceDue) over all installments of the invoice.
  • For each installment: OriginalAmount == AmountPaid + InstallmentBalanceDue.
  • InstallmentBalanceDue is never negative. There is no caller-facing way to over-apply: applications are created only by Apply Receipts Using AutoMatch, which allocates at most the remaining balance of each schedule. A receipt larger than what is outstanding applies the remainder and keeps the rest as UnappliedAmount. This line named an HTTP status until 2026-08-04 that no handler returns.
  • A closed installment auto-reopens if a reversal pushes InstallmentBalanceDue back > 0.

Endpoint

  GET   https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments                  — list
  GET   https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/child/receivablesInvoiceInstallments/{InstallmentId}  — retrieve
  POST  https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{CustomerTransactionId}/action/splitInstallments                              — replace schedule

No top-level /receivablesInvoiceInstallments resource. No PATCH, PUT, DELETE — balances mutate only through receipt applications (internal) and structure changes only through splitInstallments.

Authentication

OAuth 2.0 Bearer — same flow as section 3.

| Name | Description |
| --- | --- |
| `InstallmentId` | number — Stable identifier (Oracle payment_schedule_id). |
| `InstallmentSequenceNumber` | number — 1-based installment number within the invoice. |
| `InstallmentDueDate` | YYYY-MM-DD — Date this installment is due. |
| `OriginalAmount` | number — Original installment amount. Immutable after creation. |
| `AmountPaid` | number — Total applied to this installment from APP-status receipt applications. |
| `InstallmentBalanceDue` | number — Oracle: "The outstanding balance on the installment." OriginalAmount − AmountPaid, driven by receipt applications. NOT reduced by a dispute — see DisputeAmount. |
| `InstallmentAmountAdjusted` | number — Oracle: "The amount that was adjusted on the installment." 0 throughout this simulator; adjustments are not implemented. |
| `InstallmentAmountCredited` | number — Oracle: "The amount that was credited on the installment." This is what an APPROVED credit memo produces, and it is a different thing from an amount in dispute. |
| `PendingAdjustmentAmount` | number — Adjustment submitted and not yet approved. 0 throughout this simulator. |
| `DisputeAmount` | number — Oracle: "The amount in dispute on the installment." Read-only. A dispute does NOT reduce InstallmentBalanceDue: the contested money is still outstanding, and only an approved credit memo reduces what is owed. May be PARTIAL — an installment can have 250 of 1000 disputed and the whole 1000 still due. Treat DisputeAmount > 0 as a reason not to pursue collection, not as a reduction in the amount. |
| `DisputeDate` | date \| null — Oracle: "The date when a dispute was recorded against the installment." Read-only. Null when nothing is in dispute. |
| `InstallmentStatus` | 'OP' \| 'CL' — Open or Closed. |
| `InstallmentClosedDate` | date \| null — Set automatically when InstallmentBalanceDue reaches 0; cleared if a reversal re-opens it. |
| `InstallmentGLClosedDate` | date \| null — General-ledger close date. Null unless the installment is closed. |
| `PaymentDaysLate` | number — max(0, today − InstallmentDueDate) for OP; 0 for CL. Computed live on read. |
| `LastUpdateDate` | timestamptz — Last server-side change. |
| `links` | array — HATEOAS: self, parent → receivablesInvoices/{CustomerTransactionId}. |

**List all installments of an invoice**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000008/child/receivablesInvoiceInstallments" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

**Retrieve a single installment**

```bash
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000008/child/receivablesInvoiceInstallments/300100000000082" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

**Pull only what is currently open and unpaid**

```bash
curl -G "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000008/child/receivablesInvoiceInstallments" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=InstallmentDueDate<='2026-12-31'" \
  --data-urlencode "fields=InstallmentId,InstallmentDueDate,InstallmentBalanceDue,InstallmentStatus"
```

**Example response — list**

```json
{
  "items": [
    {
      "InstallmentId": 300100000000082,
      "CustomerTransactionId": 300100000000008,
      "InstallmentSequenceNumber": 1,
      "InstallmentDueDate": "2026-06-28",
      "OriginalAmount": 288.50,
      "InstallmentBalanceDue": 288.50,
      "AmountPaid": 0.00,
      "InstallmentStatus": "OP",
      "InstallmentClosedDate": null,
      "PaymentDaysLate": 0,
      "LastUpdateDate": "2026-06-26T21:26:13.877839+00:00",
      "links": [
        { "rel": "self",   "href": ".../receivablesInvoiceInstallments/300100000000082" },
        { "rel": "parent", "href": ".../receivablesInvoices/300100000000008" }
      ]
    },
    {
      "InstallmentId": 300100000000083,
      "CustomerTransactionId": 300100000000008,
      "InstallmentSequenceNumber": 2,
      "InstallmentDueDate": "2026-07-28",
      "OriginalAmount": 288.50,
      "InstallmentBalanceDue": 288.50,
      "AmountPaid": 0.00,
      "InstallmentStatus": "OP",
      "InstallmentClosedDate": null,
      "PaymentDaysLate": 0,
      "LastUpdateDate": "2026-06-26T21:26:12.755185+00:00",
      "links": [ /* ... */ ]
    }
  ],
  "count": 2,
  "hasMore": false,
  "limit": 25,
  "offset": 0
}
```

**Split into two installments**

```bash
curl -s -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001/action/splitInstallments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "installmentPayload": [
      { "InstallmentSequenceNumber": "1", "OriginalAmount": "750.00", "InstallmentDueDate": "2026-07-15" },
      { "OriginalAmount": "750.00", "InstallmentDueDate": "2026-08-15" }
    ]
  }'
```

Pagination, filtering, field selection

limit (default 25, max 500), offset, totalResults=true, onlyData=true. q-filterable fields are exactly those Oracle marks x-queryable: InstallmentId, InstallmentSequenceNumber, InstallmentDueDate, OriginalAmount. Everything else is refused 400 — including InstallmentStatus, InstallmentBalanceDue, AmountPaid and LastUpdateDate, which a real pod also refuses. So the open-installments question is NOT a server-side filter in Oracle: read an invoice's installments and select locally, or filter the parent on InvoiceStatus and InvoiceBalanceAmount, which ARE queryable there. Examples: q=InstallmentDueDate<='2026-12-31', q=OriginalAmount>1000. InstallmentStatus and InstallmentBalanceDue are NOT queryable in Oracle; select on them client-side after reading the collection.

How to determine what is currently due
  • Currently due now = open installments whose DueDate <= today.
  • Total amount due now for an invoice = SUM(InstallmentBalanceDue) over those rows.
  • Next due = the open installment with the earliest DueDate.

How to identify open / partially paid / closed installments
  | Visual state         | API condition                                                       |
  | -------------------- | ------------------------------------------------------------------- |
  | Open (not paid)      | InstallmentStatus='OP' AND AmountPaid=0                                        |
  | Partially paid       | InstallmentStatus='OP' AND AmountPaid>0 AND InstallmentBalanceDue>0               |
  | Closed (fully paid)  | InstallmentStatus='CL' (equivalently InstallmentBalanceDue=0)                     |

Safe collections filter: q=InstallmentStatus='OP';InstallmentBalanceDue>0.

How installment balances relate to invoice InvoiceBalanceAmount
  • For a COMPLETE invoice, InvoiceBalanceAmount equals SUM(installments.InstallmentBalanceDue) — maintained by trigger.
  • An INCOMPLETE invoice has no installments at all: payment schedules are created when the transaction is completed. Its InvoiceBalanceAmount therefore reflects EnteredAmount and has no installment rows behind it. Do not reconcile the two on an incomplete invoice.
  • Closing the last open installment sets InvoiceBalanceAmount=0 atomically.
  • Reversing a receipt re-opens the most-recently-closed installment first (Oracle default).

How an external payment-collection provider should avoid collecting a closed or zero-balance installment
  1. Re-read the installment immediately before quoting/charging: GET .../receivablesInvoiceInstallments/{InstallmentId}.
  2. Refuse to collect if any of: InstallmentStatus='CL', InstallmentBalanceDue<=0, InstallmentClosedDate!=null.
  3. Cap the collection amount at InstallmentBalanceDue.
  4. After your receipt is recorded in the simulator, re-read the installment once Apply Receipts Using AutoMatch has run — balance updates are asynchronous, so a poll immediately after POST /standardReceipts will still show the old balance.
  5. There is no server-side refusal to fall back on, because there is nothing to refuse: a caller cannot post against an installment at all. Receipts are created with POST /standardReceipts and applied only by Apply Receipts Using AutoMatch, which allocates at most each schedule's remaining balance and leaves any excess on the receipt as UnappliedAmount. Steps 1-4 are the protection. This step named two error codes and an HTTP status until 2026-08-04; none of the three exists.

Receipt-application interaction (context)
  • Installment balances change only as a consequence of a receipt application created by Apply Receipts Using AutoMatch.
  • A receipt cannot target an installment. The 26B Standard Receipts request has no InstallmentId, PaymentScheduleId or InstallmentNumber attribute; sending one is rejected. Which installments are hit follows from the transaction named by the remittance reference and the active AutoCash configuration.
  • Reversing an application (Status='REV') restores both the installment balance and the invoice InvoiceBalanceAmount atomically.

Limitations
  • No top-level /receivablesInvoiceInstallments resource — always go through the parent invoice path.
  • No PATCH/PUT/DELETE; structure changes only via /action/splitInstallments.
  • splitInstallments preconditions: invoice must be COMPLETE (else 409 AR-2010); OriginalAmount values must sum to the invoice's EnteredAmount (else 400 AR-1040) — the WHOLE amount, not the amount less what has been paid; no installment may be set below what has already settled it, and no installment closed BY settlement may change amount or due date (both 409 AR-2012, naming the installment). An installment closed only because it was zeroed may be changed again, and an applied receipt does not block the split: the cash is reallocated, InstallmentSequenceNumber values must be unique integers >= 1 and contiguous from 1; omit it on a new installment and its position is used, InstallmentDueDate must be >= invoice.TransactionDate.
  • AmountPaid is driven by receipt applications. Post a Standard Receipt to pay an invoice (see section 14); applications themselves are read-only.

### 14. Standard Receipts and Apply Receipts Using AutoMatch

An external platform that has collected a payment records it by creating a Standard Receipt carrying one or more remittance references that identify the transaction being paid. It does not post a payment record, and it does not mark an invoice or installment paid.\n\nReceipt creation and receipt application are separate operations. POST /standardReceipts validates, creates the receipt and its remittance references, commits, and returns - leaving the receipt UNAPPLIED (or UNIDENTIFIED when no customer could be resolved). Applications are created later by a separate asynchronous scheduled process, Apply Receipts Using AutoMatch. A poll immediately after the POST will show no applications and an unchanged invoice balance; this is correct behaviour, not a failure.\n\nWhen Apply Receipts Using AutoMatch actually runs\n\nThere is no cron and no background timer in this deployment, so it is worth knowing exactly what advances it. Nothing runs without an incoming authenticated request. Creating a receipt - or adding a remittance reference to one - marks the tenant's schedule due immediately, but it does not itself apply anything: the run happens on the NEXT authenticated request to your simulator. Otherwise the schedule becomes due on its own every 5 minutes, and is likewise picked up by the next request after that. A completely idle tenant does not advance at all.\n\nA single run processes a bounded number of receipts, so a burst of payments drains over several runs rather than all at once. Polling is therefore not only how you observe progress - it is also what drives it. If you create many receipts at once, keep polling until UnappliedAmount reaches zero; each poll is itself an opportunity for the sweep to advance.\n\nOne trap in that rule: UnappliedAmount is zero on an UNIDENTIFIED receipt from the moment it is created, because its money is held against no customer rather than against a customer with nothing applied. So do not read UnappliedAmount == 0 on its own as proof of full application. Check State first: UNIDENTIFIED means no customer resolved and no application will ever happen until one is assigned; APPLIED with UnappliedAmount == 0 is the success condition. Applied money is Amount - UnappliedAmount; there is no AppliedAmount attribute on this resource in Oracle and this simulator no longer emits one.\n\nPractical expectation: post the receipt, then poll. The first poll is usually the request that triggers the run, so the second poll is where you normally see it applied. Do not post and then wait passively - without traffic nothing happens. If it is still UNAPPLIED after several polls, the reference did not match: check ReferenceNumber against the invoice TransactionNumber rather than polling longer.\n\nIntegration sequence\n  1. Create a Standard Receipt.\n  2. Include one or more remittance references.\n  3. Read StandardReceiptId from the response.\n  4. Poll until applied - polling also advances the sweep (see above).\n  5. Query the Standard Receipt (State, UnappliedAmount).\n  6. Query Standard Receipt Applications.\n  7. Query the invoice installments / transaction payment schedules.\n  8. Confirm the final applied and unapplied balances.\n\nState and Status are different dimensions. State is the application dimension (APPLIED, UNAPPLIED, UNIDENTIFIED, INSUFFICIENT FUNDS, REVERSE PAYMENT, STOP PAYMENT). Status is the lifecycle dimension (CONFIRMED, CLEARED, APPROVED, REMITTED). CONFIRMED does not mean the invoice is paid, and CLEARED does not mean the receipt is fully applied. Do not use InvoiceStatus as a payment status: invoice completion and receipt application are unrelated concepts, and a fully paid invoice is not reported as Paid.

- Required on create: Amount, BusinessUnit, Currency, ReceiptDate, ReceiptMethod.
- ReceiptMethod is resolved by name against the methods configured for your tenant, and an unknown one is rejected with AR_INVAL_RECEIPT_MTH_ID. Only Manual is configured by default; more can be added on the ERP simulator settings page. A method that has been retired is refused with AR_BOE_OBSOLETE rather than treated as unknown.
- Omitting customer details creates an UNIDENTIFIED receipt - that is deliberate and is how cash received before the payer is known is recorded. But a CustomerAccountNumber or CustomerName that does NOT resolve is rejected with 400 REST-01400, not silently dropped: a caller who supplies an identifier and receives 201 with it nulled cannot tell acceptance from being ignored.
- ReceiptNumber is optional, max 30 characters. For external payments, derive a stable unique value from your payment reference so a retry is detected as a duplicate rather than creating a second receipt.
- Duplicate detection follows Oracle: same receipt number, date, amount and customer returns AR_RCP_DUP_NUM. There is no separate idempotency-key contract; send Upsert-Mode: true to have a duplicate return the existing receipt instead of an error.
- Store your own payment identifier in an Oracle-supported field - ReceiptNumber, StructuredPaymentReference, Comments or a descriptive flexfield. Provider-specific attributes such as externalPaymentId or paymentId are rejected.
- Amount must be expressible in the currency you send. A currency carries a precision - JPY has 0 decimal places, USD 2, KWD 3 - and an amount with more decimals than its currency allows is rejected with AR_RAPI_AMOUNT_INVALID rather than rounded. 100.5 JPY is not a valid amount. It is refused rather than adjusted because you stated it: silently changing a figure you sent would misstate a payment, and you would have no way to tell. The same rule applies to ReferenceAmount, checked against the parent receipt's currency.
- ReferenceNumber is max 50 characters. ReferenceAmount is the intended application amount for that reference.
- A receipt with incomplete remittance information is still created successfully; it simply stays unapplied because no qualifying transaction can be identified.
- Multiple remittance references produce separate applications. They are never merged into one.
- The request cannot target a specific installment: InstallmentId, PaymentScheduleId and InstallmentNumber are not part of the 26B contract and are rejected. The transaction number identifies the transaction; its open payment schedules are then evaluated by the configured matching and application rules.
- Overpayments and underpayments follow the configured application exception rules. In the default configuration an unmatched surplus is left unapplied - never discarded, and never applied to another transaction without a remittance reference.
- Receipt applications are read-only through the 26B REST resources.
- The Oracle 26C applyReceipt action is intentionally not implemented.

**Create an identified receipt with one invoice reference**

```bash
curl -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "ReceiptNumber": "PAY-20260728-001",
    "ReceiptMethod": "Manual",
    "BusinessUnit": "Vision Operations",
    "CustomerAccountNumber": "0001001",
    "Amount": 500.00,
    "Currency": "USD",
    "ReceiptDate": "2026-07-28",
    "AccountingDate": "2026-07-28",
    "StructuredPaymentReference": "pi_3ABC123",
    "remittanceReferences": [
      { "ReceiptMatchBy": "Transaction Number", "ReferenceNumber": "INV-300100000000001", "ReferenceAmount": 500.00 }
    ]
  }'
```

**Create a receipt with several invoice references**

```bash
curl -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "ReceiptNumber": "PAY-20260728-002",
    "ReceiptMethod": "Manual",
    "BusinessUnit": "Vision Operations",
    "CustomerAccountNumber": "0001001",
    "Amount": 750.00,
    "Currency": "USD",
    "ReceiptDate": "2026-07-28",
    "remittanceReferences": [
      { "ReceiptMatchBy": "Transaction Number", "ReferenceNumber": "INV-300100000000001", "ReferenceAmount": 500.00 },
      { "ReceiptMatchBy": "Transaction Number", "ReferenceNumber": "INV-1002", "ReferenceAmount": 250.00 }
    ]
  }'
# Two references produce two applications against two transactions.
```

**Create an unidentified receipt (no customer details)**

```bash
curl -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "ReceiptMethod": "Manual",
    "BusinessUnit": "Vision Operations",
    "Amount": 300.00,
    "Currency": "USD",
    "ReceiptDate": "2026-07-28"
  }'
# -> "State": "UNIDENTIFIED". It stays unidentified, and unapplied,
#    until the customer is resolved with PATCH.
```

**Add a remittance reference to an existing receipt**

```bash
curl -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts/300100169169023/child/remittanceReferences" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{ "ReceiptMatchBy": "Transaction Number", "ReferenceNumber": "INV-300100000000005", "ReferenceAmount": 125.00 }'
```

**Query the receipt and expand its references**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts/300100169169023?expand=remittanceReferences" \
  -H "Authorization: Bearer $TOKEN"

# Immediately after creation:
#   "State": "UNAPPLIED", "UnappliedAmount": 500.00
# After Apply Receipts Using AutoMatch has run:
#   "State": "APPLIED",   "UnappliedAmount": 0.00
```

**Query remittance references on their own**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts/300100169169023/child/remittanceReferences" \
  -H "Authorization: Bearer $TOKEN"
```

**Query the receipt applications AutoMatch created**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesCustomerAccountActivities/1004/child/standardReceiptApplications" \
  -H "Authorization: Bearer $TOKEN"

# Read-only. There is no POST on this resource.
```

**Confirm the installment balances moved**

```bash
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/300100000000001/child/receivablesInvoiceInstallments" \
  -H "Authorization: Bearer $TOKEN"

# AmountPaid and InstallmentBalanceDue reflect the applications.
# InvoiceStatus is unchanged - it is not a payment status.
```

**Handle an unmatched receipt**

```bash
# A reference matching no open transaction leaves the receipt unapplied.
# That is not an error: the receipt stays eligible for a later run once
# the transaction exists or the reference is corrected.
curl "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/standardReceipts?q=CustomerAccountNumber='0001001'" \
  -H "Authorization: Bearer $TOKEN"
```

**Handle a duplicate receipt**

```bash
# Re-sending the same ReceiptNumber + ReceiptDate + Amount + customer:
# HTTP 400
# {
#   "o:errorCode": "AR_RCP_DUP_NUM",
#   "detail": "A receipt with this number, date, amount and customer already exists. Enter a unique receipt number."
# }
# Send "Upsert-Mode: true" to receive the existing receipt instead of an error.
```

### 15. HATEOAS response envelope

List responses include items, count (page size), hasMore, limit, offset, optionally totalResults, and a top-level links array. Each item includes its own links: self, canonical, child collections (e.g. receivablesInvoiceLines), and applicable actions - the only action link emitted is action/splitInstallments. Use the links to drive navigation generically; do not hand-build child URLs in production clients.

- Set onlyData=true to strip the links section. It does NOT strip the envelope: count, hasMore, limit, offset and totalResults are still returned.
- links[].rel values used: self, canonical, parent, child, action/<name>.
- Contacts carry self, canonical and a child link to ContactPoint. The parent link on this resource family is on the ContactPoint CHILD and points back to contacts/{PartyNumber}. An earlier version of this page described a parent link to customersV2/{CustomerAccountId}; no response has carried one since contacts moved to the CX base.

### 16. Error handling

REST errors return a JSON envelope with title, detail, o:errorCode and (for validation errors) an o:errorDetails array pinpointing the offending field. SOAP errors return a SOAP 1.1 Fault with a structured faultcode (env:Client.* for caller errors, env:Server.* for server errors).

| Name | Description |
| --- | --- |
| `401 REST-01401` | Missing/invalid/expired bearer token. Re-mint a token and retry once. |
| `403 FND_SECURITY_INSUFFICIENT_PRIVILEGE` | The token is valid but the credential's scope list does not include the Oracle functional privilege the operation requires — AR_CREATE_RECEIVABLES_RECEIPT_PRIV to create a receipt or a remittance reference, AR_MANAGE_RECEIVABLES_RECEIPT_PRIV to read, update or delete one, AR_VIEW_CUSTOMER_ACCOUNT_ACTIVITY_PRIV for the customer account activity resources. Retrying will not help: the credential needs the privilege added. A credential whose scope list is a single entry of urn:opc:resource:consumer::all is unrestricted and never sees this. Note that Oracle documents the 403 status for a caller lacking the roles and privileges for a resource, but publishes no error-code token for it in the REST guide, so treat the code STRING as this simulator's own and branch on the 403 status rather than on the token. |
| `400 REST-01002` | Invalid path parameter (non-numeric id). |
| `400 REST-01007` | Malformed JSON body. |
| `404 REST-01003 / 01102` | Unknown action/child path or unimplemented resource. |
| `400 AR-1000` | Missing required field(s) on invoice create — see o:errorDetails. |
| `400 AR-1001` | No invoice lines supplied. |
| `400 AR-1010` | BillToCustomerNumber not found. |
| `400 AR-1020` | Attempt to PATCH a read-only field. |
| `400 AR-1030` | Invalid DeliveryMethod, or an InvoiceCurrencyCode that is not defined or not enabled for this environment. |
| `400 AR-1031` | BillToContact does not name an active contact on the customer account. Unmatched and inactive are reported the same way: the lookup only considers active contacts. |
| `400 AR-1033` | BillToContact matches more than one contact on the account. A name that identifies nobody uniquely is rejected rather than resolved to one of them. |
| `400 AR-1040` | Installment split validation failed (sum, amounts, sequences or dates). |
| `409 AR-2010 / 2012` | Cannot split: invoice not COMPLETE / a closed installment exists. |
| `404 AR-7041` | Receivables invoice not found. |
| `404 REST-01404` | Contact, or contact point, not found. |
| `404 REST-01005` | Customer account site not found for the given SiteUseId. |
| `400 invalid_request / unsupported_grant_type` | OAuth: bad form, wrong content-type, a missing required parameter (grant_type, client_id, client_secret, scope), or grant_type ≠ client_credentials. |
| `400 invalid_scope` | OAuth: the requested scope exceeds the scope granted to the client, or urn:opc:resource:consumer::all was combined with another scope — Oracle requires that one to be requested on its own. |
| `401 invalid_client` | OAuth: unknown client_id, wrong client_secret, revoked client, or a credential issued for a different environment. All four are reported identically — the response never confirms that a client_id exists. |
| `405 invalid_request` | OAuth: the token endpoint accepts POST only. The response carries an Allow header. |

**Validation error**

```json
{
  "title": "Bad Request",
  "status": "400",
  "o:errorCode": "AR-1000",
  "detail": "Missing required fields",
  "o:errorDetails": [
    { "o:errorPath": "$.BusinessUnit", "detail": "BusinessUnit is required" }
  ]
}
```

### 17. Retry strategy and idempotency

The simulator does not yet enforce rate limits or accept idempotency keys. Build your client with exponential backoff on 5xx and on transient network errors; treat 4xx as permanent and surface them to the caller. Re-mint tokens on 401 and retry the original call exactly once. For non-idempotent POSTs (invoice create, split), de-duplicate at the source using a correlation ID in your own database BEFORE sending the request — the simulator cannot reject duplicates for you.

### 18. End-to-end example — create, complete, split, query

A complete lifecycle from a fresh tenant. Each step assumes the previous one succeeded and that $TOKEN was minted at step 0.

**Full lifecycle**

```bash
# 0. Token. Set these two first, from ERP simulator settings ->
#    OAuth 2.0 clients -> New client. The secret is shown once, at creation.
#      export CLIENT_ID=...
#      export CLIENT_SECRET=...
TOKEN=$(curl -s "https://erplab.cloud/sim/{environmentKey}/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" | jq -r .access_token)

# 1. Pick a customer + contact
ACCOUNT=$(curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV?limit=1" -H "Authorization: Bearer $TOKEN" \
  | jq -r '.items[0].CustomerAccountId')
# BillToContact is a NAME, not an id. ContactPointId is not part of the
# Oracle contract in either direction, and sending one returns AR-1031.
#
# Contacts are on the CX base, and neither Oracle nor this simulator has a
# customer-account finder on that resource, so there is nothing to filter by
# $ACCOUNT here. Omitting BillToContact is the reliable route: an active
# bill-to contact carrying an email address is resolved server-side. Section 8
# covers the resource itself.

# 2. Create
INV=$(curl -s -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d "{ \"BusinessUnit\":\"Vision Operations\",\"TransactionType\":\"Invoice\",
        \"TransactionSource\":\"MANUAL\",\"BillToCustomerNumber\":\"0001001\",
        \"InvoiceCurrencyCode\":\"USD\",\"PaymentTerms\":\"NET30\",
        \"receivablesInvoiceLines\":[{\"Description\":\"Service\",\"Quantity\":1,\"UnitSellingPrice\":1500}] }" \
  | jq -r .CustomerTransactionId)

# 3. The invoice is ALREADY Complete - POST returns it that way, with its
#    payment schedule built. There is no completion step: /action/complete is
#    not an Oracle action and answers 404. This script called it here until
#    2026-08-04, so the published end-to-end walkthrough failed at step 3.
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/$INV?expand=receivablesInvoiceInstallments" \
  -H "Authorization: Bearer $TOKEN" | jq '{InvoiceStatus, InvoiceBalanceAmount}'

# 4. Split into two installments
curl -s -X POST "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/$INV/action/splitInstallments" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{ "installmentPayload":[
          {"InstallmentSequenceNumber":"1","OriginalAmount":"750.00","InstallmentDueDate":"2026-07-15"},
          {"OriginalAmount":"750.00","InstallmentDueDate":"2026-08-15"}
        ] }'

# 5. Confirm
curl -s "https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/$INV/child/receivablesInvoiceInstallments" \
  -H "Authorization: Bearer $TOKEN" | jq .
```

### 19. Tenant isolation and credential hygiene

Every credential (OAuth client, SOAP user, access token) is scoped to a single tenant. Issuing tenant A's bearer token against tenant B's environment key URL returns 401 — the lookup is keyed by the tenant resolved from the URL. Rotate credentials immediately if a secret is exposed (Settings → revoke). Resetting the ERP from the Danger zone invalidates everything atomically: environment key, all clients, all tokens, all seed data.

- Store client_secret and SOAP password in a secret manager — never in source control.
- Use a distinct OAuth client per integration so you can revoke without impacting other consumers.
- Treat the environment key as a non-secret routing identifier, not a credential.

### 20. Observability — request logs

Every REST/SOAP/OAuth request your integration makes is captured in the tenant's request log (visible at /erp/logs). Bodies are server-side redacted before storage. Use the label field on OAuth clients and SOAP credentials to correlate log entries with the calling system — when triaging integration issues, filter by label first.

### 21. Conventions, encoding and precision

- Charset: UTF-8 for both REST and SOAP.
- Monetary amounts: server stores 4-decimal precision; round on display, not before sending.
- Identifiers: use string or 64-bit integer; never JS Number.
- Dates: YYYY-MM-DD; LastUpdateDate is full ISO-8601 with timezone.
- Booleans: JSON true/false in REST, lowercase true/false in q-grammar.
- URL-encoding: always pass q with --data-urlencode or equivalent — semicolons and quotes WILL break unencoded.

### 22. What is NOT supported

- DELETE on any resource EXCEPT receivablesInvoices and standardReceipts. Both are implemented, answering 204 with no body as Oracle documents. This bullet claimed DELETE was unsupported everywhere until 2026-08-04, while section 7 said on the same page that invoice DELETE is implemented. An invoice carrying receipt applications is refused 400 AR_TRX_DELETE_NOT_ALLOWED rather than deleted; a receipt is refused when it has applications or is accounted, frozen, reversed or automatic.
- Top-level /customers, /customersV2, /parties REST resources.
- The Oracle 26C /standardReceipts/{id}/action/applyReceipt action — deliberately absent from this 26B simulation.
- PATCH or DELETE on remittanceReferences. Oracle 26B documents only POST and GET on this child, so there is nothing to conform to — a reference is added, not edited or removed.
- POST on standardReceiptApplications — applications are created only by Apply Receipts Using AutoMatch.
- Contacts are served where Oracle serves them, and the portability caveat that used to sit here no longer applies. This bullet said the contacts shape was "this simulator's own" and might not port — true of the OLD Financials-based resource, and left standing after contacts moved to the CX family. They are now at /crmRestApi/resources/11.13.18.05/contacts, keyed by PartyNumber, with communication channels on the ContactPoint child, which is Oracle's own model. What IS still worth knowing: Oracle Financials has no contacts resource at all, so the Financials path answers 404, and three q filters (PhoneNumber, PrimaryFlag, Status) are accepted here without being confirmed queryable in Oracle — recorded as unverified rather than removed.
- There is NO completion step on invoice create. Oracle's InvoiceStatus defaults to Complete and Oracle requires that value on create, so POST /receivablesInvoices returns an invoice that is already Complete with its installments generated. /action/complete answers 404, exactly as a real pod does for an action it has never had. It was a simulator invention, and code written against it failed against a real Oracle pod at the second call. Oracle documents approve, rework and splitInstallments on this resource; only splitInstallments is implemented here.
- Account totals are LEDGER-CURRENCY amounts. Note the attribute names differ by resource - the site resource publishes TotalOpenReceivablesForSite and TotalTransactionsDueForSite, and everything in this paragraph applies to both pairs. TotalOpenReceivablesForAccount and TotalTransactionsDueForAccount are converted to the ledger currency (USD in this simulator) using the environment's daily rates - they are NOT sums of entered amounts, and the resource has no currency attribute because Oracle defines none. Do not compare either figure against a client-side sum of InvoiceBalanceAmount without converting first: on a multi-currency account the two legitimately differ. Oracle relates them as open = due - pendingApplication, where pending is cash received and not yet applied, so open is the SMALLER figure whenever an account holds unapplied cash, and can be NEGATIVE for a customer in credit. Pending is not exposed as an attribute (Oracle publishes none); reconstruct it from standardReceipts where UnappliedAmount > 0.
- Two semantics on those totals are INFERRED from Oracle's wording rather than confirmed, and are recorded as such. (1) TotalTransactionsDueForAccount is implemented as gross outstanding; whether Oracle excludes not-yet-due installments is not stated on any reachable page. (2) The negative case above follows from the documented subtraction, but no page states outright that the attribute goes negative. If you depend on either for money movement rather than display, verify against your own Oracle instance before relying on it.
- Invoice line amounts are rounded to the transaction currency's precision, half away from zero, per line, with the header equal to the sum of the rounded lines. Oracle documents the amount fields as bare numbers with no precision, formula or rounding notes, so the MODE (half-up vs half-even) and whether Oracle rounds per line or per total are unconfirmed. Expect possible disagreement of one minor unit on a line whose fraction lands exactly on the midpoint of a multi-line invoice.
- Children on the activity resources: Oracle documents seven (creditMemoApplications, creditMemos, standardReceipts, standardReceiptApplications, transactionAdjustments, transactionPaymentSchedules, transactionsPaidByOtherCustomers). Only standardReceiptApplications is implemented — the one that confirms a payment landed. The other six are named as documented-but-unimplemented on request rather than returning a bare 404 or an empty collection, so the boundary is legible. Listing all activities and reading one by key ARE implemented, as Oracle documents them.
- Receipt reversal. Oracle 26B documents no reversal action on standardReceipts (only GET, POST, PATCH and DELETE), so the simulator has none. The State values REVERSE PAYMENT, INSUFFICIENT FUNDS and STOP PAYMENT are part of Oracle's documented read-only value set and are recognised on read, but nothing in this simulator produces them — a chargeback or returned payment cannot be modelled through the API. Plan refund handling on your own side.
- Twenty-one attributes Oracle documents that this simulator does not emit at all. On receivablesInvoices: AllowCompletion, BillingDate, CreatedBy, CreationDate, LastUpdatedBy, LastPrintDate, OriginalPrintDate, ReceiptMethod, SalesPersonNumber, ShipToContact - printing, sales credits, ship-to and audit-USER attribution are not modelled, though LastUpdateDate IS emitted so change-based incremental sync works. On receivablesInvoiceLines: CreatedBy, CreationDate, LastUpdateDate, LastUpdatedBy, PrepayCustomerTrxId, RemainingPrepayAmount - a line carries no audit columns and no timestamp of its own, so per-line change detection is unavailable (a line write DOES bump the parent invoice's LastUpdateDate, so sync works at the invoice grain), and prepayment application is not modelled at all. These six became visible on 2026-08-10: Oracle's queryable flag for that child had been recorded as never confirmed, so nothing was comparing it. On standardReceiptApplications: ReceiptMethod, ActivityName, IsLatestApplication, ProcessStatus - read the receipt for its method; receivables activities and a separate process status are not modelled, and Oracle does not state whether IsLatestApplication is latest per receipt, per transaction or per installment, so it is recorded as unverified rather than guessed. On contacts: LastUpdateDate, so that resource has no sync watermark while its ContactPoint child does. Each gap is declared with its reason internally and a guard fails on any NEW one, so this list cannot silently grow. It is derived against the attributes Oracle marks QUERYABLE, which is a lower bound on Oracle's full attribute list - it catches new divergence in the surface that has been recorded and does not prove attribute completeness.
- A public scheduled-process submission API (no verified Oracle ESS job package / parameter list).
- Invoice actions other than splitInstallments. Oracle documents approve, rework and splitInstallments; only the last is implemented, and the other two answer 404 naming themselves. This bullet named complete as a supported action until 2026-08-04, three sections after another bullet on the same page said complete answers 404 and has never been an Oracle action.
- Children other than receivablesInvoiceLines and receivablesInvoiceInstallments on receivablesInvoices.
- expand on any child collection, and q on ContactPoint. Each is refused 400 REST-01003 naming the parameter. The stated REASON for the expand refusal was wrong until 2026-08-10: it read 'none of them has a child of its own', which is false of Oracle - receivablesInvoiceLines publishes tax lines, attachments and three flexfield children in 26B. It is THIS SIMULATOR that models none of them, so there is nothing here for expand to embed. A sentence that blames the resource for a gap that is ours tells an integrator the capability does not exist in production, when it does. orderBy and finder=PrimaryKey were on this list until 2026-08-05: accepted and silently dropped, then refused, now implemented, because Oracle supports both on child collections. A finder other than PrimaryKey is refused by name. Reading ONE invoice line by key was on this list until 2026-08-10 and is now implemented, as is q on receivablesInvoiceLines.
- dependency on any item read. Oracle documents it on the invoice, line and installment item reads - it sets attributes before generating the response and rolls them back afterwards, so a caller can preview the effect of a change without making it. Nothing on this surface implements it, and it is refused 400 REST-01003 naming the parameter rather than ignored: a silently dropped dependency returns the UNMODIFIED row, which looks exactly like a preview in which the change had no effect.
- OAuth token introspection / refresh / revocation endpoints.
- SAML / PasswordDigest WS-Security profiles.
- ESS jobs, BI Publisher, FBDI imports (planned, not exposed).
- Rate limiting and idempotency-key enforcement.
- q operators beyond = != > >= < <= LIKE AND OR (no BETWEEN, no IS NULL, no nested grouping).

### 23. Troubleshooting checklist

- 401 invalid_client → check client_id, regenerate the secret in Settings if unsure.
- 401 REST-01401 → token expired (>1h) or revoked; mint a new one.
- 404 SIM-1000 → wrong environment key in the URL.
- 409 SIM-1001 → tenant ERP not provisioned; choose Oracle Fusion in Settings.
- 503 SIM-1002 → tenant ERP reset in progress; retry after the operation completes.
- 400 AR-1000 → look at o:errorDetails to see which field is missing.
- 404 → POST to /action/complete. That action does not exist: invoices are created Complete.
- env:Client.AuthRequired → SOAP envelope missing the wsse:Security header.
- env:Client.PasswordTypeUnsupported → switch to PasswordText; PasswordDigest is not implemented.
- Unexpected 404 on a child/action path → confirm the path appears in section 7; anything else returns REST-01003.

### 24. Production-readiness checklist

- Secret management: client_secret and SOAP password stored in a vault, not env files committed to git.
- Token cache: shared across worker instances, refreshed before expiry, never logged.
- Retries: exponential backoff on 5xx and network errors; single retry on 401 after re-minting.
- Idempotency: source-side de-duplication on every POST.
- Identifier handling: 64-bit safe across the whole pipeline (DB columns, serializers, logs).
- Observability: correlate your logs with the simulator's request log via OAuth-client label.
- Schema validation: validate every outbound payload against the field reference before sending.
- Reset playbook: documented procedure for re-binding to a fresh environment_key after a tenant reset.

### 24b. Incremental sync with LastUpdateDate

Every REST datetime attribute is emitted in Oracle Fusion's canonical wire format: ISO-8601 UTC with millisecond precision and a compact numeric offset, for example 2026-06-25T12:00:00.000+0000. The regex an external client can use to validate the format is ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}$.

LastUpdateDate is filterable on receivablesInvoices. It is NOT filterable on the receivablesInvoiceInstallments child: Oracle marks it x-queryable false there, so the child's queryable set is InstallmentId, InstallmentSequenceNumber, InstallmentDueDate and OriginalAmount only, and a LastUpdateDate filter on it is refused 400 here and on a real pod. This page claimed both until 2026-08-04. The same literal is used inside single quotes as the q filter value:

  GET https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices
    ?q=LastUpdateDate > '2026-06-25T12:00:00.000+0000'
    &orderBy=LastUpdateDate:asc,CustomerTransactionId:asc
    &limit=200

Cascade rule: any change to a child installment (create/split/close/reopen) bumps the parent invoice's LastUpdateDate. A single cursor over receivablesInvoices is therefore sufficient to detect header-level and installment-level changes for one invoice — you do NOT need to poll the installments collection separately for change detection. Per-installment change granularity is not available as a filter, and does not need to be: read the child collection for an invoice the cursor has already surfaced.

Recommended cursor algorithm (safe against clock skew, equal-timestamp ties and mid-poll writes):
  1. Persist a high-watermark `cursor` initialised to the epoch on first run.
  2. On each poll, subtract an overlap window (e.g. 5 seconds) from `cursor` to produce `since`.
  3. Page through `q=LastUpdateDate > 'since'` with `orderBy=LastUpdateDate:asc,CustomerTransactionId:asc` and `limit=200` until `hasMore` is false.
  4. Track the maximum LastUpdateDate observed across the entire page loop; write it back as the new `cursor` only after the page loop completes successfully.
  5. Upserts on your side must be idempotent — the overlap window guarantees you will occasionally re-see records that already synced.

- Canonical format: 2026-06-25T12:00:00.000+0000 (UTC, milliseconds, `+0000` offset).
- Filterable via q on receivablesInvoices only. The installments child does not accept it - Oracle marks it x-queryable false there.
- Installment mutations cascade to the parent invoice's LastUpdateDate — one cursor over invoices is enough.
- Use a small overlap window (a few seconds) and tie-break by primary key ascending to avoid missing rows updated within the same second.
- Trailing 'Z' inputs are also accepted server-side, but the response always uses `+0000`.

### 25. Quick reference

| Name | Description |
| --- | --- |
| `OAuth` | POST https://erplab.cloud/sim/{environmentKey}/oauth/token  grant_type=client_credentials&scope=urn:opc:resource:consumer::all  → access_token (TTL 3600s) |
| `List invoices` | GET https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices?limit=25&offset=0 |
| `Create invoice` | POST https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices  (≥1 receivablesInvoiceLines) |
| `Complete an invoice` | Nothing to call — POST https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices returns InvoiceStatus 'Complete' with its installments already built. /action/complete is not an Oracle action and answers 404; this row published it as a live endpoint until 2026-08-04, in the most copy-pasteable list on the page. |
| `Split installments` | POST https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{id}/action/splitInstallments |
| `Lines / Installments` | GET https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/receivablesInvoices/{id}/child/{receivablesInvoiceLines\|receivablesInvoiceInstallments} |
| `Contacts` | GET https://erplab.cloud/sim/{environmentKey}/crmRestApi/resources/11.13.18.05/contacts  (?q=PartyStatus='A', ?finder=PrimaryKey;PartyId=…, ?expand=ContactPoint) — CX base, not Financials |
| `Customer account sites` | GET https://erplab.cloud/sim/{environmentKey}/fscmRestApi/resources/11.13.18.05/customerAccountSitesLOV[/{SiteUseId}] |
| `SOAP create` | POST https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService  SOAPAction: createSimpleInvoice |
| `WSDL` | GET https://erplab.cloud/sim/{environmentKey}/soap/InvoiceService?WSDL |

