← All standards
Open specificationStablePublished November 2026Changelog

The Job Close Build Standard

The job is done and the paperwork is not. This is how the tech’s voice note, photos and parts become the job card in your job system before they leave site, priced from your own price book, checked by the tech, and saved once, so the invoice can go the same day. Written so you can build it yourself.

Used by

  • Service Coordinator
  • Office Manager
  • Operations Manager
  • Accounts Officer

11 min read · Published by AI Pathway

Using Claude? This standard installs as a skill. Guides for ServiceM8, Xero and Simpro.

What this is

An open build standard for the paperwork at the end of a job. The tech says what they did into their phone, like "replaced the tempering valve and two 15 mil elbows, an hour and a half", adds photos, and the job card in ServiceM8 or Simpro is filled in before they drive off.

The core rule

Every part on the card comes from your own price book, at your price. Anything it cannot match, and any extra work the quote did not cover, is set aside for the office instead of guessed. The tech checks the card before it is saved.

What it does not do

It never makes up a job, never prices a variation, and never sends an invoice. It marks the job complete only once the job system has saved the card, which is the signal Invoice Out waits for.

The hard part

Saving the card into a job system you do not own from a phone in a roof space, where the first try times out and the second must not make a duplicate. And a yes that only the tech on the job can give.

Mia finishes at 2pm. She replaced a leaking tempering valve and two elbows, swapped an element she had in the van, and spent an hour and a half. The job card says “done”. Everything else is in her head and her camera roll. On Friday the office asks what went in; she remembers the valve and the hours, not the element. Invoice Out could not raise the invoice from an empty card, so it waited four days and went out short, and the next tech to visit that house starts with no record of what was done.

The close, as a record

  1. From site

    The tech's voice note or notes, photos and parts, sent with the job number. Kept word for word.

    • transcript
    • photos
    • parts spoken

    priced from

  2. Your price book

    One catalogue line per part, at your price when the card is saved. No match, two matches or extra work: parked.

    • catalogue_code
    • unit_price
    • parked

    confirmed by

  3. The tech

    One message with the draft. Only the tech on the job can say yes.

    • draft
    • yes

    written to

  4. Your job system

    ServiceM8, Simpro, AroFlo or Fergus. One card per intent id, ids back, then complete.

    • intent_id
    • external_ids
    • complete

    read by

Read it downward. What the tech sent is kept; the price book is the only source of a price; the tech says yes; the job system sends its ids back before anything is marked complete. The arrows are what this standard checks.

One close, through the gates

  1. The tech sends what they did from site: a voice note or typed notes, photos, and the parts they used.
  2. The job is read from the job system by its id, and the sender checked against the tech assigned to it. No job, no close.
  3. What the tech sent is kept word for word before anything is taken from it.
  4. Each part is priced from the business's own price book. A part the book does not hold, one that matches two lines, and work the quote did not cover are parked for a person.
  5. Does the tech say yes to the draft, from their own phone? If not, nothing is written, and their supervisor is told after two hours.
  6. If yes, the card, lines and photos are written once, under one intent id made from the tenant, the job and the capture.
  7. Did the job system send its ids back? If so, the job is marked complete and every parked item goes to the exceptions queue with an owner.
  8. If not, the write is raised as failed and tried again under the same id, so it lands once.
The filled diamond is the tech: nothing is written until they say yes. The second diamond is the job system’s answer: no ids, no completion, and the retry goes under the same id so it lands once.

Take the spec to Claude, ChatGPT or Copilot. The sentence to paste is one click away.

1. What this standard covers

A trade or field service business whose techs finish jobs on site and whose invoices are raised from the job card: plumbing, electrical, air conditioning, fire, security, appliance repair. The standard starts when the tech says the work is done and ends when the job is marked complete in the job system, with a card that has the work done, the parts as price book lines, the labour, the photos and, where the business wants it, the customer’s sign-off.

It sits on the cash path between the Dispatch Board, which put the right tech at the house, and Invoice Out, which bills the completed job. It carries Cash Seam’s job id and adds none of its own. The field service roadmap explains why this handover was built first.

Job systemWhat the write touches
ServiceM8Job notes, job materials from the materials list, attachments, and the job status set to Completed. Who is on the job is read from its scheduled activities.
SimproJob notes, cost centre items from the catalogue, attachments, and the job stage. Who is on the job is read from the schedule.
AroFloTask notes, materials from the inventory, documents and the task status, through its API.
FergusJob notes, price book items, attachments and time entries, through its public API.
TradifyCannot meet it. Tradify has no public write API, so there is no sanctioned route that writes a card, a line or a photo into a Tradify job.

