Back to Accounts Receivable & Chasing

Integration and API Spec

The reference during the build: every tool connection, auth scope, field mapping, and error-handling rule.

4 pagesPDF · Technical
FS-DOC-05Technical

Integration and API Spec

Accounts Receivable and Chasing

[YourCompany.com] · Finance Department · Prepared by FullSpec · [Today's Date]

This document is the authoritative integration reference for the AR Chase Agent build. It defines every tool connection, the exact OAuth scopes and webhook configurations required, field mappings between systems, the orchestration layout, and the error handling behaviour for every integration point. The FullSpec team uses this specification to configure, test, and validate all connections before any production credentials are applied. Where a value must be stored in the credential store rather than hardcoded, this document states that explicitly.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agent
Xero
Invoice source and payment reconciliation trigger
OAuth 2.0 (authorization code flow)
Xero Starter or above
AR Chase Agent (Agent 1)
Gmail
Send tiered reminder emails to overdue clients
OAuth 2.0 via Google Workspace
Google Workspace Business Starter or above
AR Chase Agent (Agent 1)
Google Sheets
Chase history log: read reminder count, write new rows
OAuth 2.0 via Google Workspace (same app as Gmail)
Google Workspace Business Starter or above
AR Chase Agent (Agent 1)
Slack
Post escalation alerts to the finance channel
OAuth 2.0 (Slack app, bot token)
Slack Free or above
AR Chase Agent (Agent 1)
HubSpot
Write payment status notes to client contact records
OAuth 2.0 (private app token)
HubSpot Starter CRM or above
AR Chase Agent (Agent 1)
Orchestration layer
Schedule daily poll, route data between tools, manage retries
Internal service account / platform credentials
Standard plan ($55/month)
All agents
Before you connect anything: all OAuth connections and webhook endpoints must be validated against sandbox or test environments before production credentials are entered. For Xero, use the Xero Demo Company. For Gmail and Google Sheets, use a dedicated test Google Workspace account. For HubSpot, use a sandbox portal. Validate token refresh flows, scope grants, and rate limit behaviour in the sandbox before switching to live credentials.
Integration and API SpecPage 1 of 4
FS-DOC-05Technical

02Per-tool integration detail

Xero

Xero is polled daily by the orchestration layer to retrieve all invoices with a status of AUTHORISED or OVERDUE where the DueDate is in the past and the AmountDue is greater than zero. The same connection is used later in the flow to apply payment records when a bank feed match is confirmed.

Auth method
OAuth 2.0 authorization code flow. Register a connected app in the Xero developer portal. Store client_id and client_secret in the credential store. Access tokens expire after 30 minutes; refresh tokens are valid for 60 days and must be rotated automatically by the orchestration layer.
Required scopes
openid profile email accounting.transactions accounting.transactions.read accounting.contacts accounting.contacts.read offline_access
Trigger / poll setup
No inbound webhook is available for invoice status changes on standard Xero plans. The orchestration layer runs a scheduled GET poll once daily at 07:00 local business time. Endpoint: GET /api.xro/2.0/Invoices?where=Status=="AUTHORISED"AND DueDate<DateTime.UtcNow&summaryOnly=false. Filter in-platform for AmountDue > 0.
Required configuration
Xero tenant ID (stored in credential store, not hardcoded). Connected app client_id and client_secret (credential store). Refresh token (credential store, auto-rotated). Target organisation confirmed as the correct Xero tenant before go-live.
Rate limits
Xero enforces 60 API calls per minute and 5,000 calls per day per connected app. At ~60 invoices/month the daily poll generates approximately 2 to 5 API calls. Throttling is not required at current volume. Build in a 1-second delay between paginated requests as a precaution.
Constraints
OAuth token refresh must be handled silently by the platform; a failed refresh must trigger an alert before the next scheduled run. The Xero API returns dates in UTC; the platform must convert to the business local timezone for day-overdue calculations. Do not use the Xero Reports API for invoice retrieval; use the Invoices endpoint directly.
// Poll output (per invoice)
InvoiceID        : string (UUID)
InvoiceNumber    : string
Contact.Name     : string
Contact.EmailAddress : string
Contact.ContactID : string (UUID)
AmountDue        : decimal
DueDate          : ISO8601 date string
Status           : string (AUTHORISED | OVERDUE)
// Payment write input
InvoiceID        : string (UUID)
Amount           : decimal
Date             : ISO8601 date string
Account.Code     : string (bank account code from Xero chart of accounts)
Gmail

Gmail sends all outbound reminder emails from the designated finance inbox. Emails are composed by the orchestration layer using pre-approved tiered templates, with invoice-specific values injected at send time. The from address must match the authorised send-as address in Google Workspace.

Auth method
OAuth 2.0 via the Google Workspace Gmail API. Use the same Google Cloud project as Google Sheets to share a single OAuth consent screen. Store access_token and refresh_token in the credential store. Tokens expire after 1 hour; the platform must refresh silently.
Required scopes
https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.compose
Send-as configuration
Confirm the send-as address in Google Workspace Admin before build. The OAuth-authenticated user must have Send As permission for the finance inbox address. If a custom domain is in use, verify DKIM and SPF records are correctly configured to avoid delivery failures.
Required configuration
Authorised send-as email address (credential store). OAuth client_id, client_secret, access_token, refresh_token (credential store). Three reminder email templates stored in the orchestration layer with named placeholders: {{invoice_number}}, {{client_name}}, {{amount_due}}, {{due_date}}, {{days_overdue}}, {{reminder_count}}, {{finance_contact_name}}, {{finance_contact_email}}.
Rate limits
Gmail API enforces 250 quota units per user per second and a daily sending limit of 2,000 messages for Google Workspace accounts. At ~60 invoices/month the maximum daily send volume is well under 10 messages. Throttling is not required at current volume.
Constraints
The platform must never send a reminder to an invoice contact address that appears on the exceptions list in Google Sheets. Validate the exclusion list read before composing any email. Do not use SMTP directly; use the Gmail API send endpoint (POST /gmail/v1/users/me/messages/send) so that sent messages appear in the finance inbox sent folder.
// Input per send action
to              : string (client email address from Xero contact)
from            : string (authorised send-as address, from credential store)
subject         : string (rendered from template)
body_html       : string (rendered HTML template with injected values)
body_text       : string (plain-text fallback)
// Output (Gmail API response)
message_id      : string (Gmail message ID, stored to Google Sheets log)
thread_id       : string
labelIds        : array
Google Sheets

Google Sheets serves as the central chase log. Before each reminder send, the orchestration layer reads the sheet to determine how many reminders have already been sent for a given invoice and when the last one was dispatched. After each action, a new row is appended recording the outcome.

Auth method
OAuth 2.0 via Google Sheets API, shared Google Cloud project with Gmail. Same access_token and refresh_token stored in the credential store.
Required scopes
https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.readonly
Sheet structure
Spreadsheet name: AR Chase Log. Tab name: chase_log. Columns (A through K) in exact order: invoice_id, invoice_number, client_name, client_email, amount_due, due_date, days_overdue, reminder_count, last_reminder_date, last_reminder_subject, gmail_message_id. Row 1 is a header row and must not be written to. All date values stored as ISO8601 strings (YYYY-MM-DD). A second tab named exceptions_list contains a single column (A) of email addresses excluded from automated chasing.
Required configuration
Spreadsheet ID (stored in credential store, not hardcoded). Sheet tab names as listed above (confirmed before build). The Google service account or OAuth user must have Editor access to the spreadsheet.
Rate limits
Google Sheets API enforces 300 read requests per minute per project and 300 write requests per minute per project. At ~60 invoices/month the daily run generates fewer than 20 read and 20 write calls. Throttling is not required at current volume.
Constraints
Always use the spreadsheetId from the credential store. Never hardcode the spreadsheet URL or ID in workflow logic. Use FILTER or a structured GET (sheets.spreadsheets.values.get with a named range) to read reminder history for a specific invoice_id, not a full sheet download. Append rows using sheets.spreadsheets.values.append with valueInputOption=RAW.
// Read input (reminder history lookup)
spreadsheet_id  : string (from credential store)
range           : string  e.g. 'chase_log!A:K'
filter_field    : invoice_id
// Read output
reminder_count  : integer
last_reminder_date : string (ISO8601)
// Write input (append row after action)
invoice_id      : string
invoice_number  : string
client_name     : string
client_email    : string
amount_due      : decimal
due_date        : string (ISO8601)
days_overdue    : integer
reminder_count  : integer (incremented)
last_reminder_date : string (ISO8601, today)
last_reminder_subject : string
gmail_message_id : string
Slack

Slack receives a formatted escalation alert when an invoice meets the escalation threshold: 60 or more days overdue, or three or more reminders sent without payment. Alerts are posted to the designated finance channel using a Slack bot token.

Auth method
OAuth 2.0 Slack app with bot token scope. Create a Slack app in the workspace, install it, and store the bot_token (xoxb-...) in the credential store. No user token is required.
Required scopes
chat:write chat:write.public channels:read
Webhook / channel setup
The platform posts using the Slack Web API chat.postMessage endpoint (POST https://slack.com/api/chat.postMessage). The target channel ID (not channel name) must be stored in the credential store. Retrieve the channel ID from the Slack admin console or via conversations.list. Do not use an incoming webhook URL as these are not rotatable; use the bot token and API method instead.
Required configuration
Slack bot_token (credential store). Target finance channel ID (credential store). Alert message template with fields: client_name, invoice_number, amount_due, days_overdue, reminder_count, xero_invoice_url. The bot must be invited to the target channel before go-live.
Rate limits
Slack Web API enforces a Tier 3 rate limit of 50 calls per minute for chat.postMessage. At ~60 invoices/month the maximum escalation volume is a small fraction of this. Throttling is not required at current volume.
Constraints
Post only one alert per invoice per day, even if the invoice meets multiple escalation criteria simultaneously. Store a flag in Google Sheets (column: slack_alerted, boolean) to prevent duplicate alerts on subsequent daily runs for the same invoice.
// Input
channel         : string (channel ID from credential store)
text            : string (fallback plain text)
blocks          : array (Slack Block Kit JSON with invoice details)
  > client_name     : string
  > invoice_number  : string
  > amount_due      : decimal
  > days_overdue    : integer
  > reminder_count  : integer
  > xero_invoice_url : string
// Output
ok              : boolean
ts              : string (message timestamp, store for audit)
HubSpot

HubSpot receives a note on the client's contact record after each reminder send and after each payment reconciliation. The note records the current reminder stage or confirms payment received. The contact is matched by email address from the Xero invoice contact.

Auth method
HubSpot private app access token (Bearer token). Create a private app in HubSpot settings, grant the required scopes, and store the access token in the credential store. Private app tokens do not expire unless revoked; rotate every 90 days as a security policy.
Required scopes
crm.objects.contacts.read crm.objects.contacts.write crm.objects.notes.write crm.schemas.contacts.read
Contact lookup
Use the HubSpot Contacts Search API (POST /crm/v3/objects/contacts/search) with filterGroups matching on the email property equal to the client email address from Xero. If no contact is found, log the miss to Google Sheets and skip the HubSpot step without failing the run.
Required configuration
HubSpot private app access token (credential store). HubSpot portal ID (credential store). Note body template with placeholders: {{invoice_number}}, {{reminder_stage}}, {{amount_due}}, {{action_date}}. Association type ID for Contact-to-Note associations (standard value: 202, confirm against the target portal).
Rate limits
HubSpot enforces 100 API calls per 10 seconds and 40,000 calls per day on Starter plans. At ~60 invoices/month this automation generates fewer than 5 HubSpot API calls per daily run. Throttling is not required at current volume.
Constraints
Never create a new HubSpot contact from this automation. The AR Chase Agent is a read-and-note tool only; contact creation is out of scope. If the contact lookup returns multiple matches (duplicate email), log the ambiguity to Google Sheets and skip the HubSpot note for that invoice, alerting in Slack.
// Contact search input
filterGroups[0].filters[0].propertyName : 'email'
filterGroups[0].filters[0].operator     : 'EQ'
filterGroups[0].filters[0].value        : string (client email from Xero)
// Contact search output
results[0].id   : string (HubSpot contact ID)
// Note create input (POST /crm/v3/objects/notes)
properties.hs_note_body  : string (rendered template)
properties.hs_timestamp  : string (ISO8601 UTC)
associations[0].to.id    : string (contact ID)
associations[0].types[0].associationCategory : 'HUBSPOT_DEFINED'
associations[0].types[0].associationTypeId   : 202
// Note create output
id              : string (HubSpot note ID, store to Google Sheets log)
Integration and API SpecPage 2 of 4
FS-DOC-05Technical

03Field mappings between tools

The tables below document every field handoff between systems in the AR Chase Agent flow. Field names are shown in the exact format used by each tool's API. All mappings are one-directional unless stated.

Handoff 1: Xero poll output to Google Sheets reminder history lookup

Source tool
Source field
Destination tool
Destination field
Xero
InvoiceID
Google Sheets
invoice_id
Xero
InvoiceNumber
Google Sheets
invoice_number
Xero
Contact.Name
Google Sheets
client_name
Xero
Contact.EmailAddress
Google Sheets
client_email
Xero
AmountDue
Google Sheets
amount_due
Xero
DueDate
Google Sheets
due_date
Xero
(computed: today minus DueDate in days)
Google Sheets
days_overdue

Handoff 2: Google Sheets chase log read to AR Chase Agent reminder selection logic

Source tool
Source field
Destination tool
Destination field
Google Sheets
reminder_count
Orchestration layer
reminder_count (integer, drives template selection)
Google Sheets
last_reminder_date
Orchestration layer
last_reminder_date (gate: skip if < 7 days ago)
Google Sheets
exceptions_list!A:A
Orchestration layer
exclusion_email_list (array, compared against client_email)

Handoff 3: Orchestration layer to Gmail send action

Source tool
Source field
Destination tool
Destination field
Xero
Contact.EmailAddress
Gmail
to
Credential store
send_as_address
Gmail
from
Orchestration layer
rendered_subject (from template + invoice_number)
Gmail
subject
Orchestration layer
rendered_body_html (template with injected values)
Gmail
body_html
Orchestration layer
rendered_body_text
Gmail
body_text
Xero
InvoiceNumber
Gmail template
{{invoice_number}}
Xero
Contact.Name
Gmail template
{{client_name}}
Xero
AmountDue
Gmail template
{{amount_due}}
Xero
DueDate
Gmail template
{{due_date}}
Orchestration layer
days_overdue (computed)
Gmail template
{{days_overdue}}
Google Sheets
reminder_count (incremented)
Gmail template
{{reminder_count}}

Handoff 4: Gmail send response to Google Sheets log append

Source tool
Source field
Destination tool
Destination field
Gmail API response
message_id
Google Sheets
gmail_message_id
Orchestration layer
rendered_subject
Google Sheets
last_reminder_subject
Orchestration layer
today (ISO8601)
Google Sheets
last_reminder_date
Orchestration layer
reminder_count + 1
Google Sheets
reminder_count

Handoff 5: Escalation decision to Slack alert

Source tool
Source field
Destination tool
Destination field
Xero
Contact.Name
Slack block
client_name
Xero
InvoiceNumber
Slack block
invoice_number
Xero
AmountDue
Slack block
amount_due
Orchestration layer
days_overdue (computed)
Slack block
days_overdue
Google Sheets
reminder_count
Slack block
reminder_count
Orchestration layer
xero_invoice_url (constructed from InvoiceID)
Slack block
xero_invoice_url

Handoff 6: Xero payment detected to HubSpot note creation

Source tool
Source field
Destination tool
Destination field
Xero
Contact.EmailAddress
HubSpot search filter
filterGroups[0].filters[0].value
HubSpot search response
results[0].id
HubSpot note create
associations[0].to.id
Xero
InvoiceNumber
HubSpot note template
{{invoice_number}}
Orchestration layer
reminder_stage (e.g. Reminder 2 of 3)
HubSpot note template
{{reminder_stage}}
Xero
AmountDue
HubSpot note template
{{amount_due}}
Orchestration layer
today (ISO8601)
HubSpot note template
{{action_date}}
Integration and API SpecPage 3 of 4
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
One workflow per agent. The AR Chase Agent is implemented as a single workflow in the automation platform, covering all steps from the daily Xero poll through to the HubSpot note write. A shared credential store holds all secrets and IDs; no secret or identifier is hardcoded in workflow logic.
Number of workflows
1 (AR Chase Agent workflow). Sub-branches within the workflow handle the escalation path (Slack alert) and the HubSpot note path independently, both triggered from the same invoice loop.
AR Chase Agent trigger mechanism
Scheduled poll. The workflow is triggered by a time-based schedule set to 07:00 local business timezone daily. On trigger, the platform executes a GET request to the Xero Invoices API endpoint with the overdue filter. There is no inbound webhook for this agent. Signature validation is not applicable for a poll trigger.
Credential store contents
See code block below. All values are environment variables or secret manager entries in the platform, referenced by key name in workflow nodes.
Token refresh handling
OAuth refresh tokens for Xero, Gmail, and Google Sheets must be refreshed silently by the platform before expiry. Configure the platform's OAuth connector to store and auto-rotate access tokens. A failed refresh must emit an error event that triggers a Slack alert to the FullSpec monitoring channel before the next scheduled run.
Retry configuration
All HTTP nodes are configured with a maximum of 3 retry attempts with exponential backoff starting at 5 seconds (5s, 25s, 125s). See Section 05 for per-integration retry behaviour.
Environment separation
Maintain separate credential store entries for sandbox and production environments. The workflow includes an environment flag variable (ENV: sandbox | production) that gates which credential set is used. Switch to production only after QA sign-off.
Logging
The platform must write an execution log entry for every workflow run, capturing: run timestamp, number of invoices processed, number of emails sent, number of Slack alerts posted, number of HubSpot notes written, and any errors encountered. Retain execution logs for a minimum of 90 days.
Credential store key reference. Store all values as encrypted secrets. Never interpolate secrets directly into workflow node configuration fields visible in plain text.
// Credential store contents (all values stored as secrets, referenced by key name)

// Xero
XERO_CLIENT_ID            : string   // OAuth app client ID
XERO_CLIENT_SECRET        : string   // OAuth app client secret
XERO_TENANT_ID            : string   // Xero organisation tenant ID
XERO_ACCESS_TOKEN         : string   // Auto-rotated by platform
XERO_REFRESH_TOKEN        : string   // Auto-rotated by platform, 60-day expiry
XERO_BANK_ACCOUNT_CODE    : string   // Chart of accounts code for payment matching

// Gmail / Google Workspace
GOOGLE_CLIENT_ID          : string   // Shared Google Cloud project OAuth client ID
GOOGLE_CLIENT_SECRET      : string   // Shared Google Cloud project OAuth client secret
GOOGLE_ACCESS_TOKEN       : string   // Auto-rotated by platform
GOOGLE_REFRESH_TOKEN      : string   // Auto-rotated by platform
GMAIL_SEND_AS_ADDRESS     : string   // Authorised send-as email address

// Google Sheets
SHEETS_SPREADSHEET_ID     : string   // AR Chase Log spreadsheet ID
SHEETS_LOG_TAB            : string   // Value: chase_log
SHEETS_EXCEPTIONS_TAB     : string   // Value: exceptions_list

// Slack
SLACK_BOT_TOKEN           : string   // xoxb-... bot token
SLACK_FINANCE_CHANNEL_ID  : string   // Target channel ID (not channel name)

// HubSpot
HUBSPOT_ACCESS_TOKEN      : string   // Private app token, rotate every 90 days
HUBSPOT_PORTAL_ID         : string   // HubSpot portal ID
HUBSPOT_NOTE_ASSOC_TYPE   : integer  // Value: 202 (confirm against target portal)

// Orchestration
ENV                       : string   // sandbox | production
BUSINESS_TIMEZONE         : string   // e.g. Australia/Sydney
REMINDER_MIN_INTERVAL_DAYS: integer  // Minimum days between reminders, e.g. 7
ESCALATION_DAYS_THRESHOLD : integer  // Days overdue before escalation, e.g. 60
ESCALATION_REMINDER_COUNT : integer  // Reminder count before escalation, e.g. 3
The ESCALATION_DAYS_THRESHOLD and ESCALATION_REMINDER_COUNT values must be confirmed with the finance team before go-live and stored as configurable credential store entries, not hardcoded integers. This allows the business to adjust thresholds without a code change.

05Error handling and retry logic

Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently. Where a retry policy is defined, the platform must log each retry attempt and the final outcome. If a manual fallback is required, the platform must post a Slack alert to the FullSpec monitoring channel with the invoice ID, the failed step, and the error message.

Integration
Scenario
Required behaviour
Xero API poll
HTTP 429 rate limit response
Wait 60 seconds and retry up to 3 times with exponential backoff. If all retries fail, abort the run and post a Slack alert to the monitoring channel. Do not process invoices with stale data.
Xero OAuth token refresh
Refresh token expired or revoked
Immediately halt all workflow execution. Post a critical Slack alert to the monitoring channel. Do not attempt to process invoices. Manual re-authorisation required before next run.
Xero API poll
HTTP 500 or 503 server error
Retry 3 times with backoff (5s, 25s, 125s). If all retries fail, skip the run and log the failure. Post a Slack alert. Resume on next scheduled run. Do not fail silently.
Google Sheets read (reminder history)
Spreadsheet not found or permission denied
Abort the run immediately. Post a Slack alert with the spreadsheet ID and error. Do not send any emails without confirmed reminder history. Manual investigation required.
Google Sheets write (log append)
Write failure after email sent
Retry 3 times with backoff. If all retries fail, send a Slack alert with the invoice ID and Gmail message ID so the log entry can be added manually. Email is already sent; do not resend.
Gmail send
HTTP 429 sending quota exceeded
Pause sending for 60 seconds and retry up to 3 times. If quota is exhausted for the day, queue remaining sends for the next run and log affected invoice IDs to Google Sheets with status: send_deferred.
Gmail send
Invalid recipient address (bounce or 4xx)
Log the failed send to Google Sheets with status: send_failed and the error code. Post a Slack alert with the invoice ID and the invalid address. Do not retry. Manual review required.
Gmail OAuth token refresh
Refresh token expired or revoked
Halt all email sending. Post a critical Slack alert. Do not attempt to send reminders without a valid token. Manual re-authorisation required.
Slack chat.postMessage
HTTP 429 rate limit or invalid channel
Retry 3 times with 5-second delays. If the channel ID is invalid, log the error to the platform execution log and email a fallback alert to the finance contact address stored in the credential store.
HubSpot contact search
No contact found for client email
Log the miss to Google Sheets with status: hubspot_contact_not_found. Skip the HubSpot note step and continue the run. Do not fail the invoice processing step. No retry required.
HubSpot contact search
Multiple contacts returned for same email
Log the ambiguity to Google Sheets with status: hubspot_duplicate_contact. Skip the HubSpot note. Post a Slack alert with the client email and contact IDs. Manual deduplication required before the next run.
HubSpot note create
HTTP 401 invalid token
Halt HubSpot note writing for the run. Post a Slack alert. Token rotation required. Log all skipped note writes with status: hubspot_auth_failed so they can be written manually once the token is restored.
Orchestration layer
Any unhandled exception in workflow execution
The platform must catch all unhandled exceptions at the workflow level, log the full error with stack trace to the execution log, and post a Slack alert with the run ID, the failed node name, and the error message. Silent failures are not permitted under any circumstance.
For support during build or post-launch issues, contact the FullSpec team at support@gofullspec.com. Include the workflow run ID, the affected invoice ID, and the error message from the platform execution log.
Integration and API SpecPage 4 of 4

More documents for this process

Every document generated for Accounts Receivable & Chasing.

Launch Plan
Operations · Owner
View
ROI and Business Case
Finance · Owner
View
Process Runbook / SOP
Operations · Owner
View
Developer Handover Pack
Technical · Developer
View
Test and QA Plan
Quality · Developer
View