Developer reference
Zapier REST API
The ExpenseBot Zapier integration uses this production API to read approved expense data, create reviewed entries, upload receipts, start Gmail scans, and create reports.
- Base URL
https://mcp.expensebot.ai- Content type
application/json- Support
- support@expensebot.ai
Authentication
ExpenseBot uses OAuth 2.0 Authorization Code with PKCE. Native Zapier connections obtain and refresh tokens through the ExpenseBot consent flow; users do not create API keys or copy client secrets.
Authorization: Bearer <OAuth access token>
Accept: application/json
Content-Type: application/json| Scope | Permits |
|---|---|
expenses.read | Read expenses, categories, tags, and receipt results. |
expenses.write | Create expenses, mileage, income, and receipt submissions. |
gmail.scan | Start Gmail receipt scans and read their status. |
reports.read | List and find reports. |
reports.write | Create reports. |
Dates and safe retries
Calendar dates use strict, valid YYYY-MM-DD values. Date ranges are inclusive and must provide both boundaries, with the end on or after the start. Timestamps use timezone-bearing ISO 8601 instants. Invalid, ambiguous, incomplete, or reversed dates are rejected.
Every financial write requires source_event_id: the stable unique ID from the source trigger. Reusing it for the same operation makes a retry idempotent and returns idempotent_replay: true instead of creating a duplicate. Reusing it with conflicting data returns 409.
Receipt upload flow
- Call
POST /api/zapier/receipts/upload-urlswith file metadata. - Upload each file's raw bytes to its short-lived
signedUrlusingPUTand exactly the returnedrequiredHeaders. - Call
POST /api/zapier/receiptswith the returned upload references, then poll the exact submission ID until processing completes.
Endpoints
/api/zapier/meReturn the ExpenseBot account connected to the OAuth token.
- Scope
Authenticated connection- Request
- No query parameters.
- Response
- An object containing id and email for the connected account.
/api/zapier/reportsList reports for polling triggers and exact report searches.
- Scope
reports.read- Request
- Optional query parameters: page (1 or greater), limit (1-100), and status.
- Response
- An array of report objects with a stable report_id, title, status, created_at timestamp, expense_count, total, currency, and report_url.
/api/zapier/expensesList or search expenses using exact filters.
- Scope
expenses.read- Request
- Optional query parameters: query, merchant, category, tag, start, end, limit (1-100), and cursor. start and end are inclusive ISO calendar dates.
- Response
- An array of expense objects. Each object includes expense_id, date, merchant, amount, currency, category, tag, notes, and review_url when available.
/api/zapier/categoriesList configured expense categories for Zapier dynamic fields.
- Scope
expenses.read- Request
- No query parameters.
- Response
- An array of objects containing id and name.
/api/zapier/tagsList configured client, project, and trip groups for Zapier dynamic fields.
- Scope
expenses.read- Request
- No query parameters.
- Response
- An array of objects containing id and name.
/api/zapier/expensesCreate a reviewed cash or card expense.
- Scope
expenses.write- Request
- JSON body. Required: source_event_id, merchant, total, date, category. Optional: currency, subtotal, tax, tip, city, notes, tag. date is YYYY-MM-DD.
- Response
- A write result with success, message, record_id, row_number, spreadsheet_url, review_expenses_url, and idempotent_replay.
/api/zapier/mileageCreate a reviewed business mileage entry.
- Scope
expenses.write- Request
- JSON body. Required: source_event_id, distance, purpose. Optional: date, round_trip, destination, city, category, tag, notes. date is YYYY-MM-DD when supplied.
- Response
- A write result with success, message, record_id, review_expenses_url, and idempotent_replay.
/api/zapier/incomeCreate a reviewed income entry.
- Scope
expenses.write- Request
- JSON body. Required: source_event_id, amount, source, payment_method. Optional: date, currency, description, category, reference, fees, tax_collected, tag, notes. date is YYYY-MM-DD when supplied.
- Response
- A write result with success, message, record_id, review_income_url, and idempotent_replay.
/api/zapier/gmail/scansStart a Gmail receipt scan for a recent lookback or an exact date range.
- Scope
gmail.scan- Request
- JSON body. Required: source_event_id and either lookback_days or both start_date and end_date. Optional: account_email. Date ranges are inclusive YYYY-MM-DD values and end_date cannot precede start_date.
- Response
- A write result with submission_id, status, message, and idempotent_replay.
/api/zapier/gmail/statusReturn the current or latest Gmail scan status.
- Scope
gmail.scan- Request
- No query parameters.
- Response
- A status object with scan_in_progress, completed_at, result counts, action_needed_count, and available review links.
/api/zapier/receipts/upload-urlsCreate short-lived signed upload URLs for receipt files.
- Scope
expenses.write- Request
- JSON body with files, an array of objects containing id, filename, and mimeType. Supported receipt sources include images, HEIC files, and PDFs.
- Response
- Upload metadata for each file, including signedUrl, uploadRef, requiredHeaders, and the expiration window. Upload raw file bytes to signedUrl with PUT and exactly the returned headers.
/api/zapier/receiptsSubmit uploaded receipt references for extraction.
- Scope
expenses.write- Request
- JSON body. Required: source_event_id and upload_refs. Each upload_refs item contains the same id used in the upload request and its uploadRef. Optional: note and tag.
- Response
- A write result with submission_id, status, spreadsheet_url, review_expenses_url, and idempotent_replay.
/api/zapier/receipts/{submissionId}Get the processing result for one exact receipt submission.
- Scope
expenses.read- Request
- Path parameter: submissionId returned by POST /api/zapier/receipts.
- Response
- A processing result with found, state, verdict, completed_at, aggregate counts, per-file outcomes when available, and review links.
/api/zapier/reportsCreate an expense report for an exact date range.
- Scope
reports.write- Request
- JSON body. Required: source_event_id, title, and date_range with inclusive YYYY-MM-DD start and end values. Optional: categories, tags, exclude_personal, excluded_categories, and excluded_tags.
- Response
- A write result with report_id, report_url, bill_client_url, message, and idempotent_replay.
Error responses
| Status | Meaning |
|---|---|
| 400 | Invalid input, missing source event ID, or failed validation. |
| 401 | Missing, invalid, expired, or revoked OAuth token. Reconnect the Zapier account. |
| 403 | The OAuth connection does not include the required scope. |
| 409 | A source event is already processing or conflicts with an earlier write. |
| 502 | The underlying ExpenseBot operation could not return a usable result. |
Google permissions and data use
ExpenseBot's production Google OAuth application is verified for the Google permissions it requests. Gmail access is optional and is used only after the user connects Gmail and starts or schedules a scan. ExpenseBot does not send or delete email.
Google Workspace listingPrivacy policy and Gmail scope detailsTerms
