ml-connector
VismaSnowflake

Visma and Snowflake integration

Visma.net ERP runs your accounting and finance. Snowflake stores and queries data at scale. Connecting the two brings your Visma financial records into Snowflake so you can analyze spending, reconcile accounts, and audit transactions without exporting and re-keying. Each day ml-connector pulls what has changed in Visma since the last sync and loads it into Snowflake tables, so your warehouse always holds the current state of your suppliers, invoices, purchase orders, and GL accounts.

How Visma works

Visma.net ERP exposes suppliers, invoices, purchase orders, purchase receipts, GL accounts, dimensions, journal transactions, and budget data through REST APIs over HTTPS. Authentication uses OAuth 2.0 client credentials via Visma Connect; the service obtains a token using client_id, client_secret, and tenant_id, and includes the ipp-company-id header on every call. Visma supports both webhooks and polling: webhooks notify once on entity changes but have no automatic retry, so ml-connector also polls using the lastModifiedDateTime query parameter to detect changes since the last sync. Webhook enablement is required at the company level.

How Snowflake works

Snowflake is a cloud data warehouse with no built-in finance objects; all entity tables are user-defined. It exposes SQL query and REST APIs that support key pair authentication (RSA private key plus JWT) or programmatic access tokens. Snowflake uses partition-based pagination and returns HTTP 202 with a statement handle for async queries; JWT tokens expire in one hour and PAT tokens in 1 to 365 days. The warehouse must have AUTO_RESUME enabled or queries fail. Snowflake case-insensitizes unquoted identifiers and offers native change-data-capture via Streams, which are consumed on read. Service accounts require a network policy and whitelisted egress IPs.

What moves between them

Data flows from Visma into Snowflake. ml-connector polls Visma for invoices, purchase orders, GL transactions, vendor records, and GL accounts on a schedule you set -- typically daily or after each business cycle. It compares against the lastModifiedDateTime on each record to detect what changed since the last sync, then upserts those records into corresponding Snowflake tables. Dimension data such as cost centers and GL accounts are synced first so invoice records reference valid accounts. Snowflake serves as the historical archive and query layer; ml-connector does not write changes back into Visma.

How ml-connector handles it

ml-connector stores the Visma OAuth credentials encrypted and refreshes the bearer token when it expires. It polls Visma's invoice, PO, GL transaction, and vendor endpoints using the lastModifiedDateTime filter to pull only records that changed since the last sync, minimizing API calls. Each record carries its Visma internal ID and lastModifiedDateTime so ml-connector can detect downstream updates. For each table in Snowflake, ml-connector upserts the record by primary key (typically the Visma entity ID); this idempotency ensures that if a sync is retried, duplicate rows do not accumulate. ml-connector tracks the last sync datetime per entity type and resumes from that point on the next run. Visma webhooks are one-time delivery with no automatic retry, so ml-connector relies on polling as the primary sync mechanism; webhooks are monitored where enabled but treated as supplementary. Snowflake's JWT tokens expire in one hour, so ml-connector refreshes before expiry. Because Snowflake's SQL API returns HTTP 202 for async queries, ml-connector polls the statement handle until the result is ready, with exponential backoff. Every upsert carries a source timestamp and sync batch ID for full traceability.

A real-world example

A mid-market manufacturing company runs Visma.net ERP for accounting across multiple subsidiaries. The finance team needs to analyze spending patterns, reconcile intercompany invoices, and track GL account balances across the group. Before the integration, they exported invoice and transaction reports from Visma each month and loaded them into Excel for manual reconciliation, a process that took days and was error-prone. With Visma and Snowflake connected, invoices and GL transactions flow automatically into Snowflake each night. The finance team now writes SQL queries to reconcile accounts, spot duplicate invoices, and drill into spending by vendor and cost center. Month-end close is faster because the GL is already in Snowflake and can be queried directly.

What you can do

  • Load invoices, purchase orders, GL transactions, and vendor records from Visma into Snowflake on a daily or custom schedule.
  • Detect changes in Visma using the lastModifiedDateTime field and upsert only modified records into Snowflake, minimizing data duplication.
  • Authenticate Visma with OAuth 2.0 client credentials and Snowflake with key pair or token authentication.
  • Query your financial data directly in Snowflake for reconciliation, audit, and spend analysis without manual export.
  • Track every sync with batch IDs and timestamps so you know exactly when each record arrived and can replay any sync if needed.

Questions

What financial records from Visma flow into Snowflake?
ml-connector syncs invoices, purchase orders, GL transactions, vendor records, GL accounts, and dimensions. All records carry their Visma internal ID and last-modified timestamp. The sync uses the lastModifiedDateTime field to pull only records that changed since the last run, so you always have the current state without duplicates.
How does ml-connector handle Visma webhooks and polling?
Visma webhooks are one-time delivery with no automatic retry, so they are not reliable as a sole sync mechanism. ml-connector polls Visma's APIs on a schedule you set and uses the lastModifiedDateTime filter to detect changes. Webhooks are monitored where enabled at the company level but treated as supplementary to polling.
Why do I need Snowflake network policies and egress IP whitelisting?
Snowflake requires a network policy for service accounts to restrict which IPs can connect. ml-connector's egress IPs must be whitelisted in your policy so the integration can write records into your warehouse. This is a standard security requirement in Snowflake and protects your database from unauthorized access.

Related integrations

Connect Visma and Snowflake

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started