Skip to main content
Insyrge - Zoho CRM & Business Automation Consulting
← Back to All ArticlesAI & Business Automation

Legacy ERP CRM Integration Without Downtime

How to connect an on-premise ERP with no modern API to a cloud CRM safely, using staging tables, secure agents and staged rollout.

•Manav Sharma
Legacy ERP CRM Integration Without Downtime

Legacy ERP CRM integration without opening your firewall: staging tables, an outbound agent, idempotent upserts and a staged, low-risk rollout plan.

Plenty of businesses run their operations on an ERP installed years ago on a server in the office or a data centre. It holds the stock, the pricing, the invoices and decades of customer history, and it works. Meanwhile, sales have moved to a cloud CRM. The two need to share customers, products, orders and balances, but the ERP was never designed to talk to the internet: no modern API, limited documentation and a firewall that IT is rightly protective of. Legacy ERP CRM integration is the work of connecting them safely without replacing the ERP or interrupting the business. This guide covers the integration patterns that work with older systems, how to keep the connection secure, how to roll it out without downtime, and a worked example.

Why legacy ERPs are hard to integrate

Older on-premise ERPs share a few traits that make integration harder than connecting two cloud apps:

  • No REST API, or an API limited to a few objects
  • Business logic buried in stored procedures, screens or batch jobs
  • Data models with cryptic table names and codes understood by a few long-serving staff
  • Servers behind firewalls that block inbound connections from the internet
  • Vendor support that has ended or become expensive
  • Batch processes that lock tables at certain times of day

None of these is a reason to avoid integration. They simply mean choosing patterns that respect the ERP's limits.

Integration patterns for legacy ERP CRM integration

PatternHow it worksGood forWatch out forStaging tablesThe ERP or a job writes changes to dedicated tables; an agent reads and sends themERPs with database accessNever write directly to core ERP tablesFile exchangeThe ERP exports CSV or XML files on a schedule; an agent picks them upERPs with export features but no database accessFile naming, partial files and archivingVendor API or connectorUse whatever API or integration module the ERP offersSupported, modern-enough versionsLicensing costs and version limitsDatabase change captureDetect changes from database logs or timestampsHigh volumes and near-real-time needsComplexity and vendor support termsScreen automationSoftware operates the ERP's user interfaceA last resort when nothing else existsFragile; breaks when screens change

For most legacy systems, staging tables or file exchange combined with a small on-premise agent is the safest starting point. The agent runs inside the network, reads from the ERP side and makes only outbound connections to the CRM, so no inbound firewall rule is needed.

Security for on-premise connections

Opening the ERP to the internet is almost never necessary. Design the connection so that:

  • The on-premise agent initiates all connections, outbound over HTTPS
  • The agent's database account can read staging tables and nothing else; writes back to the ERP go through a separate controlled table or the ERP's own import process
  • Credentials and tokens are stored in a secrets manager or protected configuration, not in scripts, following guidance such as the OWASP Secrets Management Cheat Sheet
  • Every record sent and received is logged with timestamps for audit
  • IT reviews and approves the agent like any other server software

This approach usually wins IT's support quickly, because it adds no new entry points to the network.

Rolling out without downtime

Replace the old way of sharing data gradually rather than switching everything at once:

  1. Start read-only: send ERP data to the CRM, such as customers and products, while users keep their existing processes
  2. Run in parallel: compare what the integration produces with the manual process for a few weeks
  3. Add flows one at a time, such as order status, then invoices and balances
  4. Introduce writes back to the ERP last, such as new orders from the CRM, through the ERP's own import mechanism
  5. Retire manual steps only after each flow has run cleanly for an agreed period

Schedule heavy reads outside the ERP's batch windows, and agree a maintenance process so ERP upgrades or patches do not silently break the integration.

Worked example: legacy ERP CRM integration with staging tables

Suppose a manufacturer runs an on-premise ERP on a SQL database, with about 6,000 customers and 15,000 products. Sales use Zoho CRM. The ERP vendor offers no supported API for this version, but the IT team can add a staging table and a database trigger or nightly job that writes changed customers into it. An agent on a small internal server reads new staging rows every ten minutes and upserts them into Zoho CRM using the customer number as a unique field.

