❝

❝ A commercial general contractor in Phoenix runs 85 direct staff and 38 regular subcontractors, with around 420 people badged onto its sites in a year and roughly 1,900 certificate records between them. The records live in a spreadsheet maintained by one safety coordinator, who spends about 14 hours a week on it. The spreadsheet showed 7 expired certificates. An audit after a state inspection found 61, because many cards, forklift evaluations among them, print the date someone was assessed rather than the date it expires, and 340 records had no expiry date to compare against. The design below reads every card as it arrives, calculates expiry from a rules table, chases renewals at 60, 30 and 7 days, and checks tomorrow's site roster at 05:30. The agent costs about $210 a month.

Hector has driven telehandlers for nine years.

He is good at it, which is why the superintendent put him on the telehandler for the steel deliveries on a medical office building in Chandler, and why nobody gave the matter a second thought. His operator evaluation was in the safety file. Teresa, the safety coordinator, had logged it herself in March 2023.

Federal rules require a powered industrial truck operator, telehandler drivers included, to be re-evaluated at least once every three years. Hector's evaluation lapsed on 14 March 2026. He drove the telehandler every working day after that until 19 August, when a load swung into a scaffold during a lift. Nobody was hurt. The scaffolding contractor complained anyway, and an inspector from the state safety programme arrived two days later and asked to see his paperwork.

The spreadsheet said he was current. The spreadsheet had said so all along.

The business

A commercial general contractor in the Phoenix metro area: tilt-up warehouses, medical office buildings, tenant improvement work. Around $64M in annual revenue, 85 direct employees and 38 subcontractor firms it uses regularly. In a typical year around 420 different people are badged onto its sites.

Between them those people hold roughly 1,900 certificates the contractor needs to know about. OSHA 30 cards for superintendents and foremen, which the contractor's healthcare clients require refreshed every five years. Forklift and telehandler evaluations. Aerial lift training. Crane operator certifications. First aid and CPR. Fall protection competent person. Confined space. And for the subcontractor firms themselves, certificates of insurance that renew every year.

Arizona runs its own occupational safety programme, ADOSH, as an OSHA-approved state plan, and its standards and penalties track the federal ones. Procore holds the project directory and the daily logs. The certificates live in a shared inbox, a folder of phone photos, and a spreadsheet with 1,900 rows.

The contractor, Hector and Teresa are a composite, built from the patterns we see in commercial contractors of this size, and the figures attached to them are design projections. The regulations, penalties and validity periods are real, and linked to their sources.

What is actually going wrong

Teresa logged every card she was sent, accurately and on the day it arrived. The 54 expired certificates nobody noticed come down to two linked things the spreadsheet had no way of seeing, and the audit turned up a third problem it could not have shown at all.

Many cards never print an expiry date. Hector's evaluation card says when he was evaluated. It says nothing about when the evaluation stops counting, because a regulation sets that. The same is true of a large share of the file: training certificates often carry only a completion date, and the validity period lives in a standard, a provider's policy, or a clause in a client contract. When Teresa logged those cards she had a date to type into the Issued column and nothing to type into the Expiry column, so the Expiry column stayed blank. 340 of the 1,900 records had no expiry date at all.

A blank expiry looks exactly like a valid one. The spreadsheet's status column used a careful formula: if the expiry cell is empty, show nothing; if the date is before today, show EXPIRED in red. The guard on empty cells was sensible, because without it every half-finished row would have lit up red. It also meant that on the 340 rows with no expiry, the formula politely showed nothing, and nothing carries no colour. So the system for knowing who was qualified worked flawlessly for everyone whose card happened to print the right date, and stayed silent about everyone whose card did not.

A role change creates no row. This is the third problem, and it is the one no amount of careful logging would have caught. When a labourer moves onto a scissor lift on a Tuesday, the requirement for aerial lift training arrives with the job. The spreadsheet lists certificates people have. It has no idea which certificates their current task requires, so a missing certificate produces no row, and no row produces no red. The audit found 23 people doing work that required a certificate they had never held.

So the spreadsheet was accurate about everything it had been told, and silent about everything else. Teresa's 14 hours a week went on typing, chasing and filing. Nothing in her week involved working out what had quietly expired, because nothing in the spreadsheet was capable of telling her.

What it costs

The inspection produced two serious citations, one for Hector and one for a second telehandler operator found on the same site without a current evaluation. At the 2026 federal maximum of $16,550 per serious violation, less the 30% reduction for an employer of 85 people, that came to $23,170.

