What is BC2SQL Sync?
BC2SQL Sync is a platform that automatically synchronizes data from Microsoft Business Central (cloud) to on-premises or cloud SQL databases. It lets you keep a local, up-to-date copy of BC data for integration with BI tools, reporting systems, and custom applications.
Which SQL databases are supported?
BC2SQL supports:
- Microsoft SQL Server — version 2016 and later
- PostgreSQL — version 12 and later
- Azure SQL Database
Does BC2SQL require additional software to be installed?
The web interface is accessible via browser with no installation needed. The bc2sql-core component (the sync engine) must be installed on the server that hosts or can reach your destination SQL database. It is distributed as a standalone executable for both Windows and Linux.
Which versions of Business Central are supported?
BC2SQL supports Business Central SaaS (cloud) via the standard OData v4 APIs. Web API access must be enabled on your BC environment. On-premises Business Central with direct database access is not supported.
Does synchronization happen in real time?
On Free, and on Flat without the webhook add-on, BC2SQL uses scheduled polling (CRON) — synchronizations run on a fixed interval rather than instantly. With webhook sync enabled — included by default on Enterprise, or added to Flat — sync is triggered by Business Central's native webhook notifications: a change in BC (including deletions) fires an incremental sync within seconds, without waiting for the next polling interval. See the scheduled vs. webhook sync section above and the dedicated Webhooks & Real-Time Sync category below for setup details.
How it works
Read the full guide
How do I register?
After installing BC2SQL on your own server (see our download page), open the bc2sql-web interface and go to /register to create your local admin account — fill in your username, email, and password, or sign in quickly with your Microsoft or Google account via OAuth2 if configured. After registration you will receive a verification email.
I did not receive the verification email — what should I do?
Check your spam/junk folder first. If you still cannot find it, log in to the app and go to Profile — there is a button to resend the verification email. If the issue persists, please contact support.
I forgot my password — how do I reset it?
On the login page, click "Forgot password?" and enter your email address. You will receive a link to reset your password. The link is valid for a limited time.
Is BC2SQL self-hosted?
Yes — on every plan. Free, Flat, and Enterprise all install bc2sql-core and bc2sql-web on your own server; there's no vendor-hosted account to sign up for. What changes between plans is the monthly sync limit, whether webhook sync is included, and — on Enterprise only — the option to have us host and manage the installation for you instead.
How does licensing work? Where do I find my license key?
The license is tied to the running bc2sql-core instance via its machine fingerprint. On Free, any key auto-activates in limited mode the first time you run it — no need to contact us first. On Flat and Enterprise, we issue your license key after you get in touch, and you add it to the core configuration file. You can verify the current license status on the Version Info page.
What happens when the license expires?
When the license expires, automatic synchronizations are suspended. The web interface remains accessible for configuration, but the sync engine will not run new jobs until the license is renewed or replaced.
Account Security
- Passwords encrypted with bcrypt
- Secure session tokens
- OAuth2 for social login
- Mandatory email verification
- Password reset via email
Where do I find the Tenant ID and Client ID in Azure?
Go to the Azure portal (portal.azure.com) → Azure Active Directory → App registrations. The Tenant ID is shown on the Azure AD overview page; the Client ID is displayed in the app registration you created for BC2SQL.
Which API permissions are required on Azure for Business Central?
In your Azure app registration, add permissions for Dynamics 365 Business Central:
Financials.ReadWrite.All— for reading and writing BC data- Alternatively
API.ReadWrite.Allfor full API access
Make sure to click Grant admin consent after adding the permissions.
How do I find the Business Central Environment Name?
Log in to Business Central and look at the browser URL. The environment name is the segment after /environments/ — typically Production or Sandbox. You can also find it in the BC Admin Center.
The BC API connection test fails — why?
The most common causes are:
- Incorrect Tenant ID or Client ID
- Expired or incorrectly copied Client Secret
- API permissions not granted or admin consent missing
- Company Name does not exactly match the name in BC
- The BC user does not have the required web API permissions
Required BC credentials
- Tenant ID (Azure AD)
- Client ID (App registration)
- Client Secret
- Company Name (in BC)
- Environment Name (e.g. Production)
Does the SQL database need to be exposed to the internet?
No. The bc2sql-core component is installed on the same network as your SQL database and connects to it locally. Only bc2sql-core needs outbound internet access (port 443) to reach the Business Central APIs — your database never needs to be publicly accessible.
The SQL connection test fails with "connection refused" — what should I check?
Verify that:
- The host/IP and port are correct (SQL Server default: 1433, PostgreSQL: 5432)
- The firewall / Windows Firewall allows inbound connections on the configured port
- For SQL Server: the SQL Server Browser service is running if you use named instances
- The SQL user has
db_datareaderanddb_datawriterpermissions on the target database
Do I need to create the destination SQL tables manually?
No. BC2SQL can automatically generate a CREATE TABLE script based on the Business Central entity metadata. In the Entity Mapping page, use the "Suggest Create Table" button to generate the SQL script, which you can then run directly on your database.
Can I sync to multiple different databases at the same time?
Yes. BC2SQL supports multiple Remote DB Config entries (SQL endpoints), and you can associate different entity mappings with different databases. Each mapping can point to a different SQL endpoint.
Can I connect to a cloud database on Azure (Azure SQL / Azure Database for PostgreSQL)?
Yes. Fill in the standard fields (host, port, username, password) using the values from your Azure resource:
- Azure SQL Database: host =
myserver.database.windows.net, port1433, username and password as configured in Azure. - Azure Database for PostgreSQL – Flexible Server: host =
myserver.postgres.database.azure.com, port5432. SSL is negotiated automatically. - Azure Database for PostgreSQL – Single Server (legacy): same as above, but the username must include the server name:
myuser@myserver.
For advanced scenarios (custom SSL certificates, specific connection options), use the Connection String field instead of individual fields — it is passed directly to the driver without any modification. Example for PostgreSQL:
Required SQL connection details
- Host / IP of the SQL server
- Port (1433 for SQL Server)
- Database name
- SQL username
- SQL password
db_datareader + db_datawriter are sufficient for synchronization.
What is the difference between Full and Incremental synchronization?
- Full: downloads all records from the BC entity and upserts them into the SQL database. Slower but guarantees complete alignment. Recommended for the first sync or after issues.
- Incremental: downloads only records modified since the last synchronization (based on the
lastModifiedDateTimefield in BC). Much faster — ideal for frequent scheduled syncs.
How does Field Mapping work?
For each Entity Mapping you can define the correspondence between Business Central entity fields and SQL table columns. If no field mapping is configured, BC2SQL attempts to auto-map fields with matching names. Custom field mapping lets you rename columns, exclude fields, or apply transformation rules.
What are Transformation Rules?
Transformations let you modify a field value during synchronization. Available functions include: UPPER, LOWER, TRIM, REPLACE, FORMAT_DATE, CONCAT, DEFAULT_IF_EMPTY, and more. They are useful for normalizing data before it is inserted into SQL.
Can I filter which records are synchronized?
Yes. In the Entity Mapping configuration you can set an OData filter that is applied to the Business Central API call. For example, you can sync only active customers or invoices from a specific year. The syntax follows the OData v4 standard.
What happens to records deleted in BC?
Incremental mode does not automatically delete records from SQL when they are removed in BC (the OData APIs do not expose deleted records). To handle deletions, run a periodic Full synchronization with the orphan-record cleanup option enabled.
Sync modes at a glance
- All records
- Slower
- First sync or maintenance
- Only recent changes
- Very fast
- Day-to-day use
How do I write a CRON expression?
BC2SQL uses the standard 5-field CRON syntax:
│ ┌── hour (0-23)
│ │ ┌── day of month (1-31)
│ │ │ ┌── month (1-12)
│ │ │ │ ┌── day of week (0-7, 0=Sun)
* * * * *
Practical examples:
*/15 * * * *— every 15 minutes0 * * * *— every hour (at minute 0)0 6 * * *— every day at 06:000 6 * * 1-5— Monday–Friday at 06:000 0 * * 0— every Sunday at midnight
What is the recommended minimum frequency?
It depends on data volume. For incremental syncs with few records, running every 5 minutes (*/5 * * * *) is feasible. For full syncs on large tables, once per day is recommended. Avoid excessively high frequencies to prevent hitting Business Central API rate limits.
Can I trigger a sync manually?
Yes. In the Entity Mapping → Detail page, the "Run Sync Now" button immediately triggers a synchronization for that entity, regardless of the CRON schedule.
How do I temporarily disable a job?
Every Sync Job has an Active/Inactive toggle. Disabling the job prevents the CRON from running until you re-enable it. You can also disable the entire Entity Mapping to pause all related jobs.
Quick CRON reference
| */5 * * * * | Every 5 min |
| */15 * * * * | Every 15 min |
| 0 * * * * | Every hour |
| 0 6 * * * | Daily at 6:00 |
| 0 6 * * 1 | Every Monday 6:00 |
Where can I see synchronization logs?
The Sync Logs section shows the detail of every execution: status (success/error), number of records processed, duration, and error message. You can filter by date, entity, and status. Logs can be exported as PDF or CSV.
The sync fails with "401 Unauthorized" from Business Central
This error indicates an OAuth2 authentication problem. Check:
- The Client Secret has not expired (Azure secrets have a configurable lifetime)
- The Client ID and Tenant ID are correct
- API permissions on Azure have been granted with Grant admin consent
- The Azure app is registered in the correct tenant
The sync is slow or times out
If synchronizations take too long:
- Check network connectivity between the server running bc2sql-core and the BC APIs
- Use incremental mode instead of full for regular syncs
- Reduce the number of mapped fields if not all are needed
- Verify that Business Central rate limits are not being exceeded (error 429)
The sync service shows as offline in the dashboard
The status badge in the navbar indicates whether bc2sql-core is reachable. If it appears offline:
- Verify the bc2sql-core process is running on the server
- Check that the host and port in the config file are correct
- Review the core logs for startup errors
- Check that the firewall is not blocking communication between the web app and the core
How do I contact support?
You can reach us via:
- The Contact form in the application (login required)
- Direct email: [email protected]
When reporting an issue, please include: software version, error type, full error log text, and the operating system of your server.
Debug checklist
- Is bc2sql-core running?
- BC connection test → OK?
- SQL connection test → OK?
- License valid?
- Entity mapping active?
- Sync job active?
- Error logs reviewed?
What are BC2SQL webhooks and how do they differ from scheduled sync?
Instead of waiting for the next CRON tick, BC2SQL subscribes directly to Business Central's native webhook notifications for the entities you choose. When a record is created, updated, or deleted in BC, an incremental sync for that entity is triggered within seconds — the polling schedule keeps running for everything else, unaffected.
Which plans include webhook sync?
Webhook-triggered sync is included by default on Enterprise, and available as a paid add-on on Flat. Free uses scheduled polling only — see scheduled vs. webhook sync for a comparison.
How do I enable webhooks for an entity?
First enable webhooks on the relevant BC API Config (this generates a public receiver URL and a signing secret for that Business Central tenant). Then, from the entity mapping detail page, use the Enable Webhook toggle to create the subscription with Business Central. The Webhooks section lists every active subscription with its status, expiration, and recent event count.
What are the requirements to use webhooks?
Business Central requires an HTTPS public URL to deliver notifications to — it will not send webhooks to plain HTTP. Since BC2SQL runs on your own server, exposing that endpoint (e.g. via a reverse proxy or tunnel) is part of your own setup — unless you choose Enterprise's fully-managed hosting, in which case we handle it for you. Each Business Central connection has its own signing secret, so notifications are verified per tenant and rotating one tenant's secret never affects another's.
How are deleted records handled?
Deletions are the one change scheduled incremental sync cannot see, because Business Central's OData API does not expose removed records. Webhook delete notifications close that gap: the deleted record's key is queued and removed from the destination table right before the next incremental sync for that entity runs.
What happens if a subscription expires or Business Central stops delivering notifications?
Subscriptions are renewed automatically well before they expire. If a renewal fails repeatedly, the subscription is marked as failed and flagged in the Webhooks section, where you can re-enable it with one click. Scheduled polling on your plan (where applicable) continues to run independently, so a webhook hiccup never stops synchronization entirely.
Can I see a history of webhook events?
Yes. Each subscription keeps a 7-day audit log of received notifications — change type, resource, timestamp, and whether it triggered a new sync job or was coalesced into an already-pending one — accessible from the Webhooks section.