Before you start
Get partner access
Before writing any code, you need:- A signed partner agreement with DualEntry.
- API credentials for your partner account.
- Access to a DualEntry sandbox organization for development and certification testing.
- Access to the partner API documentation (request through your partnership contact).
Define your integration scope
Work with the integrations team to nail down the following before you write code:- Data flow direction: Pull-only, push-only, or bidirectional.
- Record types in scope: Customers, vendors, invoices, bills, journal entries, payments, etc.
- Field mapping: Which fields on your side map to which DualEntry fields, and what transformations are needed.
- DualEntry modules affected: Accounts Payable, Accounts Receivable, General Ledger, Revenue Recognition, Payroll.
- Multi-entity support: Whether customers need multiple instances of your integration in a single DualEntry org (for example, one per legal entity).
- Attachment handling: Whether you sync files (PDFs, receipts) along with records.
Key questions to resolve early
- Does your platform support sandbox or test environments? You need one for end-to-end testing.
- Does your API return paginated results? What’s the maximum page size? See Pagination for DualEntry’s conventions.
- Do you support webhooks, or does DualEntry need to poll? What polling interval is acceptable?
- What are your rate limits? What’s your recommended backoff strategy? See Rate limiting for DualEntry’s limits.
- Do you return stable, immutable external IDs that DualEntry can use for deduplication?
- If syncing attachments: what’s the maximum file size, and what file types do you support?
Implementation
Authentication
Implement the auth flow that fits your security model and your customers’ expectations. See Authentication for DualEntry’s supported flows in detail. The DualEntry side of this is simpler than most APIs you will have integrated with. There is one mechanism: an organization API key in theX-API-KEY header. There is no token exchange, no refresh step, and no session to maintain, so the same header works on the first request and the millionth.
What that means for your implementation:
- Store the key encrypted, scoped to the customer’s organization.
- Validate the key on save by making a lightweight API call before persisting it, so a typo surfaces during setup rather than on the first sync.
- The key identifies the organization, so your requests carry no separate tenant parameter and a key can never reach another organization’s data.
- If your setup UI exposes fields like Client ID or Client Secret for your own side of the connection, label them clearly. Ambiguous auth fields are a top source of failed setups, and they are more confusing when the other side of the integration needs only a single key.
Sync engine
Build the sync logic that moves data between systems. Pull integrations (DualEntry consumes data from your platform):- Run sync as a scheduled background task on your side, or expose endpoints DualEntry can poll.
- Support configurable sync intervals. DualEntry stores the interval per organization and provider as a number of seconds, bounded at a minimum of 30 minutes and a maximum of 30 days, so build for a range rather than a fixed menu of choices.
- Implement a “sync-from” timestamp that defaults to the last successful sync.
- Support manual trigger (“Sync Now”) from the DualEntry UI.
- Support full sync, sync-from-last-synced-date, and custom date range modes.
- Trigger on relevant events (record creation, status change, void, etc.).
- Queue outbound work asynchronously to avoid blocking the originating request.
- Implement retry logic with exponential backoff for failures (see Errors).
- Register a webhook endpoint during the customer setup flow.
- Validate webhook signatures or HMACs on every inbound payload. Never trust unsigned webhooks.
- Acknowledge receipt immediately and process the payload asynchronously.
- Make webhook processing idempotent: partners (and DualEntry) replay webhooks on failure.
- Expose the next scheduled sync time to the customer in the UI.
- Report every sync run to DualEntry’s Sync History so customers can see what happened and when.
- Add tracing or logging around your core sync steps so issues can be diagnosed quickly.
Field mapping and data transformation
Maintain a clear mapping between your data model and DualEntry’s. This becomes part of the integration documentation and your certification artifacts. A typical mapping looks like:
Common transformations:
- Monetary amounts: Many APIs use minor units (cents). DualEntry uses decimal major units (dollars). Convert explicitly; don’t rely on automatic coercion.
- Dates: Normalize to ISO 8601. Pay attention to timezones: partner timestamps may be UTC, local, or ambiguous, and getting this wrong causes off-by-one-day bugs.
- Statuses and enums: Map your statuses to DualEntry statuses explicitly. Document any statuses that don’t have a clean mapping.
- External IDs: Always store your stable external ID on the DualEntry record. This is what makes deduplication and incremental updates possible.
- Define explicit behavior when a source field is null, missing, or invalid.
- Use the integration-level defaults the customer configured during setup (for example, default company, default GL account).
- Never create placeholder records like “Unknown Company”. This corrupts the customer’s data and creates cleanup work.
Cut-off date enforcement
Customers set a cut-off date during setup that defines the earliest record date your integration should sync. Records dated before the cut-off are out of scope and must not flow into DualEntry. Requirements:- Accept the cut-off date during initial setup and store it in your integration config.
- Filter sync queries by cut-off date at the query level, not by fetching everything and filtering after. This is a recurring source of bugs.
- Apply the cut-off on initial sync and every subsequent sync.
- Handle edge cases:
- Records dated exactly on the cut-off date → include them.
- Records backdated by your platform after the cut-off → exclude them if their effective date is before the cut-off.
Duplicate prevention
Duplicate records are one of the most disruptive integration bugs: they corrupt customer ledgers and require manual cleanup. Get this right from day one. Requirements:- Use a stable external ID from your system as the deduplication key.
- Implement upsert logic: if a record with the same external ID already exists in DualEntry, update it instead of creating a new one.
- Make re-sync idempotent: running it twice in a row must never produce duplicates.
- Handle concurrent sync workers correctly. Use upsert semantics or proper locking so that two workers processing the same record don’t race into a duplicate write or an integrity error.
Locked / read-only records
Records imported from your platform may be locked from manual editing in DualEntry to prevent the customer’s accounting data from drifting from your source of truth.- Define which fields are editable in DualEntry vs. locked to integration-only updates.
- Make the locking behavior visible to customers: they shouldn’t be confused about why a field is grayed out.
- If admin override is supported, document the unlock flow.
Error handling and retry
Robust error handling separates a good integration from a flaky one.- Classify errors as transient (retry) or permanent (surface to user). Don’t retry indefinitely on a permanent failure.
- Use exponential backoff for transient failures: timeouts, rate limits, 5xx responses. See Errors for DualEntry’s error model and Rate limiting for backoff guidance.
- Respect rate limits. Read rate limit headers from API responses where available and adjust your throughput accordingly.
- Surface persistent failures in DualEntry’s Sync History with actionable error messages. “Sync failed” is not actionable; “Account mapping missing for vendor
Acme Co.: assign a GL account in Settings → Integrations” is. - Handle integrity errors and duplicate-key violations gracefully in async workers: don’t let one bad row kill the whole sync.
Environments
- Build and test in a sandbox DualEntry organization.
- Maintain a sandbox account on your end too, so customers and the solutions team can demo the integration end-to-end.
- Don’t ship until your integration works cleanly in both sandbox and production environments.
Multi-currency and cross-company
If your integration moves money or creates journal entries (Money-In, Money-Out, Journal Entries, Intercompany Journal Entries, or Bank Transfers), multi-currency and cross-company handling are required.Multi-currency
- Sync the original transaction currency, not just an amount converted to the customer’s base currency.
- Decide explicitly where the exchange rate comes from: your platform, DualEntry’s daily rate, or a market rate. Document this so customers know what to expect.
- Calculate and post FX gain/loss entries where applicable.
- Handle partial payments in different currencies than the underlying invoice or bill.
- Handle currency mismatches (e.g., an invoice in EUR paid in USD) and document your resolution logic.
Cross-company / intercompany
- Handle transactions that span multiple DualEntry entities.
- Create intercompany journal entries following DualEntry’s intercompany rules.
- Generate elimination entries where required.
- For bank transfers across entities, post to the correct accounts in each entity.
Multi-instance support
Some customers need multiple instances of your integration in a single DualEntry organization, for example, a customer with multiple entities on your platform mapped to multiple DualEntry companies. If you support this:- Allow multiple instances of the integration to be created within one DualEntry org.
- Differentiate instances by your platform’s entity ID.
- Run sync schedules independently per instance.
- In any mapping or settings UI surfaced inside DualEntry, make it unambiguous which instance maps to which DualEntry company.
Attachments
Not every integration needs to handle files. If yours does:- Pull or push the relevant files (PDFs, receipts, supporting documents) along with their parent record. For the attachment schema and the available API operations, see Working with Attachments.
- Respect file size limits and supported file types on both sides.
- Handle missing or inaccessible attachments gracefully: never fail the entire sync because one file couldn’t be retrieved.