A Construction-Site Daily Report Through WhatsApp: Evidence Structure That Does Not Rely on Free Text
Back to blog
automation·September 6, 2026·5 min read·By Yehonatan Saadia

A Construction-Site Daily Report Through WhatsApp: Evidence Structure That Does Not Rely on Free Text

Turning field WhatsApp messages into an evidence record: the five anchors a chat photo lacks, which timestamp counts, and the five-minute media window.

Key takeaways

  • A free-text message loses five anchors: site, zone, work item, sender identity and an authoritative time. Without them the photo is a file, not evidence.
  • The time that counts is the one that arrives in the webhook as Unix seconds, not the moment your worker processed the message and not the camera's EXIF.
  • A media URL from Meta is valid for five minutes. Download outside that window and you are left with an ID pointing at nothing.
  • A correction to yesterday's report is a new record with its own time and author. Overwriting the original deletes exactly what you were trying to prove.

A photo sent in a chat proves that somebody sent a photo. A site evidence record has to bind the file to a site, a zone, a work item, an identified sender, and a time nobody at your end can edit. What follows is a technical description of converting field messages into that record, not legal, medical or financial advice.

The five anchors a free-text message does not carry

"Finished the tiling on floor 3, photo attached" is perfectly clear to two people at ten in the morning and clear to nobody four months later. It is missing:

  • Site. A foreman running two projects posts into the same group, and "floor 3" exists in both.
  • Zone. A floor is not a location. A wing, a grid line, an apartment number or a room number is a location.
  • Work item. "Tiling" is a description. A numbered bill-of-quantities line is something you can certify for payment.
  • Sender identity. A phone number is not a worker. It is a device. Workers change and devices get handed over.
  • Authoritative time. When the information left the field, not when somebody read it.

The distance between that sentence and a record you can rely on is the distance between a chat archive and a site diary. The same gap in an order-intake context, rather than a reporting one, is taken apart in turning WhatsApp messages into a work queue. This article is about something else: not capturing an enquiry, but preserving something somebody will open during a dispute.

Which timestamp actually counts on a field report?

The one WhatsApp delivers inside the webhook. On an inbound message event the timestamp field arrives as a string of Unix seconds, alongside from and a message ID beginning with wamid.. Those three fields are the only part of the record that was not produced on your own machines.

There are three different times around the same photo, and all three deserve separate fields:

The timeSourceWhat it actually saysEditable at your end
Message timestampMeta's webhookWhen the message left the device for the serverNo
Processing timeYour serverWhen you managed to ingest itYes
EXIF capture timeThe image fileWhen the camera believed it was shootingYes, and often absent

Storing all three costs three columns. It settles the argument where one side claims the photo was taken two days earlier and the other claims it was sent on time. Store them in one representation with an explicit offset, as RFC 3339 defines, rather than as a local-format string.

The five-minute window that decides whether you still have the photo

An inbound media message does not carry the file. It carries a media ID, and the file is fetched from the Graph API with an access token. Meta's documentation states plainly that the media URL expires after five minutes, after which you must query the ID again for a fresh one. For current build and running costs, see how much a chatbot costs.

The practical consequence: downloading is part of ingesting the message, not an overnight job. A process that tries to pull a thousand photos at the end of the day gets errors on some of them and will not know which. The build walkthrough is in how to create a WhatsApp bot.

Meta's size limits also decide what can realistically arrive from a site at all:

KindExamplesDocumented limit
Imageimage/jpeg, image/png5MB
Videovideo/mp4, video/3gpp16MB
Audioaudio/ogg with the OPUS codec, audio/mpeg16MB
DocumentPDF, Word and Excel files100MB

Error 131053 is a mismatch between the declared MIME type and the actual file, and it shows up most often when renamed files are sent back out. A wider catalogue of failure codes sits in WhatsApp Cloud API error codes.

The record itself: what is stored per report

