Skip to content
sandadocs

Stream a ServiceM8 account

Land a ServiceM8 account's jobs, quotes, invoice lines, payments, bookings, clients, staff time and forms in your warehouse, read with an API key, with nothing to approve.

Standard · EnterpriseFor owners and admins

A ServiceM8 stream lands a ServiceM8 account's jobs and quotes, the lines and payments behind each invoice, the schedule, clients, staff time, forms and assets in your warehouse, as often as every 15 minutes. After the first run, each run reads only what changed in ServiceM8 since the last.

ServiceM8 is a published source, like Postgres and Bite: sanda wrote the code that reads it and runs it as its own, so there is no connector for sam to write or for anyone to approve. You type an API key the account's Business Owner makes in ServiceM8, choose what to read, and set a schedule.

Before you start

  • The Business Owner makes the key. In ServiceM8, only the Business Owner can make an API key. It is under Settings · API Keys (the button may read API Access). Make an API key there, not a Plugin API key (one that starts smk-): those are ServiceM8's older kind, and its API doesn't accept them. sanda only reads, so Read Only access is enough. Give the key a name such as sanda, so you can tell it apart from other keys later.
  • One account at a time. Each key reads one ServiceM8 account. A business with two accounts connects each one and makes a stream for each.
  • Only owners and admins connect a key and make a stream on it in sanda, because sanda reads the account on the whole workspace's behalf.

Connect an account

  1. Open Pull. Go to Data · Streams, open the Pull tab and press the ServiceM8 card under Choose a source. The new pull's editor opens on Connect a ServiceM8 account when none is connected yet. Once an account is connected, Connect an account beside ServiceM8 under Connected adds another.
  2. Paste the API key into API key. Name is optional: leave it empty and sanda names the account after the business.
  3. Press Check and connect. sanda asks ServiceM8 which account the key belongs to before it keeps the key. The account is listed under ServiceM8 in Connected, named after the business (such as ServiceM8 · Acme Plumbing), with the last characters of the key. If you connected it from a new pull's editor, the account is chosen there.

sanda keeps the key encrypted, only ever sends it to ServiceM8, and never shows it again, in the console or to sam. Type it again replaces the key (after you make a new one in ServiceM8, say), and every stream on the account carries on. A key for a different ServiceM8 account is refused there, because a stream keeps the account it reads. Disconnect forgets the key in sanda. To stop it working in ServiceM8 as well, revoke it under Settings · API Keys.

Make a stream

  1. Start it. Press the ServiceM8 card under Choose a source, or New pull and then ServiceM8.
  2. Choose when it runs. When it runs comes first. A ServiceM8 stream runs at most every 15 minutes, so the faster choices are greyed out. Within your trading hours is a good start. See when a stream runs.
  3. Name it. Its tables are named after it: a stream called sm8 lands jobs in raw.sm8__jobs.
  4. Choose the account, and, if your workspace has more than one warehouse, the warehouse it lands in. Both are chosen once.
  5. Choose what it reads. Everything is ticked. Untick what you don't need: each one you leave out saves requests from the account's daily allowance.
  6. Press Save pull. Saving reads nothing yet: press Run now, or wait for its schedule.

What it reads

Tick Lands in Each run reads
Jobs raw.<stream>__jobs The jobs that changed since the last run
Job materials raw.<stream>__job_materials The job materials that changed since the last run
Job material bundles raw.<stream>__job_material_bundles The job material bundles that changed since the last run
Job activities raw.<stream>__job_activities The job activities that changed since the last run
Job payments raw.<stream>__job_payments The job payments that changed since the last run
Job allocations raw.<stream>__job_allocations The job allocations that changed since the last run
Job contacts raw.<stream>__job_contacts The job contacts that changed since the last run
Job queues raw.<stream>__job_queues The job queues that changed since the last run
Clients raw.<stream>__clients The clients that changed since the last run
Client contacts raw.<stream>__client_contacts The client contacts that changed since the last run
Staff raw.<stream>__staff The staff that changed since the last run
Staff clock events raw.<stream>__staff_time_events The staff clock events that changed since the last run
Materials and labour rates raw.<stream>__materials The materials and labour rates that changed since the last run
Job categories raw.<stream>__categories The job categories that changed since the last run
Badges raw.<stream>__badges The badges that changed since the last run
Forms raw.<stream>__forms The forms that changed since the last run
Form questions raw.<stream>__form_fields The form questions that changed since the last run
Form responses raw.<stream>__form_responses The form responses that changed since the last run
Assets raw.<stream>__assets The assets that changed since the last run
Customer feedback raw.<stream>__feedback The customer feedback that changed since the last run
Job admin time raw.<stream>__job_admin_activities The last 60 days again, once a day, so late changes land
Tax rates raw.<stream>__tax_rates The whole list, every run
Account raw.<stream>__account The whole list, every run