The agent's core loop is sketched below. It is illustrative and untested; the table, columns, CRM field names and token handling are placeholders.

import requests

API = "https://www.zohoapis.com"  # use the api_domain returned with your token

def push_changed_customers(conn, token):
    cur = conn.cursor()
    cur.execute(
        "SELECT staging_id, cust_no, name, city, credit_limit "
        "FROM crm_customer_staging WHERE sent_at IS NULL ORDER BY staging_id"
    )
    rows = cur.fetchmany(100)
    if not rows:
        return 0
    records = [
        {"ERP_Customer_No": r[1], "Account_Name": r[2], "Billing_City": r[3], "Credit_Limit": r[4]}
        for r in rows
    ]
    resp = requests.post(
        f"{API}/crm/v8/Accounts/upsert",
        headers={"Authorization": f"Zoho-oauthtoken {token}"},
        json={"data": records, "duplicate_check_fields": ["ERP_Customer_No"]},
        timeout=30,
    )
    resp.raise_for_status()
    results = resp.json().get("data", [])
    for row, result in zip(rows, results):
        if result.get("status") == "success":
            cur.execute("UPDATE crm_customer_staging SET sent_at = CURRENT_TIMESTAMP WHERE staging_id = ?", (row[0],))
        else:
            cur.execute("UPDATE crm_customer_staging SET error = ? WHERE staging_id = ?", (result.get("code"), row[0]))
    conn.commit()
    return len(rows)

The staging table is the only part of the ERP database the agent touches, and only to mark rows as sent or failed. Zoho's Upsert Records API accepts up to 100 records per call and matches them on the duplicate check field, so a row sent twice after a network failure simply updates the same account.

The rollout plan for this example:

WeekFlowDirectionMode1 to 2CustomersERP to CRMRead-only, compared with manual lists3 to 4Products and price listsERP to CRMRead-only5 to 6Outstanding balancesERP to CRMRead-only, shown on account records7 to 10Sales ordersCRM to ERPThrough an import table processed by the ERP

Writing sales orders back to the ERP comes last, once the read flows have proven reliable, and goes through an import table that the ERP's own process validates, rather than direct inserts into order tables.

When to replace instead of integrate

Integration extends the life of a working ERP, but it does not fix one that no longer fits. If the ERP cannot support new products, entities or regulations, if nobody left understands its data, or if the integration effort keeps growing, plan a replacement and use the integration as a bridge during the transition.

Reconciliation is the natural partner to any ERP integration; our guide to Zoho CRM ERP integration explains how to catch differences between systems. For more modern ERPs with APIs, our guide to SAP, NetSuite and Odoo API connectors covers connector design.

Frequently Asked Questions

Can a legacy ERP without an API be integrated with a cloud CRM?

Usually, yes. Staging tables, scheduled file exports or a vendor connector, combined with an on-premise agent that connects outbound to the CRM, work with most older systems.

Do we need to open our firewall to integrate an on-premise ERP?

Not normally. An agent inside the network can make outbound HTTPS connections to the CRM, so no inbound access to the ERP is required.

How do we avoid disrupting the ERP during integration?

Read from staging tables or exports rather than core tables, schedule heavy work outside batch windows, start read-only and add writes back through the ERP's own import process.

Should we replace the legacy ERP instead?

Replace it when it no longer supports the business or nobody understands its data. Otherwise, integration can extend its life and act as a bridge if replacement comes later.

Connect your ERP and CRM with us

We integrate on-premise and legacy ERPs with cloud CRMs using secure agents, staging tables and staged rollouts. See our CRM and API integration services, or talk to us about your ERP integration.

About the Author

Manav Sharma is the founder of Insyrge and a CRM solutions architect. He works across Zoho, Salesforce, HubSpot, Odoo and more, designing the CRM setups, integrations and automations that keep sales and operations teams working from the same data.

Need Help Implementing This in Your Business?

Our certified Zoho consultants and automation experts can help you design and deploy custom workflows tailored to your operations.

Book Free Consultation