agentsclimarketplace

Ramp complete expenses

Skill ramp-public/skills/plugins/ramp/skills/ramp-complete-expenses

Find and complete requested revisions and missing items on your transactions — receipts, memos, accounting categories, funds, and attendees. Use when: 'transaction revision requested', 'fix a rejected expense', 'missing receipts', 'upload receipt', 'attach receipt', 'receipt sweep', 'add memo', 'categorize transactions', 'missing items', 'transaction cleanup', 'fix my transactions', 'set tracking category', 'assign to fund', 'bulk memo update', 'receipt compliance'. Do NOT use for: approving transactions (use ramp-approval-dashboard), vendor documents like W-9s or contracts (use ramp-manage-vendors), or spend reporting (use ramp-spend-analysis).From its SKILL.md

Install
npx -y skills add ramp-public/skills --skill ramp-complete-expenses

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

18.3 KB, as published. Nobody here has run it

Non-Negotiables

  • Pass --rationale on every command — it is a required field on these agent-tools (a non-empty string, max 1024 chars). With --json, supply it as a "rationale" key in the body. Omitting it returns HTTP 422 (DEVELOPER_INVALID_SCHEMA), in both agent and human modes.
  • Scope to the user's own transactions by default (--transactions_to_retrieve my_transactions) unless they explicitly request broader access.
  • Only the acting cardholder can complete a transaction revision. Do not attempt revision completion as an admin, manager, or copilot on the cardholder's behalf.
  • Show the transaction details before editing. Never blind-edit.
  • Never upload a receipt without confirming the match — wrong receipt on wrong transaction is worse than no receipt.
  • For bulk edits or receipt sweeps, present the plan and confirm before executing.
  • Use ramp transactions missing {uuid} as the reliable check for whether a receipt is attached — it returns missing_receipt: true/false in real time. The receipt_uuids field in the list response can be used as a quick filter, but it may be stale (e.g., remaining null even after a successful upload+attach).
  • Receipt file upload is CLI-only. CLI uploads must be base64-encoded; accepted types are PNG, JPEG, PDF, HEIC, and WEBP.
  • MCP users must upload receipts through the Ramp web or mobile app, or forward them from their work email to [email protected]. Do not call upload-receipt-file from MCP.
  • The --user_submitted_fields flag tracks provenance — include it to mark which fields the user explicitly provided vs agent-inferred.
  • All CLI flags use underscores, not hyphens (e.g., --from_date, --transaction_uuid).

--rationale is required

Every command in this skill maps to an agent-tool endpoint that requires a rationale: a non-empty string (max 1024 chars) explaining why you are making the call. Pass it as --rationale "...", or include a "rationale" key in the --json body. It is required for both agent (--agent) and human (agent=false) invocations — omitting it is the #1 cause of HTTP 422 errors on these tools. The examples below all include it; keep it on every call.

Workflow

Revision-request tasks

When GetAttentionFeed / ramp tasks list returns TRANSACTION_REVISION_REQUESTED, preserve the task's transaction UUID and revision request context. Inspect the live transaction, show the requested changes, and get the cardholder's explicit confirmation before editing.

  1. Fix every requested agent-editable field with the applicable workflow below. A successful field edit does not itself complete the revision request.
  2. Re-read the transaction and its missing items. If a requested field still needs user-only work, give the user the returned Ramp link and stop; do not complete the revision prematurely.
  3. Ask the cardholder for, or have them approve, a nonblank completion reason summarizing how the request was resolved.
  4. Complete the revision for that same transaction.

MCP:

CompleteTransactionRevision(
  transaction_uuid="{transaction_uuid}",
  reason="Added the requested receipt and corrected the department",
  rationale="Complete the cardholder's resolved transaction revision"
)

CLI:

ramp transactions complete-revision {transaction_uuid} \
  --reason "Added the requested receipt and corrected the department" \
  --rationale "Complete the cardholder's resolved transaction revision" --agent

