Skip to content

Insight Job software and accounts 9 min read

Simpro API: a worked example with n8n

By Renzo Demartini, Chartered Accountant · · Last reviewed

Drafted with AI, reviewed and spot-checked by me.

A schedule starts the run each weekday morning. The Simpro API returns the invoice and its job. A rule finds an empty custom field. Held. A person decides. The workflow changes nothing. A blank field holds the invoice with its reason before Xero sees it.
The build behind this topicA$3,900

Invoice Check

Invoices that do not reach Xero or MYOB, duplicates, and job numbers that do not match.

  • Simpro
  • ServiceM8
  • AroFlo
  • Xero
  • MYOB
See Simpro to Xero invoice checks
Fixed price · AUD · No GSTA person approves

Each weekday morning, someone has to check yesterday’s Simpro invoices before they go to Xero, and hold the ones that are not right. I have built n8n workflows against the Simpro API to do that. This is one, on sample data.

The short answer: a schedule fetches the invoices through the Simpro API. Plain rules pass or hold each one with a reason. A person decides about anything held. Look up custom fields by name on every run, and retry only the errors that are safe to retry.

n8n workflow · Simpro invoice checkDemonstration

Invoice INV-5102, from yesterday. A sample invoice for Job 2102, $2,640.00. It is waiting to go to Xero.

The morning run fetches its job. A schedule calls the invoices changed since the last run, then each job and its custom fields.

Simpro · INV-5102Invoice

Job 2102 (sample)

Changed since the last run

  • Job 2102Customer invoice$2,640.00
Total
$2,640.00

Waiting to go to Xero.

Simpro · Job 2102Custom fields

Job 2102 (sample)

Fetched with the invoice

  • Xero trackingEmpty

Looked up by name on this run.

Plain rules check it. Not AI. Totals, references and fields are better checked by fixed rules.

Checked by a rule The rule

Checked by a rule INV-5102

Xero tracking

The rule: Must be set

INV-5102: Empty

Invoice total

The rule: Not $0.00

INV-5102: $2,640.00

  • Xero tracking not set on Job 2102
  • Total is not zero

A person decides. Fixed in Simpro, recheck, or leave held. The rules only bring it to you.

Held invoices · INV-5102

Held: Xero tracking not set Marked fixed, recheckLeft held

Is INV-5102 fixed in Simpro?

Xero tracking is empty on Job 2102.

Marked fixed. The workflow rechecks it.Left held, with its reason. The person fixed it in Simpro. The workflow only runs the checks again.It waits until someone fixes the field. Nothing is sent on.

Held invoicesINV-5102

Job 2102 (sample)

  • INV-5102Marked fixed, queued for recheck$2,640.00

The workflow never changes the invoice.

Held invoicesINV-5102

Job 2102 (sample)

  • INV-5102Held: Xero tracking not set on Job 2102$2,640.00

It waits with its reason.

End of the day Every weekday morning, yesterday’s Simpro invoices are fetched and checked by plain rules before they go to Xero. Held ones wait for a person, each with its reason. The workflow never changes an invoice.

These are demonstrations. They use sample data and simulated Claude steps. Nothing connects to your accounts, sends a message or changes a record.

The sample workflow at a glance

  1. 01 · TriggerA schedule starts it

    n8n Schedule Weekday

    • RunsEach weekday morning
  2. 02 · Simpro callsFetch what changed

    Simpro INV-5102 Changed

    • InvoiceINV-5102
    • Job2102
    • Custom fieldsFetched
  3. 03 · ChecksRules pass or hold
    • Xero tracking not set
    • Total is not zero
  4. 04 · ApproveA person decides

    INV-5102, $2,640.00Xero tracking not set on Job 2102

  5. 05 · On an errorRetry or tell someone
    • 429: wait, then retry
    • 422: send to a person

At the end of the day Rules do the checking. A person decides what is held.

Everything here uses sample data. No accounts are connected and no real IDs appear.

Step 1 in detail: a schedule or a webhook

n8n’s Schedule Trigger runs a workflow “at fixed intervals and times”.7 Simpro also offers webhooks, so a workflow can be told when a record changes instead of asking. Each webhook message carries an X-Response-Signature header, an SHA1 HMAC of the body made with a secret you choose, so you can check it came from Simpro.3

For a morning check, a schedule is simpler. You know when it runs, and a missed run is easy to spot.

The Simpro API: endpoints and calls