Out of scope. Raising, approving or sending the invoice, which is Invoice Out’s behind its own release. Ordering the parts before the job, which is Material Order’s. Pricing a variation and getting it signed, which stays with a person. Timesheets: labour on the card is what the customer is charged, not what the tech is paid, and Timesheet Check holds the second.

What cannot meet it. A job system with no write API. Tradify is the common one: a business on Tradify can run checks 1 to 6 on a sheet, and a person types the confirmed card in.

2. The close, in the shape your developer needs

Two records. What arrived from site, kept as it came; and the card it became, with where it was written and what came back.

For your developer. Show the fields for your developer
close_request
  job_external_id   string        # read from the job system, never minted
  tech_id           string        # the assigned tech, read from the job
  captured_at       datetime
  inputs
    voice_note_uri?   string
    transcript?       string      # verbatim, stored before extraction
    notes?            string
    photos            [uri]
    parts_used        [{ spoken: string, qty: number }]

close_result
  work_done         string        # drafted from the transcript; the tech confirms
  lines
    - kind            part | labour | callout
      catalogue_code? string      # resolved from the price book only
      qty             number
      unit_price?     number      # read_pricebook at close time, never typed
      source          pricebook | parked
  parked            [{ spoken, reason: not_in_book | ambiguous | variation }]
  photos_attached   [external_id]
  signoff?          { name, at }
  confirmed         { by: tech_id, at, draft_id }
  written           { system: servicem8 | simpro | aroflo | fergus | native,
                      intent_id,    # close:<tenant>:<job>:<capture>
                      external_ids: [string] }
  status            closed | closed_with_parked | not_written

A line with no catalogue code, a confirmation from anyone but the assigned tech, and a completion with no external ids are the three defects this schema exists to make visible.

3. The checks, in order

The order is the order a close runs, and each step guards the next. The job is read before anything is kept, so a wrong job number never reaches the price book. What was said is kept before it is priced, so the card can always be set beside the words. The price book is read again at the write, not at the draft, because a draft can sit for an hour while someone fixes a price. And completion is last, because it is the only signal Invoice Out acts on: a job marked complete with no card behind it is an invoice for nothing.

  1. The job exists and this tech is on it. A close starts from the job id the job system issued, read back from the job system before anything else. No job, no close: a close is never the thing that creates a job. A capture from a tech who is not assigned to that job goes to the office, not onto the card.
  2. What the tech said is stored before anything is taken from it. The transcript, the notes, the photos and the parts as spoken are kept word for word as evidence first. The draft is worked out from the stored copy, so what the tech said can always be set beside what was written.
  3. Every part is a price book line or it is parked. Each part the tech names resolves to exactly one catalogue line in the business's own price book, at the price the book holds when the card is written. A part that matches nothing is parked as not_in_book; one that matches more than one line is parked as ambiguous. No price is ever estimated, averaged or remembered.
  4. A variation is never priced at close. On a quoted job, a part or line the quote did not cover is parked as a variation and goes to the person who prices variations. It is not put on the card at any price, even one the book holds. Invoice Out bills it only once the customer has signed for it.
  5. The tech confirms the draft before it is written. The draft goes to the tech in one message: the work done, the lines, and what was parked. Only a yes from the assigned tech's own number, naming that draft, lets it be written. A yes from the office, or a draft the model marked confirmed itself, is not the tech's confirmation.
  6. A draft nobody confirms goes to the tech's supervisor. If the tech has not confirmed within the written window, two hours by default, the draft is raised as not_confirmed to the tech's supervisor, once. It is not written and the job is not marked complete while it waits.
  7. One write, with the job system's ids back. The card, its lines and its photos are written once, with the intent id close:<tenant>:<job>:<capture>. A retry carries the same intent id and lands once. A write that returns no ids is treated as not written and raised as write_failed to the office manager.
  8. The job is marked complete only after the write returns ids. Completion is the last step and the only trigger Invoice Out accepts, so it happens only once the write has come back with the job system's ids. A parked item does not hold completion: it travels to Invoice Out, which parks the invoice.
  9. Every parked item goes to the exceptions queue with an owner. Each part not in the book, ambiguous match and variation is raised once to the Exception Desk queue with the job id, the tech's words exactly and a named owner: the office manager for a part, the variation pricer for a variation. Nothing parked is left only in a message.
  10. The close is on the record, by job. For each job: what the tech sent, what was taken from it, who confirmed it and when, and what the write returned, ids or the reason it failed. The history of one close can be read in one place.
  11. It survives the builder. Someone other than the builder can explain what it does, and it runs on an account the business owns.
  12. The pass test passes. On a real job in the business's own ServiceM8 or Simpro: a thirty-second voice note naming one part in the price book and one that is not, and two photos. Within five minutes the card shows the work done, the known part at the book price, both photos and the job complete; the unknown part is on the exceptions list, not the card. Sent again, nothing duplicates.

