Design a reliable integration
Use idempotency, external IDs, pagination, incremental sync, and safe retries to keep Wafeq and your system consistent.
Design a reliable integration
Accounting integrations must be correct under retries, timeouts, delayed web requests, and partial failures. Design for those cases before moving real financial data.
Use two identifiers
| Identifier | Purpose |
|---|---|
| Wafeq id | Canonical identifier for API relationships |
| Your external_id | Durable mapping back to the source-system object |
| X-Wafeq-Idempotency-Key | Retry protection for one logical write operation |
An external ID is not a substitute for idempotency. Store both the source ID and returned Wafeq ID in a tenant-scoped mapping table.
Make writes idempotent
For POST endpoints that expose the header:
X-Wafeq-Idempotency-Key: <stable-unique-value>Recommended approach:
- Derive or generate one key for the logical operation.
- Persist it before sending the request.
- Reuse it when the same request times out or receives a retryable error.
- Generate a new key for a genuinely new operation.
- Store the returned Wafeq ID atomically with the source record.
Do not create a second accounting document merely because the first response was lost.
Retry selectively
| Result | Retry? |
|---|---|
| Network timeout | Yes, with the same idempotency key |
| 429 | Yes, with backoff and the same key |
| 5xx | Usually, with exponential backoff and jitter |
| 400 validation error | No; correct the payload |
| 401 or 403 | No automatic loop; repair credentials or access |
| 404 relationship ID | No; verify tenant and mapping |
Set a retry limit and move exhausted operations to a queue that operators can inspect.
Page through complete datasets
List endpoints return count, next, previous, and results. Follow next until it is null.
Do not calculate later page URLs yourself when the response already provides them. This preserves all server-selected filters and page sizing.
Synchronize incrementally
Many list endpoints expose filters such as created_ts_after, created_ts_before, modified_ts_after, and modified_ts_before.
A safe pull loop:
- Record a high-water timestamp before starting.
- Request changes from the previous completed checkpoint through that timestamp.
- Process every page and upsert by Wafeq ID.
- Commit the new checkpoint only after all pages succeed.
- Use a small overlap window and deduplicate by ID to protect against clock and commit timing.
Keep checkpoints per organization and object type.
Validate accounting relationships
Before sending a document:
- Confirm every related ID belongs to the connected organization.
- Validate currency and required exchange-rate context.
- Resolve accounts, tax rates, contacts, projects, cost centers, branches, and items.
- Keep invoice/payment and bill/payment allocations internally consistent.
- Reject source changes that would silently rewrite posted history.
Protect credentials and data
- Call Wafeq only from trusted server-side infrastructure.
- Redact API keys from logs and error trackers.
- Log request IDs, source IDs, endpoint, status, latency, and idempotency key—not sensitive payloads by default.
- Separate test and production organization connections.
- Provide a clear revoke and reconnect path.
Reconciliation jobs
Run scheduled checks for:
- Source records without a Wafeq ID.
- Wafeq mappings whose records now return 404.
- Open invoices and bills whose balances changed.
- Payments whose allocations do not match the source.
- Sync checkpoints that have stopped advancing.
Reliable integrations make inconsistencies visible instead of silently creating compensating data.
Updated about 1 hour ago