The citations were the small number. The contractor's client, a healthcare developer, has a clause requiring verified certification for every equipment operator on its sites. After the inspection it required a stand-down while every operator's records were checked by hand. Two days, 140 workers on site, around $130,000 in idle labour, and a schedule slip on a project with a fixed handover date.

The audit Teresa then ran by hand took her and an assistant most of three weeks. It found 61 expired certificates held by people still working on the contractor's sites. The spreadsheet had flagged 7 of them.

The design

The part that needs a model is reading the card. Phone photos of laminated cards, taken in a truck cab, at an angle, partly covered by a thumb, are not something a form can handle. The part that must not be a model is deciding when the card expires. That is a lookup against a rules table with a correct answer, and the answer has to be the same every time.

Trigger. Any card arriving in the safety inbox, sent by text to the safety number, or uploaded through a link given to each subcontractor's office. A full sweep also runs nightly at 02:00 across every record, because a certificate that was valid yesterday can expire tonight without anyone sending anything.

Stage 1, document read. A vision model reads the card and returns the holder's name, the certificate type mapped to a fixed list, the issuing body, the issue or evaluation date, the printed expiry date if one exists, and the card number. Every field carries a confidence score, and the original image is kept against the record.

Stage 2, rules engine. Deterministic. If the card prints an expiry, that date is used. If it does not, the expiry is calculated from the issue date and a rules table: powered industrial truck evaluation, three years; first aid and CPR, two years per the provider; crane operator, five years; OSHA 30, five years where the client contract requires it. Where a client rule is stricter than the regulation, the stricter rule wins. Every calculated expiry records which rule produced it, so the answer can be checked.

Stage 3, match to role. The workforce roster comes from the Procore directory and the subcontractor lists. A role requirement matrix says what each task needs: telehandler operator requires a current powered industrial truck evaluation, aerial lift work requires aerial lift training, and so on. Each person gets a status per requirement: current, expiring within 60 days, expired, or missing. Missing is now a status in its own right, which is the change that catches the labourer on the scissor lift.

Stage 4, chase. At 60, 30 and 7 days before expiry, the holder, their foreman and, for subcontractor staff, the subcontractor's office each receive a message with an upload link. Certificates of insurance are requested from the subcontractor's broker 30 days ahead. A new card coming back through the link goes straight to Stage 1.

Checkpoint, safety review. Teresa reviews every low-confidence read and every expired or missing case before anything reaches a superintendent. She is now looking at a list of exceptions rather than a list of everyone.

Stage 5, the site gate. Every morning at 05:30 the agent checks tomorrow's site roster against the status table. Anyone scheduled for a task that requires a lapsed or missing certificate is flagged to the superintendent with a full day's notice to reassign them or get them assessed.

The Monday morning test

The first 05:30 gate run should flag somebody. On a site of 140 people with a file that has never been calculated, a clean result on day one is far more likely to mean the roster join is broken than that the file is perfect. If it flags nobody, check that the Procore names are matching the certificate names before celebrating.

Before and after

Measure

Before

After

Expired certificates the system knew about

7 of 61

All, overnight

Records with no expiry date

340

0, calculated from rules

People in roles with no required certificate

23, invisible

Flagged as missing

Warning before a certificate lapses

None

60, 30 and 7 days

Safety coordinator time on records

14 hours a week

About 3 hours a week

Notice before a lapsed operator starts work

None

A full day

The build guide

Recommended stack. n8n for orchestration, a vision-capable LLM API for reading cards, Postgres for the certificate table and rules table, the Procore API for the roster, and Twilio for text intake and reminders. Field staff send photos by text far more reliably than by email, so the text number matters more than it looks.

Architecture pattern. Read, calculate, match, chase, gate. The model reads; deterministic code decides. No expiry date is ever produced by the model.

The n8n nodes, in order. IMAP Email Trigger on the safety inbox, Twilio Trigger for inbound texts, and a Webhook for the subcontractor upload link, all feeding one path. HTTP Request to fetch attachments. LLM node with image input and a structured output schema for card fields. Code node for the rules engine, reading the rules table from Postgres. Postgres node to upsert the certificate record. A second Schedule Trigger at 02:00 for the full recalculation sweep. HTTP Request to Procore for the project directory, and for tomorrow's assignments from Procore Workforce Planning (or from the superintendents' own schedule if that module is not in use). Code node for role matching. Twilio and Gmail nodes for reminders. Google Sheets node for Teresa's exception list. Schedule Trigger at 05:30 for the gate check, with a Slack or SMS node to each superintendent.

