← Back to blog

Oracle Fusion REST API: Uploading and Downloading File Attachments on Any Resource

By Mostafa Mansour 6 min read Oracle Fusion CloudREST APIAttachmentsFSCM

Oracle’s own REST API reference documents attachments separately for every module — Financials, SCM, Procurement, Sales and Service, Project Management, Common Features — each with its own page, its own resource name in the URL, and no cross-references between them. Search for a general “how do I upload a file through the Oracle Fusion REST API” guide and every result is one of those module-scoped reference pages, plus a scattering of Cloud Customer Connect threads asking variations of the same question (“how upload an attachment to Item using REST API,” “REST API for File upload and download in Oracle Fusion Cloud,” “can I upload a base64 encoded file through the Documents REST API”). No third-party guide ties it together as what it actually is: one pattern, reused almost identically across dozens of resources.

In our own 184-endpoint catalog alone, attachments appears as a child resource on more than 30 different parent resources spanning both HCM and FSCM — invoices, receivablesInvoices, receivablesCreditMemos, documentRecords, recruitingJobRequisitions, locationsV2, jointVentures, externalBankAccounts, and many more. If you’ve read our documentRecords REST API guide, you already know most of this — that post covers the same mechanism in HCM-specific depth. This post is the module-agnostic version: the same request shape, demonstrated against a Financials resource, so it’s clear the pattern isn’t an HCM quirk.

The pattern, in one shape

Every resource that supports attachments exposes the same child path and the same core fields, regardless of module:

POST /{resource}/{id}/child/attachments

with a payload built from a small, consistent set of attributes:

FieldPurpose
FileNameThe name shown in the UI and returned on GET
TitleDisplay title (often the same as FileName)
ContentType or UploadedFileContentTypeMIME type — application/pdf, image/png, etc.
CategoryNameAttachment category (module-dependent picklist, e.g. MISC)
DatatypeCodeUsually FILE for a binary upload
FileContentsThe file itself, base64-encoded

FileContents is the one field people get wrong most often — it has to be base64, not raw bytes, not a file path, not a URL. Encode it yourself before building the request (base64 -w 0 file.pdf on Linux avoids line-wrap corruption; base64 -i file.pdf on macOS).

Catalog-verified example: attaching a file to an invoice

invoices is a real FSCM resource with attachments as one of its seven child resources (alongside invoiceLines, invoiceInstallments, invoiceDff, and others). Attaching a supporting document to an existing invoice:

curl -X POST \
  -u username:password \
  -H "Content-Type: application/vnd.oracle.adf.resourceitem+json" \
  -d '{
    "FileName": "supporting-invoice.pdf",
    "Title": "supporting-invoice.pdf",
    "ContentType": "application/pdf",
    "CategoryName": "MISC",
    "DatatypeCode": "FILE",
    "FileContents": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoK..."
  }' \
  'https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/invoices/300000012345678/child/attachments'

The same shape works unchanged against receivablesInvoices/{id}/child/attachments, recruitingJobRequisitions/{id}/child/attachments, or any of the other 30-plus resources — only the base path and the module-specific CategoryName values change.

Downloading a file back out

GET the attachment collection first to find the attachment’s own ID:

curl -u username:password \
  'https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/invoices/300000012345678/child/attachments'

Each item in the response includes a links array with a rel: "enclosure" entry pointing at the raw file — GET that URL directly and you get the file’s actual bytes and content type back, not a JSON wrapper:

curl -u username:password \
  'https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/invoices/300000012345678/child/attachments/00020000.../enclosure/FileContents'

This enclosure-link download mechanism is identical to the one our documentRecords post covers in HCM — it’s the same REST framework feature, not a separate one per module.

Two things that trip people up

Attachment created but the file comes back empty or corrupted. Almost always a base64 encoding problem — either the encoder wrapped lines (Oracle expects an unwrapped base64 string) or the JSON layer double-escaped it. Re-encode with line-wrapping disabled and verify the string decodes cleanly before sending it.

Large files fail or time out. Cloud Customer Connect has multiple live threads about this — files in the 50–100MB range routinely hit request-size or gateway timeout limits when base64-encoded inline (base64 itself adds roughly 33% overhead on top of the original file size, making the problem worse than it looks). For anything beyond a few megabytes, Oracle’s own guidance points integrators toward WebCenter Content (UCM) upload plus a reference, or a middleware/OIC staging step, rather than one large inline REST payload.

Checking whether a resource supports attachments before you build against it

Not every resource has an attachments child — it depends on whether that business object was set up for the Fusion attachment framework. The /describe endpoint lists a resource’s actual child resources, so you can confirm attachments exists before writing integration code that assumes it does.

OPAL bundles this child-resource metadata for 184 of the most-used Oracle Fusion Cloud REST endpoints locally and offline — attachments shows up as a searchable child resource on every endpoint that has it, across both HCM and FSCM, so you can check before you touch a live instance.


This post is part of our complete Oracle Fusion API guide — base URLs, authentication, q filters, finders, and common errors in one place.

Explore Oracle Fusion APIs offline

OPAL bundles 59,000+ Oracle Fusion REST endpoints, fully searchable offline, with a visual Q Builder and Finder Builder that only offer fields the endpoint actually accepts — so your filter can't 400.

Free, no account required. Pro adds live requests and multi-step Flows.