4. One close, from the roof space to complete

Mia’s job again, J100, a do-and-charge call-out with no quote, run to this standard.

  1. 2:00pm. Sent from site. Mia records thirty seconds: “Replaced the leaking tempering valve under the house and two 15 mil elbows. Also swapped the Rheem element, three point six kilowatt. About an hour and a half all up.” Two photos, job J100.
  2. 2:00pm. Checked and kept. J100 is in the job system and Mia is on it. The note, the transcript and both photos are stored as they came.
  3. 2:01pm. Priced, and one thing parked. “Tempering valve” is one line in the book, TMV15. “15 mil elbow” is CU15-ELB, two of them. An hour and a half is the labour line. “Rheem element 3.6kW” is not in the book, so it is parked as not_in_book. Nothing is guessed.
  4. 2:01pm. One message to Mia. The work done, the three lines, and “parked for the office: Rheem element 3.6kW”. She replies YES with the draft number.
  5. 2:03pm. Written, on the second try. The first write times out in the roof space. It is treated as not written and raised. The retry goes under the same id, close:harbour:J100:C1, and the job system answers with the ids of the card it already holds. One card, three lines, two photos.
  6. 2:03pm. Complete, and the element to the office. The job is marked complete. The element goes to the exceptions queue with Mia’s words and the office manager’s name. Invoice Out sees the completed job and parks the invoice until the element is priced.

5. What gets parked, and whose it is

A part is parked rather than priced when the book does not hold it, when the tech’s words match two lines (“flexi hose” when the book has a 300mm and a 450mm), or when the job was quoted and the part is not on the quote. The last one is a variation even if the book has a price for it, because what the customer agreed to pay for is the quote, and anything beyond it needs their signature first. Each parked item goes to one exceptions queue with the job id, the tech’s words and an owner. The Exception Desk standard, next on the roadmap, is the queue every standard will share.

ExceptionOwnerBy when
Job number not found, or a tech not on the jobOffice managerSame day
Part not in the price book, or matches two linesOffice managerBefore invoice day
Variation: work the quote did not coverWhoever prices variationsBefore invoice day
Write failed: no ids backOffice managerSame day
Tech did not confirm within two hoursThe tech's supervisorSame day

A parked item never holds up completion. The job is complete when the work is; the parked part travels to Invoice Out, which parks the invoice until a person prices it. That keeps the two questions apart: was the job done, and what do we charge for it.

6. Writing it once

This is the step not to hand-roll. Drafting the work-done text is the easy part: a coding agent does it in an afternoon. The hard part is an authenticated write of the card, its lines and its photos into a job system you do not own, priced only from the business’s own book, that holds across retries from a phone on a bad signal.

  • One id, every try: close:<tenant>:<job>:<capture>, made from things that do not change between tries. Never a timestamp or a random number: those make a new card on every retry.
  • No ids, not written: a write that times out may have landed. It is treated as not written, raised as write_failed, and tried again under the same id. The job system's answer to the retry is the truth.
  • Complete last: the status change is a separate, final step, made only after ids come back. A failed write never leaves a completed job behind it.
  • Lines need a code: a line with no catalogue code is refused before it is sent. The job system's invoicing, and Invoice Out, both price by code.

7. What stays with a person

  • Confirming the draft: the tech on the job, from their own phone.
  • Pricing every part parked as not in the book or matching two lines.
  • Pricing every variation, and getting the customer to sign for it.
  • Chasing a tech who has not confirmed, as their supervisor.
  • Fixing a write that failed, and keeping the price book's aliases in step with what the techs say.
  • Sending the invoice, through Invoice Out's release.

8. Run it your way

The same checks and the same pass test hold whichever way you run it, and the job id is the job system’s in every one. Mix them if you like: a sheet for the drafts and Office Voice for the write, once it ships. What matters is that one surface owns each step for your business, so two of them never write the same card (run a standard anywhere sets out the rules).