Build steps. Week one, write the rules table with the safety coordinator and every superintendent in the room, including every client-specific rule, and get it signed off. Week two, the card reader, tested against 300 real phone photos from the existing folder, with the confidence threshold set where the misreads stop. Week three, the Procore roster join and the role requirement matrix. Week four, reminders and the gate. Run in parallel with the spreadsheet for a month.

Estimated build time. 50 to 70 hours, most of it in weeks one and three. The card reader is the impressive part and the easy part.

What it costs to run

Component

Monthly

n8n cloud

$50

Vision LLM API, card reading

$60

Postgres instance

$25

Twilio, text intake and reminders

$35

Monitoring and error alerting

$40

Total

$210

Year one, with an outsourced build at the upper end, lands around $14,000. The incident it was built after cost $23,170 in citations and around $130,000 in a two-day stand-down.

Failure modes and edge cases

Unreadable photos. A card photographed at 40 degrees in a dark cab will be misread. Anything below the confidence threshold goes to Teresa with the image beside the extracted fields, and the holder gets an automatic text asking for a flat photo in daylight.

Two people with the same name. A site of 420 people will have more than one J. Garcia. Match on name plus card number plus employer, and never merge records on name alone.

A wrong rule is wrong everywhere at once. The rules table is the most consequential piece of the system and the least glamorous. A three-year validity entered as five pushes every operator's calculated expiry two years too late, at the same moment, and nobody notices until an inspector does. Version the table, record who changed what, and review it whenever a client contract changes.

Subcontractors who ignore reminders. The message to the individual worker is the one most likely to be ignored. Escalate to the subcontractor's office at 7 days, and to the contractor's own project manager at expiry, with site access as the consequence.

The gate becomes the thing people work around. A superintendent who is told at 06:45 that a crane operator cannot work will find a way to let him work. The gate runs at 05:30 for tomorrow precisely so that the conversation happens a day early, when there is still time to reassign someone.

Take this with you: the starter rules table

The rules table is the part of this design that takes the longest and matters the most, so here is the version the Phoenix contractor started from. Copy it into a spreadsheet, hand it to whoever keeps your certificates, and argue about it before you build anything.

Certificate

How long it lasts

Who sets that

Watch for

Forklift or telehandler operator evaluation

At least every 3 years

Refresher also required after an accident, a near miss, or a move to a different truck type

First aid and CPR

2 years

The training provider

Card usually prints this; check it does

Crane operator certification

5 years

The certifying body, under 29 CFR 1926.1427

Check the date on the certificate itself

OSHA 30

No federal expiry

Often 5 years by client contract

The client rule is the one that bites

Aerial lift training

No fixed US interval; cards commonly 3 to 5 years

The training provider and the employer

Pick one rule, write it down, and apply it to everyone

Confined space entry

Annual refresher is common

Company or client policy

Rarely printed on the card at all

Subcontractor certificate of insurance

The policy term, usually 1 year

The subcontractor's broker

Chase the broker, not the subcontractor

These are common US defaults, included to show the shape of the table. Check every line against the regulation, the training provider and your own client contracts before relying on it, because a wrong rule is wrong for everyone at once.

The arithmetic

The contractor already had every card. It had the regulation. It had a spreadsheet with a perfectly sensible formula. The only thing it lacked was anything that added three years to a date, which is the sort of calculation the spreadsheet could have done in 2023 if anyone had known it needed to.

The agent costs $210 a month. Most of what it does is that addition, 1,900 times, every night.

One question

The design warns 60 days before a certificate expires. We chose 60 as a default, which is to say it is a guess wearing the clothes of a setting. How many days' notice do you actually need to get someone booked onto a refresher and back on site? A number and your trade is plenty. Leave it in the comments below, or reply to Thursday's newsletter if that is easier. The most useful answers will be quoted, with permission, in next week's issue, and if the number is better than ours we will change the Blueprint.

If someone else in your business keeps the certificates spreadsheet, send them this. They will either thank you or explain, at some length, why theirs is fine. Both are useful to know.

If your version of this problem is stranger than this one, raise your hand and we will design it in public.

Your industry is probably already in the back catalogue. One bottleneck, mapped end to end, every week, free to read and precise enough to build from. Subscribe here.

Keep Reading

View more