Each Simpro endpoint this example uses and what it is for
Endpoint What it is for
/api/v1.0/companies/0 The company route, for a single-company build. Every path starts here.1
/customerInvoices/ Invoices. If-Modified-Since fetches only what changed.1, 4
/jobs/{jobID} A job. display=all adds its sections and cost centres in one call.1, 4
/setup/customFields/projects/ The job custom field definitions.4
/jobs/{jobID}/customFields/ Each job’s custom field values.4
Cost to Complete reports Job costs, in operations and financial views.4

Keep to 10 requests a second or fewer to one build. Above that, Simpro returns HTTP 429 until the rate drops.2 Keep the API key in an n8n credential, not in the workflow.6

A Simpro listing returns 30 results unless you ask for 250

Results per page · orange: the default

Result-Total and Result-Pages say how many records and pages there are.

Source: Simpro Developer Center, “Advanced usage” (pagination).

Every page, not the first. In n8n’s HTTP Request node, turn on Pagination and set page to {{ $pageCount + 1 }}. Without it, the node quietly fetches page one and stops, and a busy month looks like a quiet one.5, 6

Access, the company route and the first call

Getting a Simpro API key. API access is tied to your own Simpro build. Follow the current steps in Simpro’s Developer Center (see the sources), then keep the key in an n8n credential, not in the workflow itself.6

Every Simpro route starts with a company. For a single-company build the company ID is 0, so routes begin /api/v1.0/companies/0. A multi-company build has more than one, and you choose which in each request.1 Check this first, because the same workflow pointed at the wrong company returns valid data that is simply not yours.

Only what changed. Most Simpro handlers accept an If-Modified-Since header. Each response carries a Date header you can store and send next time.1 The first call is:

GET /api/v1.0/companies/0/customerInvoices/ with If-Modified-Since set to the last run’s Date.4

Pages, columns and job costs in detail

Every page, not the first. A Simpro listing returns 30 results unless you ask for more, up to 250 with pageSize. The response headers Result-Total and Result-Pages tell you how many records and pages there are, and page picks the page.1 In n8n’s HTTP Request node, turn on Pagination and set the mode to “Update a Parameter in Each Request”. Set page to {{ $pageCount + 1 }}, because $pageCount starts at zero and counts the pages fetched so far.5, 6

Only the columns you need. The columns parameter limits what a listing returns. For a job, display=all returns its sections and cost centres in one call, instead of one call per level.1 Simpro’s API also has Cost to Complete job reports, in operations and financial views.4

Step 3: the checks

Three sample invoices, the check that applied and the result
Sample invoice Check Result
INV-5101, Job 2101, $4,180.00 Job exists, order number filled, cost centres present, total agrees Pass
INV-5102, Job 2102, $2,640.00 Custom field “Xero tracking” is empty Held: “Xero tracking not set on Job 2102”
INV-5103, Job 2104, $0.00 Zero total Held: “Zero-value invoice”

Sample data, not a client’s. Rules, not AI: totals, references and matches are better done by fixed rules. A held invoice is not lost and not fixed by the workflow. It waits with its reason.

Lesson 1: custom fields and IDs

Look up the ID by name

Fetch the setup list at the start of each run. Stop with a clear error if the name is missing.

Never assume an ID carries over

Companies, builds and test copies can differ. Look it up each time.

An empty value is a fail

Treat an empty value as a fail, not a pass. INV-5102 is held for exactly that.

In my build, a custom field was renamed in Simpro, and the workflow then read nothing from it. A workflow refers to a field by its ID, but people know it by its name.

How custom fields look in the API

The definitions for job custom fields are at /setup/customFields/projects/, each with an ID, a name, a type and whether it is locked. A job’s values are at /jobs/{jobID}/customFields/, and you update one with a PATCH to /jobs/{jobID}/customFields/{customFieldID}.4

  • Look up the ID by name at the start of each run from the setup list, and stop with a clear error if the name is not found. n8n’s Stop And Error node fails the run on purpose and triggers the error workflow.9
  • Never assume an ID carries across companies, builds or a test copy. Look it up each time.
  • Treat an empty value as a fail, not a pass. The sample’s INV-5102 is held for exactly that.

Lesson 2: errors and retries

Too many requests

Simpro returns HTTP 429 above 10 requests a second to one build. Batch, then retry.

A job someone has open

The update can fail. Wait, try later, then tell the job’s owner.

Bad data

A 422 lists each problem with a path and a value. A retry sends the same bad data again.

Anything else

Set an error workflow in n8n. It runs when an execution fails, so it can email someone.

In my build, the failure I saw most often was an update to a job that someone had open in Simpro at the time. Not every error should be retried.

