The design
How a customer connects
No screens on either side. We run one admin command for the partner and the customer. It makes one secret for that pair, which we share with Orca's engineer out of band. To cut a customer off, we disable that row.
Decided (Orca's email, Oct 29): Orca sends that secret on every update as Authorization: Bearer, stored per customer on their side. Signed webhooks (the Stripe, Slack and Twilio pattern) stay on the later list for a partner that already signs; the POC does not build them.
The three statuses
One update per POST to https://propflowai.co/api/work-order-updates, plain JSON { id, time, work_order { pms_account_id, pms_property_id, pms_work_order_id }, status }.
| Status | When Orca sends it | Extra data (optional) | What Clara does |
|---|---|---|---|
on_the_way | Tech taps start, which Orca's founder confirmed is when they leave for the job (call, Oct 29) | eta | Texts "on the way" |
arrived | Tech is at the unit | none | Texts "has arrived" |
completed | Tech says nothing is left to do | notes, photos[url], labor_minutes | Adds notes and photos, closes as job done, asks "how did it go?" |
- One message with a status field is how Dynamics 365 Field Service, Uber and ServiceChannel report a visit (Traveling / In Progress / Completed; EN_ROUTE / ARRIVED / COMPLETED; DISPATCH CONFIRMED / ON SITE / COMPLETED), so Orca's engineer has seen this shape before.
- No technician field. The PMS work order already names who is assigned; the text uses that name, else "your technician". At Western Slope that is a named person on 122 of 149 in-house orders read since August (the vendor field only says the company).
POST /api/work-order-updates HTTP/1.1
Host: propflowai.co
Content-Type: application/json
Authorization: Bearer wspm-orca-••••••••
{
"id": "88cdca95-2a99-4f1a-82c4-68d9eba0f63c",
"time": "2026-10-29T19:28:00-06:00",
"work_order": {
"pms_account_id": "westernslopepm",
"pms_property_id": "112",
"pms_work_order_id": "48213"
},
"status": "on_the_way",
"eta": "2026-10-29T19:45:00-06:00"
}
HTTP/1.1 202 Accepted
Content-Type: application/json
{ "id": "88cdca95-2a99-4f1a-82c4-68d9eba0f63c" }
Three replies only: 202 accepted (repeats too), 401 bad or disabled credential, 400 anything else wrong (the body says what). No reply: resend with the same id. Full contract: work-order-updates-openapi.yaml.
What happens on our side
completed.- Every text and PMS write obeys the customer's maintenance mode: Supervised holds each text and each AppFolio write for approval on the same review page as held messages, Live sends. No Orca-specific switches.
- Partner code lives in
src/lib/integrations/<partner>/; the core never knows it is Orca. - Why close right at
completed: at Western Slope the tech marks Work Done and the office marks Completed, with no review step between (in-house orders since August: median 5.8 hours apart, 71% the same day; nearly all close as No Need To Bill).
Prototype result (2026-10-29, local)
- A fake Orca on a laptop sent updates for a Willows test work order. All were accepted; a repeat got the same 202, no second text.
- Our test phone got the on-the-way and arrived texts, then the rating text. The prototype let them skip Supervised; the real build will not.
- AppFolio work order 3463-1 closed and now shows Ready to Bill. The production version must close as job done only.
Branch fede/orca-poc-local, local only, no CI.
Later, only if a customer needs it
- Future statuses:
return_visit_needed,canceled; plus late notes or photos, reassigned. - An optional
technician_name, for orders with no assigned person (27 of those 149). - Signed webhooks (Standard Webhooks headers) for a partner that already signs.
- A later
completedafter Orca's manager approval, carrying final labor minutes for billing. - Optional setting: require review before closing. Recommended path: Clara still closes at
completed, and only excepDecision: writes wait under Supervised
Decided (Fede, Oct 29 night): PMS writes from work order updates wait under Supervised the same way as messages. Notes, photos and the close are held for approval on the review page beside held texts, using the hold that already exists for property-software writes; approving one replays the exact write. Live lets them through. It is a maintenance-mode rule for all writes, not an Orca rule.
/li> - Hold every write.
- Send
arrivedas its own update when the geofence trips, not a flag on the start event. - Send
completedonce, when the tech taps stop; manager approval needs no update for now. - How long do your photo links stay valid?
- Maintenance rollout: the 9 in 10 figure.
- Stripe, Slack, Twilio: how they sign.
- Standard Webhooks spec: the header names.
- Dynamics 365, Uber, ServiceChannel: the status shape.
- Also: the raw 2026-10-29 call transcript and a read-only pull of Western Slope work orders.
Orca's draft vs. this design (Oct 29 email)
Stephen sent a first draft of two events the same night, then more detail an hour later. Reference, not a copy; ours stays where it is simpler.
| Item | Orca's draft | Ours | Verdict |
|---|---|---|---|
| Auth | Bearer token per customer | Same | Agree; POC is bearer only |
| Events | job.started with a geofence flag, job.completed | One update, status on_the_way / arrived / completed | Keep ours; arrived is its own send |
| Technician | Name and id on every event | Not needed; the work order names who is assigned | Ignored if sent (Fede ruling) |
| Completed status | ended or approved (manager batch sign-off) | Act when the tech taps stop | Keep ours; approval is billing, not closing |
| Work order key | AppFolio work order id | PMS id or displayed number | Agree |
| Extra fields | GPS trail, miles, start and end times, unit | Unknown fields ignored | Fine; nothing breaks |
| Photos | Coming, capture being built | Optional list of links | Agree |
| Delivery | POST, unique event id, retry on non-2xx | Same | Agree |
| Work order id on their side | Stored on the time entry; Orca does nothing else with it. Western Slope updates work orders by hand today. | The id is the key; Clara closes the order | Confirms the job-done close closes their loop |
| Notes coverage | 80% of Western Slope time entries, 40% at Situs; higher for techs | Notes optional on completed | Agree; the AppFolio note is skipped when empty |
| Other fields | Asks what else we want | Nothing for the POC | Answered in the reply: none now |