REDA One Help Center
EN
Language
English EN Español ES Português PT Italiano coming soon Français FR Deutsch coming soon العربية coming soon
reda.one ↗
Home / REDA Financials AI / API & Integration / Salesforce APIs / REST API for Accounting Data

REST API for Accounting Data

Because every REDA Financials document is a Salesforce custom object, the standard REST API is your integration front door: create invoices from your CRM or billing system, query balances into a data warehouse, post documents from middleware — all with the endpoints your team already knows.

The canonical pattern: create draft, then post

Insert the header as a Draft

POST the document (e.g. refin__Sales_Invoice__c) with entity, customer, dates — status omitted (defaults to Draft) or explicitly 'Draft'. The triggers behave exactly as in the UI: document number assigned from the entity's sequence, ledger and period derived, due date from payment terms.

Insert the lines

POST the line records (refin__Sales_Invoice_Line__c) referencing the header — products, quantities, prices, tax profiles, exactly the fields the form asks for. (The composite API bundles steps 1–2 into one call neatly.)

PATCH the status to Posted

Update refin__Status__c to 'Posted'. This single field update is the posting action: the engine writes the ledger entries, calculates tax and withholding, stamps exchange rates — and enforces every gate (balanced, open period, approval, active accounts). A refused posting comes back as a standard DML error with the same verbatim message a user would see.

The endpoints, at a glance

Nothing here is REDA-specific — these are the standard Salesforce REST endpoints, shown against the refin__ objects (the package is built at API v65.0; any current version works):

TaskMethod & endpoint
Create a document headerPOST /services/data/v65.0/sobjects/refin__Sales_Invoice__c
Read one recordGET /services/data/v65.0/sobjects/refin__Sales_Invoice__c/{id}
Update (including posting)PATCH /services/data/v65.0/sobjects/refin__Sales_Invoice__c/{id}
QueryGET /services/data/v65.0/query?q=<SOQL>
Header + lines in one round-tripPOST /services/data/v65.0/composite (or composite/tree)
Discover fields & picklistsGET /services/data/v65.0/sobjects/refin__Sales_Invoice__c/describe

Posting a draft, on the wire

The posting call is deliberately anticlimactic — one field:

PATCH /services/data/v65.0/sobjects/refin__Sales_Invoice__c/a0X8d000001AbCdEAV

{
  "refin__Status__c": "Posted"
}

Success is an HTTP 204 No Content — and a fully posted document behind it. A refusal comes back as the standard error array carrying the package's human-readable message; for example, an integration user without a REDA licence seat sees:

[
  {
    "message": "You must be a licensed REDA Financials user to create, edit, or delete Accounting Transactions. Contact your administrator.",
    "errorCode": "FIELD_CUSTOM_VALIDATION_EXCEPTION",
    "fields": []
  }
]

Reading back what you created is plain SOQL:

GET /services/data/v65.0/query
    ?q=SELECT Id, Name, refin__Status__c
       FROM refin__Sales_Invoice__c
       WHERE refin__Status__c = 'Draft'

For the insert bodies themselves, pull the field list from the describe endpoint or Object Manager rather than this article — your org's field sets and required fields are the truth, and the extra dimension fields your admin added are part of it.

What the platform fills in for you

On…The triggers do…Integration consequence
Insert with no statusStatus defaults to 'Draft'You may omit refin__Status__c on creation
InsertDocument number assigned from the entity's sequence (type-aware — invoices and memos number separately); pre-setting Name opts into manual numbering, with uniqueness validated either wayDon't generate your own numbers unless you mean to own them
InsertEntity defaults fill: ledger, accounting period, due date from the vendor's payment termSend the business fields; skip the derivable ones
Changing Entity or Invoice Type on a DraftThe document re-sequences its numberExpect a new number if your middleware "moves" a draft between entities
Draft → PostedThe full engine: ledger entries, tax + WHT calculation, exchange-rate stamping, every guardPosting via API is byte-for-byte the UI's posting

Reading data

  • SOQL through the query endpoint — open invoices, unapplied receipts, aging fields (they're formula fields on the records), whatever your dashboard needs.
  • The ledger itself — refin__Accounting_Transaction__c is the posting truth; sum debits and credits by GL account and you've rebuilt any balance externally.
  • Rollups are fields — an invoice's balance due, a receipt's unapplied amount, a budget line's committed figure: all queryable directly, no computation on your side.

Rules of the road

  • No bypass exists: posted documents are locked to API edits exactly as to users; corrections go through unpost/void flows, programmatically the same status transitions.
  • Applications are records too — creating a refin__Cash_Receipt_Application__c applies a receipt (all the matching guards run); deleting it un-applies.
  • Respect the closure dates — writes into closed books are refused; your integration should date documents in open periods like any accountant.
  • Idempotency is on you — the natural key is your source system's reference (put it in the Reference field and check before insert; the vendor-reference duplicate validation helps on the AP side).
Build the sandbox habit. Point the integration at a sandbox, run one document end-to-end, and read the result in the UI — the record page shows you exactly what your API call produced, including the accounting transactions. Ten minutes of looking beats a week of guessing.

Common mistakes to avoid

MistakeWhy it hurtsDo this instead
Inserting documents with Status 'Posted' in a single callPosting is engineered around the Draft → Posted transition; a direct insert-as-Posted is outside the supported pattern and its behavior isn't guaranteedInsert Draft, then PATCH to Posted — composite makes it one round-trip anyway
Generating your own document numbers casuallyPre-setting Name switches that document to manual numbering — now uniqueness is your job, per entityLet the sequences number documents; reserve manual numbers for deliberate migration scenarios
Running the integration as a borrowed admin loginAudit trails blur, password rotations break the feed, and permissions are far wider than the jobA dedicated integration user with a licence seat and the narrowest packaged permission set that does the work
Retrying failed posts blindlyThe message told you why it failed — a closed period retries into the same wall foreverParse the error, fix the data (or route to a human), then retry
Skipping the Reference fieldYou lose your idempotency key and bank reconciliation's best matching signalAlways carry the source system's real identifier in Reference

Where to go next

  1. Bulk API — the same pattern at migration scale.
  2. API Overview — the whole landscape.
  3. Opening Balances & Data Migration — the classic REST/Bulk project.
Official Salesforce documentation The REST API itself is a standard Salesforce feature — REDA adds the objects, not the transport. The authoritative references are the REST API Developer Guide and the SOQL Reference. Links open in a new tab.

Frequently asked questions

Use the two-step (insert Draft, then update to Posted) — it's the pattern the engine is built around, it gives you a clean error boundary between "bad data" and "posting refused", and it mirrors the UI's save-then-post. Composite calls make it one round-trip anyway.

They're standard DML errors carrying the package's verbatim validation messages ("Transaction Date ... is on or before the GL book closure date...", "This document requires approval before posting."). Log them, surface them, fix the data — the messages are written for humans.

The package targets API v65+; use a current version and the refin__ objects behave like any custom objects at that version.

Yes, if it creates or posts accounting documents — the licence check runs on API writes exactly as in the UI, and an unseated user is refused with the verbatim message shown above. Give the integration user a seat and the appropriate permission set, same as a human.

No — the package ships zero custom REST resources by design. The standard sObject, query and composite endpoints against refin__ objects are the complete REST surface, which means every Salesforce REST client, ETL tool and middleware connector already speaks it.

Was this article helpful?