Overview
The Custom Accounting Integration pushes approved financial records out of INGENIOUS.BUILD via webhooks. Because every accounting system has its own API, the integration is intentionally system-agnostic: INGENIOUS sends a standard JSON payload to a webhook URL you control, and middleware on your side (n8n, Retool, Zapier, Jitterbit, or a custom service) transforms that payload and forwards it to your accounting system's API.
This gives you full control over how data lands in your accounting system, while keeping that system as the source of truth for posted transactions.
Supported objects to sync out:
Budgets
Budget Changes
Vendor Contracts
Vendor Contract Changes
Vendor Invoices
Prerequisites
Workspace admin access in INGENIOUS.BUILD (Company Settings → Integrations Hub)
An HTTPS endpoint that can accept POST requests with JSON bodies and custom headers — provided by your middleware tool or built in-house
Access to your accounting system's API, or a middleware tool that can call it
For loading data into INGENIOUS: an Access Token or OAuth client (see the API Overview & Reference Guide)
Heads up: Coupa, SAP, and similar systems are not plug-and-play. Your middleware is responsible for transforming the INGENIOUS payload into the format your accounting system expects. Tools like Jitterbit can help with Coupa specifically, but the choice of middleware is yours.
How It Works
Data moves in two directions, and it's important to understand the difference before you start.
Outbound: INGENIOUS → your accounting system
When a user clicks Sync to Accounting on an approved record, INGENIOUS sends a POST request with a JSON payload to your configured webhook URL.
Trigger: A user clicks Sync to Accounting on a record that meets prerequisites (for invoices, typically internally approved).
Result: Your endpoint receives a JSON payload. Your middleware transforms it and calls your accounting system's API.
Inbound: your accounting system → INGENIOUS
Webhooks only push data out. To bring accounting data into INGENIOUS — vendors, GL accounts, cost codes, projects, business units — use the Public API or, where available, UI / CSV import.
Object | How to load into INGENIOUS |
Accounting Cost Codes | Public API or CSV import |
Accounting Companies (Vendors) | Public API or Accounting companies module |
Accounting Entities (GL Accounts) | Public API |
Projects | Public API |
Business Units | Public API |
Important Distinction: Outbound (Webhooks) vs. Inbound (Public API)
The Custom Accounting Integration (CAI) feature exclusively uses a Webhook “Push” model for Outbound data. INGENIOUS automatically pushes the payload to the customer’s middleware endpoint the exact moment a user clicks Sync to Accounting. If a customer’s IT team intends to run a scheduled script to poll INGENIOUS to export data (e.g., querying the API every 15 minutes for invoices in the submitted_to_accounting state), they do not need to enable or use the CAI feature. They should simply build a standard integration using our Public API, but retrieve the invoices in any of the approved statuses. Mixing these two approaches for outbound data is an anti-pattern.
Note: Customers using CAI Webhooks for outbound data MUST still use the Public API for Inbound data, such as creating Accounting Companies or syncing Payments back to INGENIOUS.
Comparing Approaches: CAI Webhooks vs. API Polling
When discussing integration design with customers, you can help them choose the right path by sharing these trade-offs:
Advantages of using CAI (Webhooks):
Built-in Validation (“No map, no button”): CAI enforces Mapping Requirements (e.g., verifying the Accounting Company, Cost Code, or Project are assigned) before the user can even click Sync to Accounting. This guarantees that records are properly linked to existing accounting objects before the data is ever sent, drastically reducing downstream errors.
Real-Time Data: The payload is pushed instantly the moment the user clicks the button. There is no waiting for the next scheduled polling cycle.
Advantage of using Public API (Polling) exclusively:
Simplified Infrastructure: The customer avoids having to host, secure, and maintain webhook receiver endpoints, relying entirely on their own scheduled API GET requests.
Process
Step 1: Enable the Custom Accounting Integration
Log in to INGENIOUS.BUILD.
Navigate to Company Settings → Integrations Hub.
Select Custom Accounting Integration.
Click Start Integration.
Step 2: Configure Mapping Requirements
This is the first decision in setup, and it controls how strictly INGENIOUS validates records before allowing them to sync to your accounting system.
In the Mapping Requirements panel, choose which of the following must be mapped on a record before it can be synced:
Accounting Entity (GL Account)
Project
Cost Code
Cost Type
Business Unit
Company (Vendor)
All boxes can be left unchecked.
What happens depending on your choice:
Nothing required — INGENIOUS will never block Sync to Accounting. The webhook payload will contain only INGENIOUS-native data with no external accounting IDs. It's on your middleware to identify and match resources on its own.
Some required — INGENIOUS will block Sync to Accounting until those mappings are filled in on the record.
Tip: Start with no required mappings during testing, then turn requirements on as your middleware matures and you're ready to enforce data quality.
Step 3: Add webhook URLs and headers
For each object type you plan to sync (Budgets, Budget Changes, Contracts, Contract Changes, Invoices):
Paste the webhook URL for that object type.
Add any authorization headers your endpoint expects, for example:
Authorization: Bearer your-token-here.
You only need to fill in URLs for the objects you actually plan to sync — leave the others blank.
Step 4: Load accounting data into INGENIOUS
It is best if those accounting object records exist in INGENIOUS first. Use the Public API or CSV import (where supported) to create them.
Best practice — always set a custom_id:
When you create accounting objects in INGENIOUS (via Public API or CSV), include a custom_id value that matches the corresponding record's identifier in your accounting system. That same custom_id appears in every webhook payload, so your middleware can match records directly with no extra lookups. Skipping this means slower syncs and more API calls back to INGENIOUS.
Step 5: Map fields on records (if required)
If you enabled any Mapping Requirements in Step 2, those fields need to be filled in on the record itself before it can sync:
Select the Accounting Company for the vendor on an invoice
Assign Accounting Cost Codes to each line item
Assign the Accounting Entity / GL Account to the record
And so on for any other required field
If you didn't require any mappings, skip this step.
Step 6: Test with a sample record
Create a small invoice (or other supported record) and take it through approval.
Map the required fields, if any are enforced.
Click Sync to Accounting.
Confirm your middleware received the payload.
Confirm your middleware successfully forwarded the data to your accounting system.
For a fast end-to-end test, you can temporarily point your webhook URL at a request bin tool to inspect the raw payload before wiring up the full middleware pipeline.
Confirmation message
When the sync succeeds in INGENIOUS, you'll see:
"Successfully Synced"
All payloads share the same top-level shape:
json
{ "name": "...", "subject": "...", "data": { ... } }The data object contains the record's contents plus the accounting mapping identifiers.
Accounting identifier fields
Each payload includes both INGENIOUS-native IDs (id, vendor_id, project_id, contract_id, cost_code_id, etc.) and accounting object fields:
accounting_project_id,accounting_project_custom_idaccounting_company_id,accounting_company_custom_idaccounting_cost_code_id,accounting_cost_code_custom_idaccounting_entity_id,accounting_entity_custom_id
For line items, you'll also see fields like unit_value, gross_value, qty, and any per-line accounting mappings.
How the accounting fields behave
The behavior depends on your Mapping Requirements configuration and whether you set a custom_id on the accounting object:
Scenario |
|
| What it means for your middleware |
Mapping not required | Empty | Empty | Your middleware matches records on its own |
Mapping required, no | Populated (INGENIOUS internal ID) | Empty | You can call the matching Public API |
Mapping required, | Populated | Populated | Ideal — your middleware matches directly, no extra lookups |
For full payload schemas for each object type, see the Webhook Payloads reference.
Common Questions
Can we use this with Coupa, NetSuite, QuickBooks, SAP, or our custom ERP?
Yes. INGENIOUS is agnostic of your accounting system. Your middleware handles the translation from the INGENIOUS payload to whatever API your system uses. Some accounting platforms have native integrations such as QuickBooks that you can try instead. No middleware or coding needed on your side.
Do webhooks also import data into INGENIOUS?
No. Webhooks only push data out when a user clicks Sync to Accounting. To bring data into INGENIOUS, use the Public API or CSV imports.
What needs to exist before we can export an invoice?
The invoice has to meet your workspace's export prerequisites — typically internally approved — and all fields you've marked as required in Mapping Requirements must be filled in on the record.
If a vendor exists in INGENIOUS but not in our accounting system, will the export create it there?
No. INGENIOUS does not create new records in your accounting system. Your middleware is responsible for that logic if you need it. Typically, vendors should already exist in both systems and be linked via Accounting Company.
Can we push existing accounting data from our accounting system into INGENIOUS automatically?
Yes — but not through this webhook integration. Use the Public API to write that data into INGENIOUS. You would build that flow in the opposite direction of the sync-out webhook.
Which middleware should we use?
That's your call. Common choices include n8n, Retool, Zapier, Jitterbit (often used for Coupa), or a custom service. Anything that can receive a webhook and call your accounting system's API will work.
Troubleshooting
No payload arrives at your endpoint
Confirm the webhook URL is correct and reachable over HTTPS
Confirm the authorization header matches what your server expects
Confirm any required Mapping Requirements are filled in on the record
Your endpoint returns 400 or 401
Pull your endpoint logs — the root cause is almost always on the middleware side
Common culprits: missing or incorrect auth header, wrong content type, schema assumptions that don't match the actual payload
Re-check the payload against the Webhook Payloads reference
Line items are missing accounting identifiers
Confirm Accounting Cost Codes have been created in INGENIOUS
Confirm cost codes are mapped on the line items
If Cost Codes are required in your Mapping Requirements, the sync will be blocked until they're mapped — that's expected behavior
Vendor isn't recognized in your accounting system
Confirm an Accounting Company exists in INGENIOUS for that vendor
Confirm the Accounting Company is linked to the vendor on the record
Confirm the matching vendor record exists in your accounting system, and that your middleware is matching on the right field (
accounting_company_custom_id)
accounting_*_id is populated but accounting_*_custom_id is empty
This means the mapping is required, but the accounting object in INGENIOUS was created without a custom_id. You have two options:
Quick fix: Use the
accounting_*_idand call the matchingGetPublic API endpoint to retrieve the full record. Adds an extra API call per record.Right fix: Update the accounting object in INGENIOUS to include a
custom_idso future payloads are self-contained.
Fast-path test for any issue
Create a small approved invoice with one line, map a known Accounting Company and Accounting Cost Code, paste a test webhook URL (a request bin works), click Sync to Accounting, and inspect what arrived against the Webhook Payloads reference. This isolates whether the problem is on the INGENIOUS side, the network, or your middleware.
Setup Checklist
HTTPS endpoint ready, accepts JSON with headers
Webhook URL(s) and auth header(s) added under Custom Accounting Integration settings
Mapping Requirements configured (or intentionally left blank for testing)
Accounting Companies, Cost Codes, Entities, Projects, and Business Units loaded in INGENIOUS — with
custom_idset on each where possibleRequired fields mapped on the test record
Test record approved
Test record synced via Sync to Accounting
Payload received by middleware and successfully forwarded to accounting system
Summary
The Custom Accounting Integration gives you a flexible, system-agnostic way to push approved financial data from INGENIOUS.BUILD into any accounting system you use. Webhooks handle the outbound flow; the Public API and CSV imports handle the inbound flow. With Mapping Requirements thought through up front and custom_id values set on every accounting object, your middleware can match records cleanly without extra lookups — and your accounting system stays the source of truth for posted transactions.