Jobs, job contacts, clients, client contacts and staff hold people's names, phone numbers, email addresses or home addresses, and the editor says so under each. Untick them if your warehouse shouldn't hold them.

What changed since the last run

The first run reads each list whole. After that, a run asks ServiceM8 for every record changed after a date: the date of the newest change the last run saw, less one day. So each run reads a day or two of changes again. A record read twice is still one row, and one that hasn't changed costs nothing in your warehouse. Reading a little again means a change is never missed, whatever ServiceM8's clock did, including the hour that repeats when daylight saving ends.

Jobs, quotes and invoices

A quote is a job whose status is Quote, and a work order one whose status is Work Order: ServiceM8 keeps them in one list, so they land in one table. ServiceM8 has no separate invoice record either: a job's invoice is its invoice_date, invoice_sent and total_invoice_amount, with its lines (labour included) in job materials and the money received in job payments. Each line and payment names its job in job_uuid.

The schedule and staff time

Job activities are both the bookings on the schedule and the time staff recorded on a job, told apart by activity_was_scheduled and activity_was_recorded. Job allocations are jobs given to someone without a booked time. Staff clock events are each clock on, clock off and lunch break.

Job admin time

ServiceM8 records no time of change for office time logged against a job, so a run can't ask for what changed. Instead, the first run reads all of it, and after that, once a day, the stream reads the last 60 days again. An entry corrected inside those days lands corrected, and one removed is marked _deleted_at. An entry older than that keeps what it last said.

Tax rates and the account

Both are a handful of rows, read whole every run. The account is the ServiceM8 account itself: its timezone_name is the time zone ServiceM8's times are in (with one exception: a form response's timestamp is UTC), and its currency the currency of every amount.

Left out

ServiceM8 also offers these, which a ServiceM8 stream doesn't read yet: job notes, tasks, checklists and job templates, attachments (such as the quote and invoice PDFs), suppliers, locations, allocation windows and security roles.

A member of staff's last known position (lat, lng and geo_timestamp) and the job they are travelling to (navigating_to_job_uuid and its times) never land.

What lands in your warehouse

Every field becomes a column, and the whole record is kept in _record, as for every pull. A few things are worth knowing when you model them:

  • Times are the account's own time, with no time zone. ServiceM8 writes its times as the wall-clock time where the account is, so these columns are timestamps without a zone. The account table's timezone_name says which zone: in a view, edit_date at time zone 'Australia/Sydney' gives the instant. A time ServiceM8 never set, which it sends as 0000-00-00 00:00:00, is empty in its column and kept in _record.
  • A form response's timestamp is UTC. When a form was completed is the one time ServiceM8 writes in UTC, so that column is a timestamp with a time zone: it already holds the instant. In a view, "timestamp" at time zone 'Australia/Sydney' gives the time on the account's clock, to set beside its other times. A form response's edit_date is the account's own time, like every other table's.
  • Amounts are numbers. ServiceM8 sends money and quantities as text. They land as numbers in total_invoice_amount on jobs, in quantity, price, cost, displayed_amount and displayed_cost on job materials, in price and cost on materials, in amount on job payments and in amount (a percentage) on tax rates. A job material's price and cost are without tax, and its displayed_amount_is_tax_inclusive says whether displayed_amount includes it.
  • Deleted records stay, with active 0. Deleting something in ServiceM8 marks it inactive rather than removing it, and ServiceM8 still lists it, so its row keeps coming in with active 0. Leave those out in a view where you count jobs or revenue.
  • Ids are ServiceM8's uuids. Every table is keyed by uuid, and a column ending in _uuid names a row of another table: company_uuid a client, staff_uuid a member of staff, category_uuid a job category.
  • Badges are uuids. A job's or client's badges holds the uuids of its badges, each a row of badges.

