Integration and API Spec
The reference during the build: every tool connection, auth scope, field mapping, and error-handling rule.
Integration and API Spec
Expense Management Automation
[YourCompany.com] · Finance Department · Prepared by FullSpec · [Today's Date]
This document provides the complete integration and API reference for the Expense Management automation. It covers every tool in the stack, the exact authentication scopes and configuration required for each, field-level mappings between agent handoffs, orchestration layout, credential store contents, and defined error handling behaviour for every integration point. This document is intended for the FullSpec build team. [YourCompany.com] is responsible for provisioning API credentials and confirming that plan tiers for each tool meet the minimums stated below.
01Tool inventory
02Per-tool integration detail
Expensify is the entry point for the automation. Every new expense claim submitted by an employee triggers Agent 1. The integration uses the Expensify Integration Server API (JSON API). The automation platform polls the Expensify report list endpoint on a defined interval to detect newly submitted reports, then retrieves the full report payload including receipt attachments.
// Trigger payload (selected fields) reportID: string reportName: string total: float (USD cents) currency: string (ISO 4217) submitterEmail: string receiptFilenames: string[] categories: string[] submittedDate: string (ISO 8601) // Output to Agent 1 Structured claim record with all fields above plus downloaded receipt file path
Gmail is used in two places: Agent 1 sends receipt chase emails when a receipt is missing or unreadable, and Agent 3 sends the employee confirmation email on approval or rejection. Both uses share the same OAuth 2.0 credential. The integration targets the Gmail API v1.
// Input to send endpoint (receipt chase)
to: submitterEmail
subject: 'Action required: missing receipt for your expense claim'
body: rendered TEMPLATE_RECEIPT_CHASE with {{employee_name}}, {{claim_amount}}, {{claim_date}}
// Input to send endpoint (confirmation)
to: submitterEmail
subject: 'Your expense claim has been approved'
body: rendered TEMPLATE_CLAIM_CONFIRMATION with {{employee_name}}, {{claim_amount}}, {{payroll_date}}Google Drive is used by Agent 1 to store downloaded receipt files before they are attached to the Xero spend money record. Files are written to a dedicated automation folder and named with a canonical format to prevent collisions. The Drive API v3 is used.
// Input receipt_binary: file stream (JPEG, PNG, or PDF) file_name: string (canonical format as above) folder_id: GDRIVE_RECEIPTS_FOLDER_ID // Output drive_file_id: string drive_file_name: string
Xero is used by Agent 2 to create a draft spend money record with the correct GL code and attached receipt, and by Agent 3 to finalise (approve) that record on manager approval, or void it on rejection. The Xero Accounting API v2 is used.
// Input to create spend money (Agent 2) type: 'SPEND' status: 'DRAFT' date: claim_date (ISO 8601) amount: claim_amount (float) reference: reportID lineItems[0].accountCode: resolved GL code from XERO_GL_MAP lineItems[0].description: merchant_name + ' - ' + category lineItems[0].unitAmount: claim_amount bankAccount.accountID: XERO_BANK_ACCOUNT_ID attachment: drive_file_id (uploaded as multipart/form-data) // Output from create bankTransactionID: string status: 'DRAFT' // Input to finalise (Agent 3, on approval) bankTransactionID: string status: 'AUTHORISED' // Input to void (Agent 3, on rejection) bankTransactionID: string status: 'VOIDED'
Slack is used exclusively by Agent 3 to send the approval request message to the relevant department manager, render the approve and reject interactive buttons, and fire a 24-hour reminder if no action is taken. The Slack Web API and Block Kit are used. A dedicated Slack App must be created in the [YourCompany.com] Slack workspace.
// Input to chat.postMessage (approval request)
channel: resolved manager Slack user ID
blocks: Block Kit array with claim_amount, merchant_name, claim_date, gl_code, receipt_thumbnail_url
attachments: approve button (action_id: 'approve_claim'), reject button (action_id: 'reject_claim')
metadata: { report_id, bank_transaction_id, submitter_email }
// Incoming interaction payload (approve or reject)
action_id: 'approve_claim' | 'reject_claim'
metadata: { report_id, bank_transaction_id, submitter_email }
user.id: manager Slack user ID
// Output to orchestration layer
approval_decision: 'approved' | 'rejected'
bank_transaction_id: string
report_id: string
submitter_email: stringGusto is used by Agent 3 to add the approved reimbursement amount as an expense line on the employee's next payroll run. The Gusto API v1 is used. Admin credentials are required.
// Input to add reimbursement
POST /v1/companies/{GUSTO_COMPANY_ID}/payrolls/{payroll_id}/employees/{employee_id}/reimbursements
amount: claim_amount (string, two decimal places)
description: 'Expense reimbursement: ' + merchant_name + ' ' + claim_date
// Output
reimbursement_id: string
payroll_id: string
employee_id: string
status: 'pending'03Field mappings between tools
The following tables define the exact field mappings at each agent handoff. Source and destination field names are given in monospace format exactly as they appear in the API response or request body. Where a value is derived or transformed, the transformation is noted in the destination field column.
Agent 1 handoff: Expensify to Agent 1 (Receipt Extraction and Policy Agent) internal claim record
Agent 2 handoff: Agent 1 claim record to Xero (GL Coding and Xero Sync Agent)
Agent 3 handoff: Agent 2 output to Slack, Xero finalisation, Gusto, and Gmail (Approval Routing and Notification Agent)
04Build stack and orchestration
// Credential store contents (key name : type : description) EXPENSIFY_PARTNER_ID : string : Expensify partnerUserID (API key) EXPENSIFY_PARTNER_SECRET : string : Expensify partnerUserSecret (partner user token) EXPENSIFY_POLICY_ID : string : [YourCompany.com] Expensify policy ID XERO_CLIENT_ID : string : Xero OAuth 2.0 application client ID XERO_CLIENT_SECRET : string : Xero OAuth 2.0 application client secret XERO_REFRESH_TOKEN : string : Xero OAuth 2.0 refresh token (auto-rotated) XERO_TENANT_ID : string : Xero organisation (tenant) ID XERO_BANK_ACCOUNT_ID : string : Xero bank account ID for spend money transactions XERO_GL_MAP : JSON obj : Merchant category to Xero account code mapping table GMAIL_CLIENT_ID : string : Google OAuth 2.0 client ID (shared with Drive) GMAIL_CLIENT_SECRET : string : Google OAuth 2.0 client secret (shared with Drive) GMAIL_REFRESH_TOKEN : string : Google OAuth 2.0 refresh token (auto-rotated) GMAIL_SENDER_ADDRESS : string : From address for all automated emails TEMPLATE_RECEIPT_CHASE : string : HTML email template for receipt chase TEMPLATE_CLAIM_CONFIRMATION : string : HTML email template for approval confirmation TEMPLATE_CLAIM_REJECTION : string : HTML email template for rejection notification GDRIVE_RECEIPTS_FOLDER_ID : string : Google Drive folder ID for receipt storage SLACK_BOT_TOKEN : string : Slack Bot Token (xoxb-...) SLACK_SIGNING_SECRET : string : Slack App signing secret for payload validation SLACK_MANAGER_MAP : JSON obj : Department / email to manager Slack user ID mapping GUSTO_CLIENT_ID : string : Gusto OAuth 2.0 client ID GUSTO_CLIENT_SECRET : string : Gusto OAuth 2.0 client secret GUSTO_REFRESH_TOKEN : string : Gusto OAuth 2.0 refresh token (auto-rotated) GUSTO_COMPANY_ID : string : Gusto company ID for [YourCompany.com] EXPENSIFY_LAST_POLL_TS : string : ISO 8601 timestamp of last successful Expensify poll PROCESSED_REPORT_IDS : string[] : Register of Expensify reportIDs already processed
05Error handling and retry logic
Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently. If an error cannot be resolved by the retry logic below, the orchestration layer must log the full error payload, halt the affected workflow branch, and send an alert to the finance admin via Gmail using GMAIL_SENDER_ADDRESS.
More documents for this process
Every document generated for Expense Management.