FS-DOC-05Technical
Integration and API Spec
Receivables and Invoice Chasing
01Tool inventory
The table below lists every tool connected in this automation, its role in the process, how it authenticates, the minimum plan required, and which agent or layer consumes it.
Tool
Role
Auth method
Min plan
Used by
Xero
Invoicing and reconciliation source of truth
OAuth 2.0 (PKCE)
Starter
Chase Scheduler Agent, Payment Reconciliation Agent
Gmail
Outbound reminder delivery
OAuth 2.0 (Google identity)
Free / Google Workspace
Reminder Sender Agent
Stripe
Pay link generation and payment capture
API key (secret key + webhook signing secret)
Free (transaction fees apply)
Reminder Sender Agent
FullSpec Automation
Orchestration, scheduling, logging, and monitoring
API key (bearer token)
Standard ($145/month)
All agents, orchestration layer
02Per-tool integration detail
Xero
Connected via the Xero OAuth 2.0 API. Used to poll aged receivables, read invoice status, apply payments, and mark invoices reconciled. Two agents consume this integration: Chase Scheduler and Payment Reconciliation.
Auth method
OAuth 2.0 with PKCE. Redirect URI must be registered in the Xero developer portal. Access tokens expire after 30 minutes; refresh tokens are valid for 60 days and must be stored securely in the n8n credential store.
OAuth scopes
openid profile email accounting.transactions accounting.contacts.read offline_access
Base URL
https://api.xero.com/api.xro/2.0/
Key endpoints
GET /Invoices?where=Status=="AUTHORISED"&&DueDateString<={today} | GET /Invoices/{InvoiceID} | POST /Payments | PUT /Invoices/{InvoiceID}
Rate limits
60 API calls/minute per app (minute bucket); 5,000 calls/day per organisation. Minute-bucket exhaustion returns HTTP 429. Implement exponential backoff with initial 2-second delay, max 3 retries.
Pagination
Use page= query parameter; default page size 100. Iterate until response count < 100.
Constraints
Xero tenantId header (Xero-tenant-id) required on every request. Multi-org installs must store tenantId per connected organisation. Webhook events are not available on Starter; polling interval set to 15 minutes.
Webhook (optional)
Xero Partner App tier unlocks webhook delivery for payment events. Signing key verified via HMAC-SHA256 on X-Xero-Signature header.
// Poll input
GET /Invoices?where=Status=="AUTHORISED"&&DueDate<={today}&page=1
Headers: { Authorization: Bearer {access_token}, Xero-tenant-id: {tenantId} }
// Invoice object (key fields)
{ InvoiceID, InvoiceNumber, Contact.ContactID, Contact.EmailAddress,
AmountDue, AmountPaid, DueDate, Status, LineItems[] }
// Payment POST body
{ Invoice: { InvoiceID }, Account: { Code: "090" },
Date: "{payment_date}", Amount: {amount_paid} }Gmail
Connected via the Google Gmail API using OAuth 2.0. Used exclusively by the Reminder Sender Agent to dispatch staged reminder emails with invoice PDFs and Stripe pay links.
Auth method
OAuth 2.0 via Google Cloud Console. Credential type: Gmail OAuth2 API in n8n. Scopes granted at consent screen.
OAuth scopes
https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.readonly
Base URL
https://gmail.googleapis.com/gmail/v1/users/me/
Key endpoints
POST /messages/send (send reminder) | GET /messages?q=from:{contact_email} (reply detection)
Rate limits
250 quota units/second per user; sending is 1 unit/message. Daily send limit 2,000 messages (Workspace) or 500 (free). At ~120 invoices/month the daily limit is not a concern. HTTP 429 triggers 5-second backoff.
Message format
RFC 2822 MIME, base64url encoded. Attachments (invoice PDF) encoded as multipart/mixed. Content-Type: text/html for body.
Reply detection
Poll GET /messages?q=in:inbox+from:{contact_email}+after:{send_timestamp} every 15 minutes. A result count > 0 triggers human handoff.
Constraints
Sending from address must match the authenticated Google account. From header spoofing is not supported. Email template must be pre-approved and stored in FullSpec Automation config.
// Send input (n8n Gmail node)
{ to: contact_email, subject: "Invoice {InvoiceNumber} - Payment reminder",
html: reminder_html_body, attachments: [ { name: "invoice.pdf", data: pdf_base64 } ] }
// Reply poll query
GET /messages?q=in:inbox from:{contact_email} after:{unix_send_time}
// Output: message ID for activity log
{ id: "17abc1234def", threadId: "17abc1234def", labelIds: ["SENT"] }Stripe
Connected via the Stripe REST API using a secret API key. Used by the Reminder Sender Agent to generate a one-time Payment Link for each invoice, which is embedded in the reminder email.
Auth method
HTTP Basic Auth with secret key as username (password blank). Key stored in n8n credential store as Stripe API credential. Webhook endpoint registered in Stripe Dashboard for payment_intent.succeeded and checkout.session.completed events.
API version
2023-10-16 (pinned via Stripe-Version header on all requests)
Base URL
https://api.stripe.com/v1/
Key endpoints
POST /payment_links (create pay link per invoice) | POST /prices (create ad-hoc price for invoice amount) | GET /payment_intents/{id} (verify payment status) | Webhook: checkout.session.completed
Rate limits
100 read requests/second; 100 write requests/second in live mode. At ~120 invoices/month, peak usage is well below limits. HTTP 429 response includes Retry-After header; honour it before retrying.
Webhook verification
Stripe-Signature header verified using HMAC-SHA256 with the webhook signing secret. Reject any event where signature does not match. Idempotency enforced by checking event ID against processed-events log.
Constraints
Payment Links are single-currency. Currency must match the Xero invoice currency (default USD). Stripe account must be activated for live payments before go-live. Test mode keys must not be deployed to production.
// Create price (ad-hoc per invoice)
POST /v1/prices
{ unit_amount: amount_due_cents, currency: "usd",
product_data: { name: "Invoice {InvoiceNumber}" } }
// Create payment link
POST /v1/payment_links
{ line_items: [{ price: price_id, quantity: 1 }],
metadata: { invoice_id: xero_invoice_id, contact_id: xero_contact_id } }
// Webhook payload (checkout.session.completed, key fields)
{ id, type: "checkout.session.completed",
data.object: { payment_status: "paid", amount_total,
metadata: { invoice_id, contact_id } } }FullSpec Automation
The orchestration layer. Hosts and executes all n8n workflows, manages scheduling, stores credentials, maintains the activity log, and surfaces monitoring alerts. All inter-agent handoffs route through this platform.
Auth method
Bearer token in Authorization header for any external call into the FullSpec API. Internal n8n nodes communicate over localhost; no external auth required between nodes in the same workflow.
Scheduler
Cron-based polling every 15 minutes for Xero invoice checks. Reminder send times driven by a staged delay node (day 1, day 7, day 14 post-due-date configurable in workflow settings).
Activity log
Each send, match, and escalation event written to a FullSpec internal log table via HTTP Request node. Fields: event_type, invoice_id, contact_id, timestamp, outcome, agent_name.
Alerting
Workflow error hook configured to POST to a nominated Slack channel or email address on any unhandled exception. Separate monitor checks that the Chase Scheduler workflow has executed within the last 20 minutes.
Rate limits
No published hard limit on internal workflow executions. External API calls are rate-limited by the downstream tool (Xero, Gmail, Stripe); FullSpec Automation enforces per-tool wait nodes.
Constraints
Standard plan ($145/month) is required. Credential store is encrypted at rest (AES-256). Workflow exports (.json) must be version-controlled in the project Git repository.
// Trigger: Cron node fires every 15 min
-> HTTP Request: GET Xero /Invoices (overdue filter)
-> IF node: AmountDue > 0 AND DueDate < today
TRUE -> Chase Scheduler sub-workflow
FALSE -> No-op end
// Activity log write
POST https://api.fullspec.io/v1/log
Headers: { Authorization: Bearer {fs_api_key} }
{ event_type: "reminder_sent", invoice_id, contact_id,
timestamp: ISO8601, outcome: "success", agent_name: "Reminder Sender Agent" }Integration and API SpecPage 1 of 4
FS-DOC-05Technical
03Field mappings between tools
One mapping table is provided per agent handoff. Field names are shown in monospace. Source fields are read from the originating tool; destination fields are written to or consumed by the receiving tool or agent.
Handoff 1: Xero to Chase Scheduler Agent. The scheduler reads overdue invoice data from Xero and builds an internal chase record for each invoice.
Source tool
Source field
Destination
Destination field
Transform
Xero
InvoiceID
Chase Scheduler Agent
invoice_id
Direct map
Xero
InvoiceNumber
Chase Scheduler Agent
invoice_number
Direct map
Xero
Contact.ContactID
Chase Scheduler Agent
contact_id
Direct map
Xero
Contact.Name
Chase Scheduler Agent
contact_name
Direct map
Xero
Contact.EmailAddress
Chase Scheduler Agent
contact_email
Direct map
Xero
AmountDue
Chase Scheduler Agent
amount_due_usd
Float, 2 decimal places
Xero
DueDate
Chase Scheduler Agent
due_date
ISO 8601 date string
Xero
Status
Chase Scheduler Agent
invoice_status
AUTHORISED only passed through
Derived
today - DueDate (days)
Chase Scheduler Agent
days_overdue
Integer, computed at poll time
Handoff 2: Chase Scheduler Agent to Reminder Sender Agent. The scheduler passes the chase record plus a generated Stripe pay link into the sender.
Source tool
Source field
Destination
Destination field
Transform
Chase Scheduler Agent
invoice_id
Reminder Sender Agent
invoice_id
Direct map
Chase Scheduler Agent
invoice_number
Reminder Sender Agent
invoice_number
Direct map
Chase Scheduler Agent
contact_email
Reminder Sender Agent
to_address
Direct map
Chase Scheduler Agent
contact_name
Reminder Sender Agent
salutation_name
First name extracted via split(' ')[0]
Chase Scheduler Agent
amount_due_usd
Reminder Sender Agent
amount_due_display
Formatted as $X,XXX.XX
Chase Scheduler Agent
amount_due_usd
Stripe
unit_amount
Multiplied by 100 (cents), integer
Chase Scheduler Agent
due_date
Reminder Sender Agent
due_date_display
Reformatted as DD MMM YYYY
Chase Scheduler Agent
days_overdue
Reminder Sender Agent
reminder_sequence
1 if <7 days; 2 if 7-13; 3 if 14+
Stripe
url (payment link)
Reminder Sender Agent
pay_link_url
Injected into email HTML template
Xero
InvoiceID (PDF)
Reminder Sender Agent
attachment_pdf
GET /Invoices/{id}/pdf, base64 encoded
Handoff 3: Stripe webhook to Payment Reconciliation Agent. On payment capture, Stripe fires a webhook that triggers reconciliation back in Xero.
Source tool
Source field
Destination
Destination field
Transform
Stripe webhook
data.object.metadata.invoice_id
Payment Reconciliation Agent
xero_invoice_id
Direct map
Stripe webhook
data.object.metadata.contact_id
Payment Reconciliation Agent
xero_contact_id
Direct map
Stripe webhook
data.object.amount_total
Payment Reconciliation Agent
payment_amount_usd
Divided by 100 (dollars), float
Stripe webhook
data.object.created
Payment Reconciliation Agent
payment_date
Unix timestamp to ISO 8601 date
Stripe webhook
data.object.id
Payment Reconciliation Agent
stripe_session_id
Stored for idempotency check
Payment Reconciliation Agent
xero_invoice_id
Xero POST /Payments
Invoice.InvoiceID
Direct map
Payment Reconciliation Agent
payment_amount_usd
Xero POST /Payments
Amount
Float, 2 decimal places
Payment Reconciliation Agent
payment_date
Xero POST /Payments
Date
ISO 8601 date string
Payment Reconciliation Agent
reconciliation_status
FullSpec Activity Log
outcome
"full" or "partial" based on AmountDue comparison
Integration and API SpecPage 2 of 4
FS-DOC-05Technical
04Build stack and orchestration
All workflows are built and hosted inside FullSpec Automation (n8n-compatible runtime). The table below maps each component of the orchestration layer to its technical role and configuration notes.
Component
Technology
Role
Config notes
Workflow runtime
FullSpec Automation (n8n)
Executes all agent workflows and manages node routing
Standard plan; workflow export format .json; version-controlled in Git
Scheduler trigger
Cron node
Polls Xero for overdue invoices every 15 minutes
Expression: */15 * * * * (UTC). Offset by 2 min from the hour to avoid API burst
Chase Scheduler workflow
n8n sub-workflow
Reads overdue invoices, computes days_overdue, stages reminder sequence
Called by main cron trigger; returns prioritised chase list
Reminder Sender workflow
n8n sub-workflow
Generates Stripe pay link, renders email, sends via Gmail, logs send event
Triggered by Chase Scheduler output; Wait node enforces send-time staging
Payment webhook receiver
n8n Webhook node (POST)
Receives Stripe checkout.session.completed events
Path: /stripe-payment-hook; validates Stripe-Signature before processing
Payment Reconciliation workflow
n8n sub-workflow
Applies payment to Xero, detects partial, notifies team
Triggered by webhook receiver; reads xero_invoice_id from Stripe metadata
Credential store
FullSpec encrypted store
Holds all OAuth tokens and API keys
AES-256 at rest; tokens refreshed automatically before expiry
Activity log
FullSpec internal log table
Records every send, match, and escalation event
Queried by monitoring dashboard; retained 90 days
Error alerting
n8n Error Trigger node
Catches unhandled exceptions across all workflows
Posts alert payload to Slack webhook or nominated email
Git repository
GitHub (private)
Version control for all workflow JSON exports and config
Main branch protected; PR review required before merge to main
The n8n credential store entries below must be configured before any workflow is activated. Names must match exactly as referenced in the workflow JSON.
n8n credential store entries (FullSpec Automation credential manager)
// Xero OAuth2 API
Credential name : xero_oauth2
Type : OAuth2 API (Xero)
Client ID : {XERO_CLIENT_ID}
Client Secret : {XERO_CLIENT_SECRET}
Authorization URL: https://login.xero.com/identity/connect/authorize
Access Token URL : https://identity.xero.com/connect/token
Scope : openid profile email accounting.transactions accounting.contacts.read offline_access
Tenant ID : {XERO_TENANT_ID} // stored as additional field
// Gmail OAuth2 API
Credential name : gmail_oauth2
Type : Gmail OAuth2 API
Client ID : {GOOGLE_CLIENT_ID}
Client Secret : {GOOGLE_CLIENT_SECRET}
Scope : https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.readonly
// Stripe API
Credential name : stripe_api
Type : Stripe API
Secret Key : {STRIPE_SECRET_KEY} // sk_live_... in production
Webhook Secret : {STRIPE_WEBHOOK_SIGNING_SECRET} // whsec_...
API Version : 2023-10-16
// FullSpec Automation internal API
Credential name : fullspec_api
Type : Header Auth
Header Name : Authorization
Header Value : Bearer {FULLSPEC_API_KEY}
// Slack alerting (optional)
Credential name : slack_alert_webhook
Type : HTTP Header Auth
Header Name : Content-Type
Webhook URL : {SLACK_INCOMING_WEBHOOK_URL} // stored as node parameter05Error handling and retry logic
All errors are caught at the workflow level via n8n Error Trigger nodes. The table below defines the response for each failure class. HTTP 429 and 5xx errors follow exponential backoff. Business-logic failures route to the activity log and, where appropriate, trigger human escalation.
Error class
Trigger condition
HTTP code / signal
Retry strategy
Escalation
Xero token expired
Access token TTL exceeded (30 min)
HTTP 401
Auto-refresh via OAuth2 refresh token before retry; if refresh fails, alert and halt
Notify developer if refresh token also expired (>60 days inactive)
Xero rate limit
Minute bucket (60 calls/min) exhausted
HTTP 429
Exponential backoff: 2s, 4s, 8s; max 3 retries; then defer to next cron cycle
Log warning to activity log; no human alert unless 3 consecutive cycles fail
Xero daily quota
5,000 calls/day exceeded
HTTP 429 with Retry-After
Pause workflow until Retry-After timestamp; resume automatically
Alert process owner; no reminders sent until quota resets
Xero payment POST failure
Payment apply returns non-2xx
HTTP 400 / 500
Retry once after 10s; on second failure, log and queue for manual review
Slack/email alert to bookkeeper with invoice ID and error detail
Gmail send failure
Gmail API returns error on send
HTTP 500 / 403
Retry up to 2 times with 5s delay; on persistent failure, skip and log
Flag invoice as reminder-failed in activity log; alert bookkeeper daily digest
Gmail daily send cap
500 (free) or 2,000 (Workspace) message limit hit
HTTP 429
Queue remaining sends; distribute across next available send window
Alert if queue depth exceeds 50 unsent reminders
Stripe pay link creation failure
POST /payment_links returns non-2xx
HTTP 400 / 500
Retry once after 5s; if still failing, send reminder without pay link and flag
Log to activity log; alert developer if failure rate exceeds 5% in one hour
Stripe webhook signature invalid
HMAC-SHA256 mismatch on incoming event
N/A (validation logic)
Reject event immediately; do not process; log rejected event ID
Alert developer; investigate for potential replay attack
Stripe duplicate payment event
Event ID already in processed-events log
N/A (idempotency check)
Discard silently; no retry needed
No escalation; logged as duplicate in activity log
Partial payment detected
Stripe amount_total < Xero AmountDue
N/A (business logic)
Apply partial payment to Xero; mark invoice as partially paid; do not reconcile fully
Notify bookkeeper with remaining balance; schedule follow-up reminder
Xero invoice not found
GET /Invoices/{id} returns 404 or empty
HTTP 404
No retry; log as orphaned event; remove from chase list
Alert bookkeeper to verify invoice status manually in Xero
Workflow execution timeout
Sub-workflow exceeds 5-minute execution limit
FullSpec timeout signal
Terminate gracefully; log incomplete run with last processed invoice ID
Alert developer; investigate for runaway loop or API slowness
Integration and API SpecPage 3 of 4
FS-DOC-05Technical
06Versioning and change control
All workflow files, credential schemas, and field mapping definitions are version-controlled in a private GitHub repository. The process below governs how changes are proposed, reviewed, tested, and deployed to the live automation.
Workflow files
Git version control
All n8n workflow JSON exports committed to /workflows/ in the project repo. Filename convention: {agent_name}_v{major}.{minor}.json (e.g. chase_scheduler_v1.0.json).
Branching strategy
Feature branches
All changes developed on a named branch (e.g. feature/reminder-cadence-update). No direct commits to main. Pull request required for all merges.
PR review
Peer review mandatory
At minimum one developer review and one process-owner acknowledgement before merge. Reviewer confirms field mappings, credential references, and retry logic are unchanged unless explicitly in scope.
Version numbering
Semantic versioning (major.minor)
Major version increments on breaking changes to field mappings or auth flows. Minor version increments on logic or cadence changes. Patch reserved for hotfixes.
Change log
CHANGELOG.md in repo root
Every merged PR appended to CHANGELOG.md with: version, date, description, author, and any downstream impact (e.g. Xero scope change requires re-auth).
Credential changes
Separate rotation procedure
API key or OAuth token rotation documented in /docs/credential-rotation.md. Rotated credentials tested in staging workflow before replacing production values in FullSpec credential store.
Staging environment
Separate FullSpec workspace
A staging workspace mirrors production. All workflow changes tested against Xero Demo Company and Stripe test mode before promotion to production.
Deployment to production
Manual promotion
Developer exports tested workflow JSON from staging, creates a PR to main, obtains review, then imports to production FullSpec workspace. Cron trigger paused during import.
Rollback
Previous workflow version import
If a production issue is detected post-deployment, the previous workflow JSON (tagged in Git) is re-imported immediately. Rollback target is the last stable tag.
API version pinning
Explicit version headers
Xero API version is not pinned via header (Xero manages versioning internally). Stripe API version pinned to 2023-10-16 via Stripe-Version header on all requests. Any version upgrade treated as a major change.
Reminder cadence config
Workflow-level parameters
Reminder sequence thresholds (7 days, 14 days) stored as workflow-level variables, not hardcoded. Changes to cadence require a minor version increment and PR, but do not require re-auth or field mapping updates.
Documentation sync
Docs updated with each PR
This Integration and API Spec document, the Developer Handover Pack, and the SOP must be updated in the same PR as any workflow change that affects endpoints, field mappings, or auth flows.
Any change to OAuth scopes for Xero or Gmail requires the authenticated user to re-authorise the connection. Schedule scope changes during a low-volume period and notify the process owner at least 48 hours in advance.
Integration and API SpecPage 4 of 4