Treat the success response's sanction-lift status PENDING_VERIFICATION as an instruction to verify, not as evidence that a card is unlocked. Poll GetAttentionFeed / ramp tasks list and ListCards with a finite bound (at most three rechecks in the current run). On every attention-feed attempt, follow every section's cursor chain until next_cursor is null and require the number of unique hydrated task UUIDs to equal each section's total_count; otherwise the attempt is incomplete and cannot prove the revision task is absent. If a section's total_count changes between pages, restart that bounded attempt from the first page rather than combining two snapshots. Success requires a fully accounted feed in which the same revision task has disappeared and the exact sanctioned card reports is_spendable: true. If the bound is exhausted, report the live task, active_locks, and blocking_task_count; do not say the revision restored card spending.

If revision completion returns:

  • CompleteTransactionRevisionNotFoundError, re-check the transaction UUID from the task context.
  • CompleteTransactionRevisionPermissionDeniedError, stop and explain that the acting cardholder must complete their own revision.
  • CompleteTransactionRevisionFailedPreconditionError, re-read the attention feed and transaction state. This also covers a replay after the revision is already complete; do not retry it as a new completion event.
  • CompleteTransactionRevisionInternalError, report that completion could not be verified and leave the task outstanding.

Step 1: Find transactions needing attention

ramp transactions list --transactions_to_retrieve my_transactions \
  --from_date {start} --state cleared --rationale "Find transactions needing cleanup" --agent --page_size 50

For any transaction, check what's missing:

ramp transactions missing {transaction_uuid} --rationale "Check missing items on the transaction"

Returns missing_receipt (bool), missing_memo (bool), and missing_accounting_items (an array of objects, not category-name strings). Each object has this shape:

{
  "category_name": "QuickBooks Online Department",
  "category_id": "category-uuid"
}

Present results grouped by what's missing:

Needs attention: 8 transactions ($4,520 total)

  Missing receipts (3):
    $1,200  United Airlines     2026-03-01
    $  800  Hilton Hotels       2026-03-03
  Missing memos (5): ...
  Missing accounting categories (2): ...

Step 2: Fill memos

Before writing memos manually, check if Ramp has suggestions:

ramp transactions memo-suggestions {transaction_uuid} --rationale "Fetch AI-suggested memos"

Returns memos[] — an array of suggested memo strings based on the transaction context. Present suggestions and let the user confirm or edit, then:

ramp transactions edit {transaction_uuid} --memo "Q2 team offsite catering" --rationale "Add the user's memo"

To clear a memo, pass an empty string: --memo "" (note: --rationale itself must never be empty).

Step 3: Assign to a fund/spend allocation

ramp transactions edit {transaction_uuid} --fund_uuid {fund_uuid} --rationale "Assign transaction to the chosen fund"

To find available funds:

ramp funds list --funds_to_retrieve MY_FUNDS --include_balance --rationale "List funds to assign the transaction" --agent

Step 4: Set tracking categories (accounting codes)

First, get available categories and their options:

# List categories
ramp accounting categories --rationale "List tracking categories" --agent

# List options for a specific category (use UUID from above)
ramp accounting category-options {tracking_category_uuid} --rationale "List options for the tracking category" --agent --page_size 50

Then edit via --json (tracking categories aren't exposed as named flags).

Important: When using --json, you must include both rationale and transaction_uuid in the body. The --json flag bypasses the CLI's automatic injection of the positional arg and the --rationale flag, so a --json body without a "rationale" key returns HTTP 422.

ramp transactions edit --json '{
  "rationale": "Set the tracking category the user chose",
  "transaction_uuid": "{transaction_uuid}",
  "tracking_category_selections": [
    {
      "category_uuid": "{category_uuid}",
      "option_selection": "{option_uuid}"
    }
  ],
  "user_submitted_fields": ["tracking_category_selections"]
}'

Note: the field names inside tracking_category_selections are category_uuid and option_selection — NOT tracking_category_uuid / tracking_category_option_uuid (those are the names returned by the categories list endpoint, not the edit endpoint).

Step 5: Set attendees

ramp transactions edit --json '{
  "rationale": "Record attendees for this expense",
  "transaction_uuid": "{transaction_uuid}",
  "attendee_selections": {
    "non_ramp_attendees": [
      {"attendee_name": "Jane Smith", "attendee_email": "[email protected]"}
    ],
    "include_self_as_attendee": false
  },
  "user_submitted_fields": ["attendee_selections"]
}'

Step 6: Upload receipts

MCP cannot upload receipt files. Direct MCP users to the Ramp web or mobile app, or ask them to forward the receipt from their work email to [email protected].

