# How we get new vendors through onboarding

Every day an agent checks new vendor requests in Gmail for a W-9, a banking form and a signed contract, logs each vendor in a Google Sheets register and flags gaps in Slack. It never approves or sets up payment.

Canonical page: https://themachine.myapps.ai/use-cases/vendor-onboarding

New vendors reach us as an email: a company name, someone to contact and, on a
good day, three files attached. One is a W-9, one is a banking form, one is a
signed contract. Before anyone sets the vendor up, all three need to be there,
filled in properly, and in agreement with each other. When people check that
by hand, it's the first thing dropped when a deadline looms. And the miss that
gets through is always the costly one, like a vendor added to the payment
system with an unsigned contract or a W-9 that has no TIN.

Machine runs an agent that takes this on. It looks at the inbox once a day,
holds every new vendor request up against the same fixed checklist, writes the
result into our vendor register, and calls out in Slack anything missing or
wrong. Its work is collecting, checking and logging. Approving a vendor, or
going anywhere near payment or banking setup, is never part of it.

- **Team:** Machine
- **Runs on:** A cron schedule, once a day
- **Connected systems:** Gmail · Google Sheets · Slack
- **Mode:** Collects, checks and logs. Never approves a vendor, never sets up payment

## The problem

On paper, vendor onboarding forms are easy. In real life they arrive in every
state imaginable. The W-9 has no signature. The banking form has a blank where
the routing number goes. The contract names the wrong legal entity because
someone reused an old template. Spotting any one of those takes seconds.
Spotting all of them, on every vendor, without fail, is tedious checklist work,
and a busy person gives the week's first vendor a careful look and the tenth
a quick glance.

You don't feel the cost of a skipped check right away. It shows up later, when
a vendor has been set up to be paid on forms that turn out to be incomplete,
and fixing that afterwards takes far longer than the two minutes the check
would have taken. Nobody needs help deciding whether to take on a vendor. What
the process lacks is someone who reads every attachment against one checklist,
every single time, and never rushes ahead to the next email.

## What we built

Once a day, a schedule on Machine starts a brand new session that remembers
nothing from yesterday. The record it relies on is the vendor register, a
Google Sheet. On each run the agent opens the new vendor-request emails under a
Gmail label and tests every attachment against a fixed checklist: a W-9 that
is filled in and signed, a banking form that is filled in, and a signed
contract whose entity name matches. Every vendor gets its result written down,
clean or not. For anything missing or wrong, the agent drafts a follow-up
email, then posts a roundup to Slack for a person to handle. It never marks a
vendor as approved and never creates a payment method or banking profile.

## How it works

### Start fresh every day

A **cron trigger** runs the agent once daily. Each time, it opens a new
**session**: a fresh cloud computer (a sandbox) with no memory of the last run.
The vendor register in Google Sheets is the only thing that links one day to
the next. That way no vendor is ever handled twice, and nothing hinges on the
agent recalling anything.

### Teach it the intake checklist

The checklist travels with the agent as a **skill**. It spells out what makes
a W-9 complete, what makes a banking form complete, and what makes a signed
contract valid. It lists the exact fields each document must have, says the
vendor's name has to be identical on all three, and explains the difference
between a document that's wrong and one that simply isn't there. Every vendor,
on every run, is measured against that same standard.

### Hook up the tools it needs

**Connectors** are scoped connections to your tools. The keys stay on our
servers, so the model never sees a raw token. With them, the agent:

- **Reads vendor requests in Gmail.** The email thread and its attachments,
kept under their own label.
- **Reads and updates the register in Google Sheets.** Where every vendor
stood before, and the status this run gives each one.
- **Drafts follow-ups in Gmail.** A request for a missing or corrected
document, saved as a draft. The agent never sends it.
- **Posts to Slack.** A roundup of every vendor it handled, with each flagged
one listing exactly what's missing or wrong.

### Put the limits in place

The agent's role ends once it has collected, checked and logged. Marking a
vendor approved, creating a payment method, and touching banking or ACH setup
in any system are all out of bounds, even when every form is perfect. Any
email meant for a vendor is saved as a draft for a person to read and send.
Bank account and routing numbers are checked to make sure they're present and
complete, but they are never copied into the register. Only the document's
status gets written down.

### Log every vendor and call out the gaps

From then on, each day adds one row to the register for every new vendor
request, marked complete or flagged, with the exact missing or wrong item
named. Slack gets a single roundup post. Any incomplete vendor already has a
follow-up email drafted and waiting. A person looks at the flag, sends the
draft or asks for something else, and makes the real call on onboarding.

> **The pattern**
> Each day a **cron** starts a **fresh session** that reads new requests in
> Gmail, checks the paperwork against a checklist kept as a **skill**, and
> writes the outcome to the vendor register in Google Sheets. The state lives
> in that register, not in the agent's head. Gaps get a drafted email and a
> flag in Slack. Approval and payment are never the agent's to touch.

## Guardrails

The agent does all the paperwork except the one decision that counts, so its
access is narrow and its authority stops short of approval:

- **Isolation.** Each run happens in a sandbox of its own. The session can
  reach Gmail, Google Sheets and Slack and nothing else, and only the register
  update and the Slack post are meant to outlast the run.
- **Scoped, brokered credentials.** Access to Gmail and Google Sheets is handed
  to the sandbox when a run begins, and only to the agents you grant it to.
- **Collect, check, log, and stop.** The agent reviews the documents and
  records a status in the register. It has no route to approving a vendor or
  setting up a payment method or banking profile, however complete the forms.
- **Drafts, never sends.** Follow-up emails to vendors sit in Gmail as drafts.
  A person reads them and sends them.
- **No sensitive data at rest in the sheet.** Bank account and routing numbers
  are checked for completeness on the original document and never copied into
  the register. Only a status goes in.
- **Everything is code.** The checklist, the layout of the register and what
  each system lets the agent do are files in the repo. They're versioned, and
  any change goes through a reviewed **change request**, not a toggle on a
  settings page.

## The outcome

- **Every day:** New vendor requests held to one unchanging checklist
- **3 documents:** W-9, banking form and signed contract checked for each vendor
- **0 approvals:** Approving vendors and setting up payment stay with a person

The forms that once got a careful read for the first vendor and a hurried one
by the tenth now get the same checklist every time, logged in a single
register rather than spread over a dozen email threads. The agent collects,
checks and logs. Who gets approved, and who gets paid, is still a person's
decision.