WayHow it runsReady today?
Office Voice, done for youThe tech texts the job number, a note and photos to your Office Voice number from site, confirms with one reply, and Office Voice writes the card into ServiceM8 or Simpro once and marks the job complete.Coming. Office Voice reads the job and your price book today; the write (close_job) and closing by text are being built and are not live.
Your own botThe tech sends the note to Grok Bot or Claude with the job number. The bot reads the job and the price book on one Office Voice key, drafts, and asks the tech to confirm.The draft and the confirm, yes. The write waits on close_job (section 9).
Google WorkspaceA Google Form on the tech’s phone feeds a sheet. Apps Script checks the job and the tech, prices from a PriceBook tab, emails the draft, takes the tech’s confirm and writes the card to the sheet’s own Jobs and JobLines tabs, the columns the Invoice Out sheet reads.Template built; its copy link is published here once the master is shared. With ServiceM8 or Simpro connected, it checks the job there and holds a confirmed card for a person to copy until close_job ships.
Microsoft 365A Power Apps form, SharePoint lists for what was sent, the price book, the closes and the exceptions, and Power Automate flows that draft, wait for the tech, write once over HTTP and only then mark complete.Yes: the build plan.
Your own codeThis page: the checks, the stub world and the pass test. Hand it to a coding agent with the button at the top.Yes. 10 of the 12 checks run on your own machine against the stub.

9. With a Grok Bot or Claude, without it guessing a price

Think of the bot as the apprentice in the passenger seat who fills in the job sheet while you drive: they write down what you said, look each part up in the price list, read it back, and only file it when you nod. The bot never prices from memory, never decides a part is close enough, and never saves a card you did not confirm. Your logins stay yours: the bot holds a key you can delete.

What each piece of access is for.

  • Read the book, on an Office Voice key. Lets the bot read the job by its number (read_job) and your price list in Xero (read_pricebook). It comes with Connect at $19a month per business. That is enough for checks 1 to 6: the job, the price, the parking and the tech’s yes.
  • The write, when close_job ships. Office Voice’s close_job will write the card, lines and photos into ServiceM8 or Simpro once per intent id and mark the job complete. It is being built and is not live. Until it is, the bot hands the confirmed card to the office to type in.
  • Not ServiceM8’s own connector, for the write. It can add a note and change a job’s status, but its published list of actions has no job materials or attachments and nothing carries an intent id, so a retry could double the note and the job could be marked complete with no lines behind it. That fails checks 7 and 8.
  1. Under Keys (office-voice.com/app/keys), create a key with Read the book only, and add it to the bot as the Grok Bot and Xero guide sets out. The same key works in Claude.
  2. Tell the bot, in its standing instructions: read the job first and stop if the sender is not its tech; keep the tech’s words as they came; price only from read_pricebook, one match or park it; park anything not on the quote; send the draft back and wait for the tech’s yes.
  3. Have the bot put every parked item on one list with the job number, the tech’s words and who owns it.
  4. Run the checklist in section 12 against a real job.

Why not let the bot price it? Grok Bot and Claude will both happily tell you what a tempering valve costs. That number is the model’s, not yours, and it will be wrong in the way that costs you money: plausible. The book is the only price.

Facts that can change, and when we checked them

Checked as at 1 November 2026

Office Voice reads a job by its id from ServiceM8 or Simpro (read_job) and the price list from Xero (read_pricebook) on a key with Read the book. Its close_job tool, which writes the job notes, lines and attachments and marks the job complete once per intent id, and closing a job by text or picture message from a tech’s registered number, are being built and are not live. Until they are, there is no hosted write and the provider block below says so.

ServiceM8’s own connector, per its support article read on 3 October 2026, lists reading jobs, activities and notes, adding notes and changing job status. It does not list job materials or attachments.

Tradify has no public or partner API, confirmed in writing by their support on 10 April 2026.

Check these against the primary instrument before you rely on them, and store the date you checked beside the value rather than hard-coding it. This standard tells you the shape and where to look. It is not legal advice and it does not tell you that anything complies.

11. What your developer builds, and the step that needs care

The step not to hand-roll is the write: one authenticated, idempotent write of the card, lines and photos into a job system you do not own, priced only from the business's own book. Office Voice's close_job will hold it and is not live yet. Everything before it is yours, and it is the free part.

For your developer. Show the setup for your developer
provider:
  stub:       local.mock_job_close
  production: none                       # scoped build, not a product

stub                                 # local.mock_job_close
  - a job store with assigned techs, a price book,
    captures, replies, and a job system that keeps
    one card per intent id
  - proves checks 1 to 10 in shape

production                           # coming: Office Voice close_job
  - read_job, read_pricebook         # live today
  - close_job(job_external_id, work_done, lines[],
              photos[], intent_id)   # CLOSE-1, not live
  - close by SMS or MMS from site    # CLOSE-2, not live

stays local                          # yours, and the standard
  - the draft and the tech's confirmation
  - the parking rules and the owners
  - the record of every close, by job