For CLI callers, when the user has a receipt file and wants to attach it to a transaction:

# Base64 encode the file (agent does this)
# For a file at /path/to/receipt.pdf:
base64 -i /path/to/receipt.pdf | tr -d '\n'

# Upload and auto-attach in one step
ramp receipts upload \
  --content_type "application/pdf" \
  --filename "receipt.pdf" \
  --file_content_base64 "{base64_string}" \
  --transaction_uuid {txn_uuid} --rationale "Upload the receipt"

The response returns receipt_uuid and attached_to_transaction: true/false.

Omitting --transaction_uuid uploads the receipt without attaching it. The CLI can attach it later with:

ramp receipts attach {receipt_uuid} {transaction_uuid} --rationale "Attach the receipt to the transaction"

Bulk upload from a directory of receipt images/PDFs:

# For each file:
# 1. Determine MIME type from extension (.pdf → application/pdf, .png → image/png, .jpg → image/jpeg)
# 2. Base64 encode: base64 -i <file> | tr -d '\n'
# 3. Match to a transaction by inferring merchant/date from filename or content
# 4. Upload with -n (dry run) first to verify

ramp receipts upload \
  --content_type "image/png" \
  --filename "uber-2026-03-01.png" \
  --file_content_base64 "{base64}" \
  --transaction_uuid {txn_uuid} -n --rationale "Upload the receipt"

# If correct, upload for real (without -n)

Step 7: Handle missing receipts without a file

If the user doesn't have a receipt and wants to provide a reason:

ramp transactions explain-missing {transaction_uuid} --reason "Lost receipt — vendor confirmed purchase via email" --rationale "Record why the receipt is missing"

Or generate a link to the missing receipt affidavit form (the user must complete it manually in the browser):

ramp transactions flag-missing {transaction_uuid} --rationale "Generate a missing-receipt affidavit link"

Receipt Matching Heuristics

When matching receipt files to transactions:

  • Filename patterns: merchant-YYYY-MM-DD.pdf, YYYY-MM-DD-merchant.png, etc.
  • Amount matching: If the receipt shows an amount, match to transactions within ±$1 at that merchant on that date.
  • Date matching: Receipt date should be within 1-2 days of transaction_time.
  • One receipt per transaction: Before each upload, re-check the live state with ramp transactions missing {transaction_uuid} and skip when missing_receipt is false. Do not rely on receipt_uuids from an earlier list response — it can be stale (see Gotchas) and would trigger a duplicate upload of a recently attached receipt.

Flag uncertain matches as "possible match — verify" rather than auto-uploading.

MIME Type Reference

ExtensionContent type
.pngimage/png
.jpg, .jpegimage/jpeg
.pdfapplication/pdf
.heicimage/heic
.webpimage/webp

Bulk Cleanup Workflow

For cleaning up many transactions at once:

  1. Fetch all transactions in the period
  2. Check missing_items on each (or batch-check via individual calls)
  3. Group by what's missing: memo, accounting, receipt
  4. Present summary: "12 transactions need memos, 5 need accounting categories, 3 need receipts"
  5. For memos: fetch suggestions for each, present them, let user confirm or edit
  6. For categories: if most transactions share a category, offer to bulk-apply
  7. For receipts: match files per the heuristics above, dry-run first, confirm the plan
  8. Execute sequentially, report progress

Provenance Tracking

The --user_submitted_fields flag tells Ramp which fields the user explicitly provided. This matters for compliance — it distinguishes user intent from agent inference.

Include it when setting fields via --json:

ramp transactions edit --json '{
  "rationale": "Add the user's memo",
  "transaction_uuid": "{transaction_uuid}",
  "memo": "Client dinner with Acme team",
  "user_submitted_fields": ["memo"]
}'

Valid values: attendee_selections, attendee_uuids, fund_uuid, memo, tracking_category_selections, trip_selection.

When using named flags (--memo, --fund_uuid), provenance is tracked automatically.

Pagination

If pagination.next_cursor is not null in the JSON envelope, there are more results:

ramp transactions list --transactions_to_retrieve my_transactions \
  --from_date {start} --state cleared --agent --page_size 50 \
  --next_page_cursor "{cursor}" --rationale "List the user's transactions"

