Clear for everyoneAuditable at every step

See exactly how it works

No black boxes. No surprises. Here’s what happens from the moment you create a job to the moment you get paid.

Three participants. Zero friction.

Each person gets the interface that fits their world — no one is forced to learn a new app.

You — the operator

CLI or AI agent

Manage the full job lifecycle from your terminal or hand the reins to Claude. Every command outputs JSON — full control, fully auditable.

# every action is one command
$ contractor jobs assign abc --contractor xyz
✓ SMS sent · status: assigned
$ contractor revenue --from 2026-01
✓ $12,840 total · 3 pending
Contractor

Just a text message

Gets a job offer by SMS. Replies YES, NO, or DONE. No app to download, no account to create — ever. Works on every phone, every carrier.

field worker's phone
New job: Gutter clean, Mar 15. Pay: $240.
Reply YES or NO. Ref: A1B2
YES
Got it! Job accepted. Reply DONE when finished.
Client

One click, no login

Gets a link by email. Clicks to approve the quote, pay the invoice, or leave a review. No account needed — not now, not ever.

From: Job Relay <noreply@…>
Subject: Your quote for Gutter Clean is ready
Your quote for Gutter Clean is $240.

A job, start to finish

Seven states. Every transition is logged. The auto badge means something fires without you lifting a finger.

1
Draft

Create the job with one CLI command

contractor jobs create
triggered by You
auto
2
Quoted

Set the price — approval email fires to the client

contractor jobs quote
triggered by You
3
Booked

Client clicks Approve in their email — no login needed

email link click
triggered by Client
auto
4
Assigned

Assign a contractor — SMS fires to their phone

contractor jobs assign
triggered by You
5
In Progress

Contractor replies YES by text — you're notified

SMS: YES
triggered by Contractor
auto
6
Complete

Contractor replies DONE — payment link fires to client

SMS: DONE
triggered by Contractor
auto
7
Paid

Client pays via Stripe — review request fires automatically

Stripe checkout
triggered by Client
Contractor experience

The contractor never
leaves their phone

Your field workers already have everything they need — their phone.

No app store. No password reset emails. No training session.

When you assign a job, they get a text. One word to accept. One word when done.

Works on any phone, any carrier
Multiple active jobs? Include the ref number to disambiguate
Declines are fine — job returns to the pool, you reassign
Job Relay
SMS
New job: Gutter clean at 42 Oak St, Mar 15. Pay: $240.
Reply YES to accept or NO to decline. Ref: A1B2C3
YES
Got it! Job accepted. Reply DONE when finished.
Day of job
DONE
Great work! Job marked complete. Payment link sent to client.
From: Job Relay <noreply@…>
Subject: Your quote for Gutter Clean is ready

Your quote for Gutter Clean, 42 Oak St is ready — $240.

From: Job Relay <noreply@…>
Subject: Work complete — your invoice is ready

Mike T. has completed the job. Pay securely via Stripe.

From: Job Relay <noreply@…>
Subject: How did Mike T. do?

Leave a quick review for Mike T. — it only takes a second.

Client experience

Your client clicks once,
that’s it

Three emails. Three clicks. That’s the entire client experience.

No account. No app. No password. Just a secure link in their inbox.

Each link works once, then expires
Approve links: 72 hours  ·  Payment links: 7 days  ·  Review links: 14 days. Expired? The operator reissues in one command.
Security model

Security that doesn’t require trust

Every client link is cryptographically unique. Here’s what that means in plain English.

One link, one action

Each link can only be used once. After a client approves a quote, that link is gone. You can't reuse it, forward it, or replay it.

Links expire automatically

Approve links expire in 72 hours. Payment links in 7 days. Review links in 14 days. Expired? The operator reissues in one command.

Same error, always

Whether a link is wrong, expired, or already used, clients see the same message. No information leaks about why it failed.

Token lifecycle
Generate
256-bit random crypto.randomBytes
Store
DB with expiry per token type
Visit
Client clicks email link
Validate
Not used? Not expired?
Consume
Atomic UPDATE marks used
Execute
Approve / Pay / Review

Invalid / expired / already used → same generic error shown to client

Ready to run your operation?

Set up takes minutes. Your first job in the pipeline today.