# Flag Out-of-Policy Spend in Ramp

Yes. Given your expense policy, an agent checks last month's Ramp card spend against it and lists each likely violation with the rule quoted.

[Run this on Rush](https://cloud.getrush.ai/run/out-of-policy-spend/ramp/).

## What the agent does

Two inputs go in. The first is your expense policy, the document people already sign. The request below points at it by URL; a private policy goes in as a `document` block in `input` instead, and the agent finds it under `/workspace/.rush/attachments/`. The second is Ramp, read through the Ramp connection (Ramp's MCP server at `https://ramp-mcp-remote.ramp.com/mcp` from the Rush connector catalog), connected once by someone whose Ramp role can see every cardholder's transactions.

The agent reads the policy first and turns it into a list of checkable rules, each kept with the sentence it came from: a per-person meal limit, a hotel nightly cap, banned merchant types such as alcohol-only bars, a rule that any charge over a set amount needs a receipt and a memo, weekend spend that needs a reason. Rules that cannot be checked from transaction data, such as "economy class unless the flight is over six hours" with no flight duration in Ramp, are listed separately as not checked.

Then it loads last month's card transactions with `load_transactions`, along with the users and departments, and runs each rule over them as a query: amount against the cap, merchant category against the banned list, date against weekends, missing receipt or memo against the threshold. Ramp's own spend limits already block some charges, so the agent looks for what got through.

Each match is a candidate, not a verdict. A $180 dinner may be a team meal for six, so where the memo explains it, the agent marks the line "explained" and keeps it in a lower section. It quotes the rule from your policy word for word on every line and changes nothing in Ramp: no card locks, no flags, no comments.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Our expense policy is at https://example.com/policies/expense-policy.pdf. Read it and list every rule that can be checked from card transaction data, quoting each. Then use the Ramp connection to read last calendar month's card transactions with cardholder, department, merchant, category, amount, date, memo and receipt status. Write policy-review.md listing each transaction that likely breaks a rule: cardholder, merchant, amount, date, the rule quoted from the policy, and whether a receipt or memo is missing. Put transactions whose memo explains the exception in a separate section, and list the policy rules you could not check and why. Read only; change nothing in Ramp.",
  "connections": [
    "ramp"
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The session returns `policy-review.md` in three parts. First, likely violations, grouped by cardholder, each with the merchant, amount, date, the policy sentence it breaks in quotes and whether the receipt or memo is missing. Second, charges that match a rule but carry a memo that may explain them. Third, the rules the agent could not check from Ramp data, so nobody assumes the list is complete when it is not.

A controller reads it as a review queue. Check the rules the agent extracted against your own reading of the policy (the list sits at the top of the report), then work down the first section. Every line points to a real transaction and the query that found it is kept in the transcript, so a disputed flag can be traced to the exact rule and the exact row.

## Run it on every card statement close

Run it once the card statement period closes, when the month's transactions have settled and people have had time to add receipts. A Project automation on a monthly schedule handles that, or a step in your close checklist can send the request.

For a tighter loop, run it weekly with "last 7 days" in the prompt so a missing receipt is chased while the dinner is still remembered. Each run is its own session, and the `run.completed` webhook tells your server when the review list is ready.

## Why run it on Rush?

Reading every receipt against a policy PDF is the slowest part of expense review, and spot checks miss most of it. The agent reads the policy once, turns it into explicit rules you can see, and checks every transaction against every rule in its own sandbox, keeping the query for each flag.

It runs read only by prompt, it never touches a card or a cardholder's record, and a person makes every call on what is a real violation. A finance team with several entities can run one review per entity at once, each a separate session with its own result.

## Frequently asked questions

### How do I give it a policy that is not public?

Send `input` as a list of blocks: a text block with the prompt and a `document` block with the policy, as base64 or as a file uploaded through `POST /o/{org}/files`. The agent finds it under `/workspace/.rush/attachments/` and the rest of the run is the same.

### Will it lock cards or notify employees?

No. The prompt says change nothing, and the output is a file for a person to review. Who gets contacted, and how, stays with your finance team.

### What if our policy is vague?

The agent lists the rules it could check, quoted, and the ones it could not. A rule like "reasonable meal costs" with no number is reported as not checkable, which is often a useful finding on its own.

### Does it check receipts themselves, or only whether one exists?

It reports whether a receipt and a memo are attached, from the transaction's data. Reading the receipt image to compare it with the charge is a separate, larger job you can ask for on the flagged lines in a follow-up.
