ml-connector
DeltekTaxJar

Deltek and TaxJar integration

Deltek runs project accounting, billing, and finance for professional services and project-based firms. TaxJar is a sales tax compliance platform that calculates rates and stores the finalized order and refund transactions a merchant reports to state authorities. Connecting the two means each client invoice Deltek finalizes is reported to TaxJar for sales tax, credit memos are reported as refunds, and the states where the firm has nexus stay visible inside Deltek. ml-connector handles the very different APIs on each side and keeps the manual tax-report export out of the close. Because TaxJar holds no projects, vendors, or GL accounts, the books stay in Deltek where they belong.

How Deltek works

Deltek Vantagepoint exposes Firms, Contacts, Employees, Projects, AR invoices, AP invoices, journal entries, cash receipts, and GL accounts through a REST JSON API on a tenant-specific deltekfirst.com URL, with an interactive reference per version. It authenticates with OAuth 2.0 using the password grant, which must be explicitly enabled in settings, and the bearer token is refreshed before its expiry. Webhooks exist only as workflow-triggered callbacks configured per hub object, carry no HMAC signature, and authenticate by basic or key fields on the URL, so invoice records are most reliably read by polling. Older Costpoint sites integrate through SOAP web services or file-based preprocessor templates instead.

How TaxJar works

TaxJar exposes a REST JSON API over HTTPS, versioned with an x-api-version header and authenticated by a single API token, with no OAuth, client secret, or account id. It calculates sales tax in real time through POST /taxes and stores finalized orders and refunds under /transactions, each keyed by a unique transaction_id, alongside customers with exemption types and the merchant's nexus regions, which are read-only. TaxJar publishes no webhooks, so order and refund lists and nexus regions are read by polling, with from_date and to_date filters on the transaction lists. Transaction endpoint calls do not count toward the monthly API threshold, and creating a transaction follows an upsert pattern: a POST that returns 422 falls back to a PUT, and a PUT that returns 404 falls back to a POST.

What moves between them

The main flow runs from Deltek into TaxJar. ml-connector reads new and changed AR invoices from Deltek Vantagepoint after they are finalized and posts each as a TaxJar order transaction, carrying the ship-to address, line amounts, shipping, and the sales tax already on the invoice. Credit memos are posted as TaxJar refund transactions that reference the original order. In the other direction, TaxJar nexus regions are pulled on a schedule and synced into Deltek as reference data so billing staff can see where the firm has a tax obligation. TaxJar nexus and rate data are read-only and TaxJar holds no GL accounts or projects, so ml-connector never writes financial entries or master data back from TaxJar into Deltek.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Deltek side it requests a password-grant OAuth 2.0 token against the tenant deltekfirst.com URL per customer and refreshes the bearer token before expiry, and it requires the API user role to have full field visibility so amount fields do not return as zero. On the TaxJar side it sends the static API token on every request and pins a version with the x-api-version header. Because Deltek's webhooks are workflow-only and unsigned and TaxJar publishes none, ml-connector polls Vantagepoint AR invoices and credit memos on a schedule rather than relying on a push, paging through the REST results, and only posts an invoice once it is finalized, since TaxJar reports this data directly to the states. The Deltek invoice number is used as the TaxJar transaction_id, and the upsert pattern handles retries: a POST that returns 422 falls back to a PUT, and a PUT that returns 404 falls back to a POST, so the same invoice is never double-reported. Shipping is always sent, even as zero, because omitting it causes a calculation error, and zero-tax invoices are reported too, because states expect gross sales regardless of tax. Reported transactions are not re-sent through PUT or DELETE once a state has them, and explicit nexus addresses are left off so TaxJar uses the account's own nexus settings. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized digital agency with about two hundred staff runs Deltek Vantagepoint for project billing across retainer and fixed-fee clients in a dozen states. Before the integration, a finance analyst exported a sales register from Vantagepoint each period and hand-keyed the taxable sales and collected tax into TaxJar so the firm's filings would reconcile, lining up amounts by eye and fixing transposition errors at the deadline. With Deltek and TaxJar connected, each finalized AR invoice flows into TaxJar as an order transaction keyed by its invoice number, credit memos post as refunds, and the firm's nexus states stay visible inside Deltek. Filing periods start from TaxJar records that already match the billed sales, and the manual re-keying step is gone.

What you can do

  • Post finalized Deltek Vantagepoint AR invoices to TaxJar as order transactions for sales tax reporting.
  • Report Deltek credit memos as TaxJar refund transactions that reference the original order.
  • Sync TaxJar nexus regions back into Deltek as read-only reference data so billing staff see where tax is owed.
  • Key each TaxJar transaction by the Deltek invoice number and use the upsert pattern so retries never double-report.
  • Bridge Deltek password-grant OAuth to TaxJar's static API token, with a full audit trail and error replay on every record.

Questions

Which direction does data move between Deltek and TaxJar?
The main flow is Deltek into TaxJar. Finalized AR invoices and credit memos move from Deltek to TaxJar as order and refund transactions, while TaxJar nexus regions are pulled back into Deltek as reference data. TaxJar nexus and rate data are read-only and TaxJar holds no GL accounts or projects, so ml-connector never writes financial entries or master data back from TaxJar into Deltek.
Does the sync run in real time or on a schedule?
It runs on a schedule. Deltek's webhooks are workflow-triggered callbacks without an HMAC signature rather than a reliable event stream, and TaxJar publishes no webhooks at all, so both sides are read by polling. ml-connector pulls new and changed Deltek AR invoices and credit memos on the interval you set, and only after an invoice is finalized, since TaxJar reports the data directly to the states.
How does the integration avoid reporting the same invoice twice?
ml-connector uses the Deltek invoice number as the TaxJar transaction_id, which TaxJar treats as a unique key. On a retry it follows TaxJar's upsert pattern: a create that returns 422 because the transaction already exists falls back to an update, and an update that returns 404 falls back to a create. That keeps one TaxJar transaction per Deltek invoice, and reported transactions are not changed once a state has them.

Related integrations

Connect Deltek and TaxJar

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

Get started