Anyone selling you an AI that fills in job cards should be able to answer one question: what happens to the second card when the first save times out?

The pass test. On a real job in your own ServiceM8 or Simpro, not a sample. The tech records a thirty-second voice note naming one part that is in your price book and one that is not, and attaches two photos. Within five minutes of their yes, the job card shows the work done, the known part as a catalogue line at the book price, both photos, and the job marked complete; the unknown part is on the exceptions list, not on the card. Send the same capture again: nothing duplicates. A stub cannot pass this, because the line, the price and the photos have to appear in your own job system with its own ids, after a phone on site sent them.

12. A checklist to hold any build or supplier to

Hold a DIY build or a vendor to this. If a box is empty, it is not in production.

  • 1. The job exists and this tech is on it. A close starts from the job id the job system issued, read back from the job system before anything else. No job, no close: a close is never the thing that creates a job. A capture from a tech who is not assigned to that job goes to the office, not onto the card.
  • 2. What the tech said is stored before anything is taken from it. The transcript, the notes, the photos and the parts as spoken are kept word for word as evidence first. The draft is worked out from the stored copy, so what the tech said can always be set beside what was written.
  • 3. Every part is a price book line or it is parked. Each part the tech names resolves to exactly one catalogue line in the business's own price book, at the price the book holds when the card is written. A part that matches nothing is parked as not_in_book; one that matches more than one line is parked as ambiguous. No price is ever estimated, averaged or remembered.
  • 4. A variation is never priced at close. On a quoted job, a part or line the quote did not cover is parked as a variation and goes to the person who prices variations. It is not put on the card at any price, even one the book holds. Invoice Out bills it only once the customer has signed for it.
  • 5. The tech confirms the draft before it is written. The draft goes to the tech in one message: the work done, the lines, and what was parked. Only a yes from the assigned tech's own number, naming that draft, lets it be written. A yes from the office, or a draft the model marked confirmed itself, is not the tech's confirmation.
  • 6. A draft nobody confirms goes to the tech's supervisor. If the tech has not confirmed within the written window, two hours by default, the draft is raised as not_confirmed to the tech's supervisor, once. It is not written and the job is not marked complete while it waits.
  • 7. One write, with the job system's ids back. The card, its lines and its photos are written once, with the intent id close:<tenant>:<job>:<capture>. A retry carries the same intent id and lands once. A write that returns no ids is treated as not written and raised as write_failed to the office manager.
  • 8. The job is marked complete only after the write returns ids. Completion is the last step and the only trigger Invoice Out accepts, so it happens only once the write has come back with the job system's ids. A parked item does not hold completion: it travels to Invoice Out, which parks the invoice.
  • 9. Every parked item goes to the exceptions queue with an owner. Each part not in the book, ambiguous match and variation is raised once to the Exception Desk queue with the job id, the tech's words exactly and a named owner: the office manager for a part, the variation pricer for a variation. Nothing parked is left only in a message.
  • 10. The close is on the record, by job. For each job: what the tech sent, what was taken from it, who confirmed it and when, and what the write returned, ids or the reason it failed. The history of one close can be read in one place.
  • 11. It survives the builder. Someone other than the builder can explain what it does, and it runs on an account the business owns.
  • 12. The pass test passes. On a real job in the business's own ServiceM8 or Simpro: a thirty-second voice note naming one part in the price book and one that is not, and two photos. Within five minutes the card shows the work done, the known part at the book price, both photos and the job complete; the unknown part is on the exceptions list, not the card. Sent again, nothing duplicates.
  1. 1

    Hold the build to the checklist

    The checks in this standard are what a working build looks like. Implement it yourself, hand it to a developer, or hand the page to an AI with the button below.

  2. 2

    Do not hand-roll

    There is no product for this step. Highest option: none. Checklist plus a build.

  3. 3

    If you are stuck

    Exceptions, three systems, a team that will not maintain a Zap, or an owner who wants it done. We implement when it has to survive the business.

Related reading

Want the whole thing by email?

This paper, plus the rest of the library. One click to stop them.

Run these checks yourself

Every check on this page is published as structured data. This prints them with what to inject, what to assert, and which ones can be proved on your own machine rather than against the live thing.

npx @aipathway/conformance show job-close-build-standard

Free and open source, CC BY 4.0. The checks are fetched from this page rather than bundled, so a correction here reaches you without a release, and you cannot end up conformant against a stale copy. The raw JSON is there if you would rather wire it into your own harness, and the package shows how to drive your build through the ports.

Built it, and one check failed?

Tell us which one. You have already read the standard and tried it, so the answer is a fixed price to finish that step, not a call to work out what you need.