Each error in detail
  • Too many requests. Simpro returns HTTP 429 to an integration that sends more than 10 requests a second to one build, until the rate drops.2 In n8n, use the HTTP Request node’s Batching option (items per batch and a batch interval), and turn on Retry On Fail with Max Tries and Wait Between Tries.6 Simpro suggests display=all, pagination and its multiple-record routes to cut the number of calls.2
  • A job someone has open. An update to a job that is open in Simpro can fail. Wait, try again later, and if it still fails after a few tries, tell the person who owns the job.
  • Bad data. A 422 response lists each problem with a path (the field) and the value Simpro received.1 Retrying sends the same bad data again. Send it to a person with the path and value.
  • Anything else. In n8n, set an error workflow in the workflow’s settings. It starts with the Error Trigger node and runs when an execution fails, so it can email someone.9, 10 Note that the Error Trigger only runs for automatic executions, not when you test by hand.10
Creating or updating jobs: search before you create

The build also created or updated Simpro jobs. To create one, Simpro needs at least a job Type (Project, Service or Prepaid) and a Site ID.4 Here retries need care: if a create times out after Simpro has saved the job, a blind retry makes a second job. Before creating, search for the job by a reference you control, such as the order number, and update it if it is already there.

A checklist before you build

  1. Company. Which company ID, and is the build single or multi-company?1
  2. Pages. Pagination on every listing, checked against Result-Total.1
  3. Last run. If-Modified-Since stored after each successful run, not before.1
  4. Custom fields. IDs looked up by name each run; a missing field stops the run.4, 9
  5. Errors. Batching and Retry On Fail for 429s; no retry for 422s.1, 2, 6
  6. Creating. A search before every create.
  7. Alerts. An error workflow that tells a named person.9
  8. Approval. A person approves anything held.

Where a person stays in charge

Rules check

Totals, references and fields, the same way every time.

n8n waits

The Wait node pauses the run. Each run gets its own resume link.

You decide

The reviewer chooses fixed or leave held. The workflow changes nothing.

In my build, the job’s project manager was the person who approved. I have built workflows in n8n against the Simpro API. That build pulled jobs, costs and WIP for reporting, created or updated Simpro jobs, and checked Simpro invoices before they reached Xero.

How the person approves in n8n

Held invoices go to a person. n8n’s Wait node can pause a run until it receives a webhook call or a form submission. The run is saved to the database while it waits, and each run gets its own resume URL, $execution.resumeUrl, which you can put in an email.8

In the sample, the reviewer gets one email each morning listing the held invoices and their reasons, with a link to a short form. For each one they choose “fixed in Simpro, recheck” or “leave held”. The workflow then rechecks the ones marked fixed. The person decides. The workflow does not change the invoice.

If you want this kind of workflow built for your Simpro, see how I work as an n8n consultant for Australian and New Zealand businesses. The invoice check above is close to Invoice Check, the Simpro to Xero invoice build, at a fixed A$3,900. The reporting side is the job profitability report for Simpro, at a fixed A$5,900.

If you are not sure which part to automate first, start with a Workflow Audit. It is a 60-minute call, a read-only review of your systems and a written report, with a fixed quote for each of the top 3 things worth automating. The audit is A$990, AUD, no GST charged.11

Questions

How do I get a Simpro API key?

API access is tied to your own Simpro build. Follow the current steps in Simpro’s Developer Center, then keep the key in an n8n credential, not in the workflow itself.6

How many requests can I send to the Simpro API?

Keep to 10 requests a second or fewer to one build. Above that, Simpro returns HTTP 429 until the rate drops.2

Should a workflow retry every failed Simpro call?

No. Batch and retry a 429. Do not retry a 422, because it sends the same bad data again. Send it to a person with the path and the value.1, 2, 6

Does the workflow change a held invoice?

No. A person chooses “fixed in Simpro, recheck” or “leave held”, and the workflow rechecks the ones marked fixed.

Sources

Not sure which to fix first?

Get a free fit check by email and I will say whether it is worth automating. No call needed. The next step is a A$990 workflow audit: the top 3 things worth automating, with a fixed quote for each.

Get a free fit check by email

If you would rather have it built

Each topic has a fixed-price build behind it. The audit tells you which one is worth doing for your business.

Need more than one workflow? For strategy, board work and larger custom builds, I work through renzodemartini.com.

More insights

Start with a free fit check by email

A free fit check by email first. The A$990 Workflow Audit is the next step, credited to your build.

Get a free fit check by email The next step after the fit check: the A$990 Workflow Audit

Get a free fit check by email

Send the form with your software, the workflow, your team size and your timing. I reply by email, usually with a question or two, and tell you whether it's a fit. No call needed. If it is, the next step is the A$990 Workflow Audit.

Sending saves your details in HubSpot so I can reply. No mailing list. No payment is taken. How your enquiry is handled.