Example Session

User: I have a bunch of transactions that need cleanup

Agent: Let me check what's missing on your recent transactions.
> ramp transactions list --transactions_to_retrieve my_transactions \
>   --from_date 2026-03-01 --state cleared --rationale "Find transactions needing cleanup" --agent --page_size 50

Found 8 transactions. Checking missing items on each...
> ramp transactions missing {uuid} --rationale "Check missing items" (×8)

Summary:
  5 need memos
  2 need accounting categories
  1 needs a receipt

Let me get AI-suggested memos for the 5:
> ramp transactions memo-suggestions {uuid} --rationale "Fetch suggested memos" (×5)

Transaction                              Suggested memo
$135  Facebook Ads     2026-03-02       "Q1 paid social campaign"
$220  AWS              2026-03-05       "March infrastructure costs"
$89   Uber             2026-03-10       (no suggestion)

Want to accept these suggestions, edit them, or write your own?

User: Accept Facebook and AWS. The Uber was a client dinner ride.

Agent: Updating 3 transactions:
> ramp transactions edit {fb-uuid} --memo "Q1 paid social campaign" --rationale "Apply accepted memo suggestion"
> ramp transactions edit {aws-uuid} --memo "March infrastructure costs" --rationale "Apply accepted memo suggestion"
> ramp transactions edit {uber-uuid} --memo "Client dinner transportation" --rationale "Set memo from user input"

Done. Now the receipt: United Airlines, $1,200 on 2026-03-05.

User: It's at ~/Downloads/united-mar5.pdf

Agent: > base64 -i ~/Downloads/united-mar5.pdf | tr -d '\n'
> ramp receipts upload --content_type "application/pdf" \
>   --filename "united-mar5.pdf" \
>   --file_content_base64 "{base64}" \
>   --transaction_uuid "abc-123" -n --rationale "Upload the receipt"

Dry run looks correct — uploading to United Airlines ($1,200) on 2026-03-05.
Proceed?

User: yes

Agent: > ramp receipts upload --content_type "application/pdf" ...
Receipt uploaded and attached (receipt_uuid: def-456).
2 transactions still need accounting categories — want to tackle those next?

When NOT to Use

  • Approving or rejecting items — use ramp-approval-dashboard
  • Vendor documents (W-9s, contracts, COIs) — use ramp-manage-vendors
  • Company-wide spend reporting — the CLI is scoped to your own data; use ramp-spend-analysis or the Ramp dashboard

Gotchas

IssueFix
HTTP 422 "API error 422: There was an error."You omitted rationale. It's a required field on these agent-tools (DEVELOPER_INVALID_SCHEMA) — add --rationale "...", or a "rationale" key in the --json body. Required for both agent and human (agent=false) calls. Not a permissions problem.
--dry_run succeeds but the real call 422s--dry_run only prints the body; it does not validate it. Confirm rationale is present before sending.
amount is a formatted string ("$135.40")Strip "$" and "," for numeric operations
--state values are lowercaseUse cleared, pending, declined — not uppercase
Tracking categories require --jsonNamed flags only cover --memo and --fund_uuid. When using --json, include both rationale and transaction_uuid in the body.
Category field names differ between endpointsaccounting category-options returns tracking_category_option_uuid, but transactions edit expects category_uuid + option_selection
memo-suggestions may return emptyNot all transactions have enough context for suggestions
accounting category-options paginates with integersUnlike other endpoints, the cursor is a number, not a string
--transactions_to_retrieve is requiredAlways include it on transactions list. Use my_transactions for personal, all_transactions_across_entire_business for admin scope
Searching for specific transactionsUse --reason_memo_merchant_or_user_name_text_search "query" (min 3 chars)
Large receipt files may hit shell arg limitsCLI: for files >100KB, write base64 to a temp file and use --json with the content read from file.
Receipt uploads from MCPReceipt file upload is unavailable. Direct users to the Ramp web/mobile app or [email protected].
Duplicate upload riskRe-check ramp transactions missing {uuid} immediately before uploading; skip when missing_receipt is false. receipt_uuids alone can be stale.
Comment on a transactionramp general comment {uuid} --ramp_object_type transaction --message "text" --rationale "Add a comment for the user"

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.