Sync Engine
A self-hosted framework for building data integrations between your application and external systems like ERPs, CRMs, and accounting platforms. Bidirectional sync with version-vector-based conflict detection, OAuth management, and a complete QuickBooks Online reference integration.
See It In Action
Watch the full demo to see bidirectional sync, OAuth management, conflict resolution, and the embeddable UI in action.
A Unique Position in the Market
The integration space has unified APIs (hosted, closed-source), ELT tools (one-way only), workflow automation (no sync state), and “open core” products with key features paywalled. A fully open-source, self-hosted, bidirectional sync platform with version vector conflict resolution doesn't exist elsewhere.
Unified APIs (Merge, Codat)
Hosted services with pre-built connectors. You can't self-host, can't see the code, and pay per connection. Write-back support is limited.
ELT Tools (Airbyte)
Great for moving data to warehouses, but one-way only. Airbyte explicitly does not support bidirectional sync.
Developer Infrastructure (Nango)
Closest alternative, but “open source” is misleading — only the API proxy is truly open. Full sync engine requires Enterprise license.
Workflow Automation (n8n)
Great for “when X happens, do Y” flows, but no built-in sync state management or conflict resolution. You build everything yourself.
How We Compare
Full source code, self-hosted deployment, and true bidirectional sync — capabilities that don't exist together in any other product.
| Capability | SaaSDog | Workato | Merge / Codat | Nango | Airbyte |
|---|---|---|---|---|---|
| Bidirectional Sync | Full | Workflow-based | Limited | Limited | No |
| Self-Hosted | Yes | No | No | Partial* | Yes |
| Full Source Code | Yes | No | No | Partial* | Yes |
| Extend with AI Coding Tools | Yes | No | No | No | One-way only |
| Conflict Resolution | Version vectors | Varies | Varies | No | N/A |
| Per-Record Sync State | Full | Limited | Limited | Limited | No |
| Push / Webhook Triggers | Built-in | Yes | Limited | Yes | No |
| OAuth Management | Built-in | Built-in | Built-in | Built-in | No |
| Embeddable UI | Yes + source | No | Yes | Yes | Yes |
| Per-Connection Pricing | None | Yes | Yes | Yes | Yes |
* Nango's free self-hosted version only includes the API proxy. Full sync engine requires Enterprise license. Airbyte is open source but designed for one-way ELT to data warehouses, not application-to-application sync.
Built for AI-Assisted Development
The QuickBooks Online integration serves as a complete reference implementation. Point Claude Code, Cursor, or GitHub Copilot at it and describe your target system — they can generate a new integration adapter, strategy, and mappers following the same patterns.
Key Features
Bidirectional Sync
Inbound, outbound, and bidirectional sync per entity type. Version vectors track changes on both sides with configurable conflict resolution.
Record-Level Sync State
Track the sync status of every individual record. Know exactly which records are synced, pending, failed, or in conflict.
OAuth & Credential Management
Built-in OAuth flow with encrypted credential storage. Supports AWS KMS, Azure Key Vault, and Fernet for development.
Reference Integration
Complete QuickBooks Online integration with OAuth, schema mapping, entity ordering, and bidirectional sync. Use it as a blueprint for new integrations.
Self-Hosted & Multi-Cloud
Deploy on your own infrastructure with Terraform. Supports AWS (ECS/Fargate), Azure, and GCP. Your data never leaves your environment.
Job History & Admin APIs
Full sync job history with per-record details. Admin APIs for cross-tenant management, sync status monitoring, and cursor resets.
Strategy & Adapter Patterns
Clean extension model: implement an Adapter for API calls and a Strategy for sync logic. Register and go.
Async & Queue-Based
Sync jobs run asynchronously via SQS (or in-memory for dev). Stuck job detection, auto-termination, and dead-letter queues built in.
Embeddable Micro-Frontend UI
Ships with a complete React UI that you can embed directly into your application via Module Federation — or run standalone. Manage integrations, monitor sync jobs, and configure sync rules without building your own interface.
Integration Management
Browse available integrations, connect via OAuth, view connection status, and manage credentials. Supports reconnect and disconnect flows.
Sync Monitoring
Real-time job list with auto-refresh, status filtering, and pagination. Drill into any job to see entity-level counts and record-level sync details.
Sync Configuration
Per-entity sync rules: enable/disable entities, set direction (inbound, outbound, bidirectional), choose conflict resolution, and configure sync frequency.
Admin Dashboard
System-wide default settings, cross-tenant management, per-entity sync status monitoring, and the ability to reset sync cursors for full re-sync.
Flexible Embedding Options
Full Standalone
Complete app with layout and routing. Deploy on its own or in an iframe.
Micro-Frontend
Content-only component — your host app provides the layout, sidebar, and navigation.
Individual Pages
Import only the pages you need: IntegrationList, IntegrationDetail, SyncJobs, or JobDetail.
// Embed in your host application via Module Federation
import { IntegrationsProvider, MicroFrontend } from 'integrations/federation'
<IntegrationsProvider config={{
apiBaseUrl: 'https://api.yourapp.com/integrations',
getAuthToken: () => getToken(),
onUnauthorized: () => redirectToLogin(),
}}>
<MicroFrontend />
</IntegrationsProvider>How Sync Works
Every record tracks three version numbers. Comparing them determines what needs to sync and in which direction.
internal_version = 3 // Bumped when your system changes the record external_version = 2 // Bumped when external system changes the record last_sync_version = 2 // Set to max(iv, ev) after successful sync // Decision logic: iv == ev == lsv → In sync (nothing to do) iv > lsv → Outbound sync needed (push your changes) ev > lsv → Inbound sync needed (pull their changes) iv > lsv AND ev > lsv → Conflict (resolved by configured master)
Inbound
External system is the source of truth. Fetch records from QuickBooks, Xero, etc. and write to your database.
Outbound
Your system is the source of truth. Detect local changes via version vectors and push to the external system.
Bidirectional
Both systems can change records. Version vectors classify each record and resolve conflicts automatically.
Change Detection & Sync Triggers
Each sync rule specifies how changes are detected and when to act on them. Combine these for polling-only, event-driven, or hybrid sync workflows.
Change Source
pollingDefault. Changes discovered during scheduled sync jobs.
pushYour system notifies the platform via POST /integrations/{id}/notify.
webhookExternal system pushes changes via POST /integrations/{id}/webhooks/{provider}.
hybridCombination of polling and webhook/push for redundancy.
Sync Trigger
deferredDefault. Bump version vectors only; changes picked up at next scheduled sync.
immediateQueue an incremental sync job as soon as the change notification arrives.
Event-Driven Sync
Combine push + immediate for near-real-time sync without polling overhead.
// Example: push-based sync with immediate trigger
{
"entity_type": "vendor",
"direction": "bidirectional",
"enabled": true,
"master_if_conflict": "external",
"change_source": "push",
"sync_trigger": "immediate"
}API Overview
Integrations
/integrations/availableList all available integrations in the catalog
/integrationsList connected integrations for the authenticated user
/integrations/{id}/connectStart OAuth flow and get authorization URL
/integrations/{id}/callbackComplete OAuth with authorization code
/integrations/{id}Disconnect an integration
/integrations/{id}/sync-statusGet per-entity sync status and timestamps
/integrations/{id}/notifyPush notification: bump internal version for changed records
/integrations/{id}/webhooks/{provider}Webhook endpoint for external system change notifications
Sync Jobs
/sync-jobsTrigger a sync job (full, incremental, or entity-specific)
/sync-jobsList sync jobs with pagination and filtering
/sync-jobs/{id}Get job details including entity-level counts
/sync-jobs/{id}/cancelCancel a running sync job
/sync-jobs/{id}/recordsGet record-level sync details (paginated)
Settings & Admin
/integrations/{id}/settingsGet sync rules, directions, and conflict resolution config
/integrations/{id}/settingsUpdate sync settings for an integration
/admin/integrationsAdmin: list all user integrations across tenants
/admin/.../sync-status/{entity}/resetAdmin: reset sync cursor for an entity
Adding a New Integration
The platform uses a Strategy + Adapter pattern. Each integration needs three things: an Adapter for API calls, a Strategy for sync logic, and Mappers for schema translation.
# 1. Adapter — handles OAuth and API calls
class XeroAdapter(IntegrationAdapterInterface):
async def authenticate(code, redirect_uri) -> OAuthTokens
async def fetch_records(entity_type, since) -> list[ExternalRecord]
async def create_record(entity_type, data) -> external_id
async def update_record(entity_type, external_id, data) -> success
# 2. Strategy — handles sync logic and entity ordering
class XeroSyncStrategy:
async def sync_entity_inbound(entity_type, ...)
async def sync_entity_outbound(entity_type, ...)
async def sync_entity_bidirectional(entity_type, ...)
def get_entity_order() -> list[str]
# 3. Mappers — bidirectional schema translation
def map_vendor_inbound(xero_data: dict) -> dict # Xero → internal
def map_vendor_outbound(internal_data: dict) -> dict # internal → Xero
# 4. Register in factory and strategy registry
adapter_factory.register("Xero", XeroAdapter)
register_sync_strategy("Xero", XeroSyncStrategy)Use the QuickBooks integration as your blueprint
The QuickBooks Online integration is a fully working reference with OAuth, 7 entity types, bidirectional sync, and schema mapping. Point your AI coding tool at it and describe your target system to generate a new integration.
Configurable Sync Rules
Each entity type has its own sync rule. Configure direction, conflict resolution, and enable/disable per entity.
{
"sync_rules": [
{
"entity_type": "vendor",
"direction": "bidirectional",
"enabled": true,
"master_if_conflict": "external"
},
{
"entity_type": "bill",
"direction": "inbound",
"enabled": true,
"master_if_conflict": "external"
},
{
"entity_type": "invoice",
"direction": "outbound",
"enabled": true,
"master_if_conflict": "our_system"
}
]
}Supported Entity Types (QuickBooks Reference)
Technology Stack
Clean Architecture
Built with hexagonal architecture. Swap databases, cloud providers, queue backends, or encryption services without touching business logic.
Domain Layer
Version vectors, sync rules, conflict resolution. No external dependencies.
Services Layer
Sync orchestrator, job runner, settings management. Coordinates adapters and strategies.
Infrastructure Layer
Database, queues, encryption, HTTP clients. Pluggable adapters for each external system.
API Layer
REST endpoints with OpenAPI spec. Multi-tenant isolation via JWT. Admin APIs for operations.
Own your integration infrastructure
Stop paying per-connection fees to iPaaS vendors. Get full source code with a working QuickBooks integration, deploy on your infrastructure, and build new integrations with AI coding tools.
Book a Demo