One report row binds a single free-text field to four identifiers. The free text stays, because it is what the worker actually wrote:

  • report_id - an internal identifier, not a running message number.
  • site_id and zone_id - both drawn from closed lists.
  • work_item_id - the numbered bill-of-quantities line.
  • reported_by - a worker ID, not a phone number. The phone number is stored separately as a channel.
  • wa_message_id - the original wamid, so you can always point at the message.
  • sent_at - the webhook timestamp.
  • raw_text - the message exactly as sent, uncleaned.
  • media[] - per file: media ID, local path of the downloaded copy, MIME type and size.
  • exceptions[] - a delay, a safety issue or a shortage, each with a severity and an owner.

Raw text is always kept beside the parsed fields. The moment somebody replaces the text with their interpretation of it, there is no way left to check the interpretation.

What happens when the foreman corrects a report the next day?

A new report record is written pointing at the old one, and the old one survives. The new version carries supersedes with the ID it replaces, plus a time, an author and a reason. The screen shows the reader only the latest version, but a query producing a period report can walk the chain.

That is the difference between a system you can lean on and a spreadsheet: in a spreadsheet a correction is a replaced cell, with no way to show what used to be there. The same append-only principle governs signing flows, and is unpacked in quote signature evidence.

Three states worth defining up front:

  1. Submitted - ingested, locked against direct editing.
  2. Superseded - a newer version exists that points at it.
  3. Flagged as wrong - never deleted, marked with a reason, and excluded from totals.

What actually breaks

  • One group for two sites. Reports from two projects land in the same stream and are classified by guesswork.
  • A photo with no work item. A thousand valid photos, none of which certifies a quantity for payment.
  • Late downloads. The nightly run discovers the URLs expired and all that remains is media IDs with no files.
  • Phone number as identity. A worker leaves, the handset moves on, and the entire history is attributed to somebody else.
  • A stored status instead of an event. A "work state" field overwritten on every report cannot reconstruct when the thing was actually finished.
  • A renamed file. An extension that no longer matches the content returns 131053 when the file is sent back to a client.
  • A daily report from all twenty workers. Without a work item that is twenty messages, not twenty lines in a quantities report.

What to have ready before you start

  • Closed lists of sites and zones, before anyone types a zone by hand.
  • A mapping from phone numbers to workers, with a start date and an end date.
  • File storage on a stable path, not a directory wiped on every deploy.
  • A decision on who owns an exception that has been open for three days.

Sources

#WhatsApp Cloud API#construction#field reporting#evidence#automation#WhatsApp

Frequently asked questions

Can the report stay a free-text message with no form?

It can, and then the system has to ask exactly one follow-up: which site and which work item. The important split is not form versus text, it is a record carrying identifiers versus one that does not. Free text stored alongside four identifiers is entirely sound.

Why not rely on the photo's EXIF data?

Because EXIF is not guaranteed. Apps strip metadata, devices are misconfigured, and a screenshot carries nothing at all. EXIF is useful corroboration where it exists, but the authoritative time should be the one received from WhatsApp's server rather than one editable on a handset.

What happens when a worker reports outside the 24-hour window?

Inbound messages always arrive, and every user message opens and resets a 24-hour customer service window. The restriction applies to what you send outward: outside the window you may only initiate with an approved template. For ingesting field reports there is no constraint here.

How long should the files themselves be kept?

That is a business decision rather than a technical one, so it belongs in a field rather than in habit. Define a retention policy per record type, and record deletion as an event with a time and an actor. A silent deletion is indistinguishable in hindsight from data loss.

Keep reading

Related service

WhatsApp Cloud API

Templates, a two-way inbox and reminders on the official Meta API.

Learn more →←

About the author

Yehonatan Saadia

Freelance automation, web & MVP developer

I'm Yehonatan Saadia, a senior developer who builds business automation, custom websites, and MVPs for small and mid-sized companies across the US, Europe, and Israel. These guides come from real client work, not theory.

Work with me

Have a project like this?

Tell me what you're trying to automate or build. I reply within 24 business hours with a few targeted questions, then we walk through it on a free 30-minute call, with no commitment. You come away with a scope, a timeline and a fixed price - or a straight answer that it isn't worth building.