Change a stream

Edit, on the stream's page, changes everything but the account and the warehouse. Something you take off keeps its table, with what it landed. Load everything again on the stream's page reads every list whole on the next run. A large account's first read, or a load from the start, can take several runs, each carrying on from the last.

Remove ServiceM8 data

ServiceM8's terms ask that its data be deleted when you stop using it, or when someone asks. To remove an account's data from sanda:

  1. Delete each pull on the account: Delete pull, at the foot of the stream's page. Its tables stay in your warehouse until you remove them.
  2. Disconnect the account under ServiceM8 in Connected, and revoke the key in ServiceM8 under Settings · API Keys.
  3. Drop what you built from it. Remove the views and modelled tables in Modelling that read the stream's tables.
  4. Ask sanda support to drop the stream's tables (raw.<stream>__jobs and the rest), naming the stream. Landing tables can't be dropped from the console.

When something goes wrong

What you see What to do
ServiceM8 refused that API key (401). Check it and type it again. The key was mistyped, was revoked in ServiceM8, or is a Plugin API key (one that starts smk-), which ServiceM8's API doesn't accept. Copy it again from Settings · API Keys, or make a new API key there
ServiceM8 didn't say which account that API key is for, so nothing was saved. ServiceM8's answer named no account. Try again later
That account is already connected as ServiceM8 · … The account is in Connected already. Press Type it again on that row to replace its key
That API key is for …, not … A stream keeps the account it reads. Connect the other account as its own, and make a stream on it
ServiceM8 stopped accepting the API key for … The key was revoked or changed in ServiceM8. The stream waits, rather than failing again and again. Make a new key and press Type it again beside the account under Connected
ServiceM8's daily allowance for this account is spent, so the run stopped. The next run after ServiceM8 resets it carries on. Nothing to do: the run kept what it landed. sanda asks ServiceM8 again 60 minutes later, with one request, and the first run after ServiceM8 resets the allowance carries on. If it happens often, run the stream less often or read less
… sanda waits until … (UTC) before asking ServiceM8 again, so nothing was read. A run that started while the allowance rests. Nothing to do: it asked ServiceM8 nothing, and isn't a failure
ServiceM8 says this account isn't in good standing and has invoices to pay, so it answers nothing until they are paid. The Business Owner settles the account's ServiceM8 invoices. The next run after that carries on
ServiceM8 didn't let the API key read …, so this run left it out. Take that list off the stream with Edit, or ask the Business Owner for a key that can read it. The rest of the run carried on
A ServiceM8 stream runs at most every 15 minutes … Choose a slower schedule
ServiceM8 asked sanda to slow down, or didn't answer Nothing to do: the run waits as ServiceM8 asks, then carries on from the last page that landed

A failed run counts toward the stream pausing itself, as any stream's does. A run that stopped for the daily allowance, or was skipped while it rests, doesn't. See runs.

Limits

  • ServiceM8 allows each account 180 requests a minute and 20,000 a day. A run makes at most 2 requests a second, which keeps it inside the minute's allowance, and a stream runs at most every 15 minutes, which keeps its everyday runs well inside the day's. A large account's first read, or Load everything again, can spend more of the day.
  • Each request returns up to 1,000 records: ServiceM8 sets the page size.
  • One run lands at most 20,000,000 records, so a large account's first read is several runs.

A ServiceM8 stream is billed like any pull: a charge for each run that does its work, and the rows it lands past what your edition includes. See what streams cost.

Something unclear or out of date? Tell us, and we will fix the page.