This document provides detailed information about the Xero CFO Assistant Agent API endpoints, request/response formats, and authentication requirements.
All API endpoints (except authentication endpoints) require authentication using JWT tokens.
Include the JWT token in the Authorization header:
Authorization: Bearer <your_jwt_token>
For n8n integration endpoints, you can also use API key authentication:
X-API-Key: <your_api_key>
All API responses follow a standard format:
{
"success": true|false,
"data": {}, // Response data (when success is true)
"message": "", // Success or error message
"errors": [] // Validation errors (when applicable)
}POST /api/auth/register
Request body:
{
"email": "user@example.com",
"password": "securepassword",
"firstName": "John",
"lastName": "Doe"
}Response:
{
"success": true,
"data": {
"userId": "user123",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
},
"message": "User registered successfully"
}POST /api/auth/login
Request body:
{
"email": "user@example.com",
"password": "securepassword"
}Response:
{
"success": true,
"data": {
"token": "jwt_token_here",
"user": {
"userId": "user123",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
}
},
"message": "Login successful"
}GET /api/auth/xero
This endpoint redirects the user to the Xero authorization page.
GET /api/auth/xero/callback
This endpoint handles the callback from Xero after authorization.
GET /api/auth/profile
Response:
{
"success": true,
"data": {
"userId": "user123",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"role": "user",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}PUT /api/auth/profile
Request body:
{
"firstName": "John",
"lastName": "Smith",
"currentPassword": "currentpassword",
"newPassword": "newpassword"
}Response:
{
"success": true,
"message": "Profile updated successfully"
}GET /api/xero/tenants
Response:
{
"success": true,
"data": [
{
"id": "tenant123",
"name": "My Company",
"isActive": true
},
{
"id": "tenant456",
"name": "Another Company",
"isActive": false
}
]
}PUT /api/xero/tenants/:tenantId/active
Response:
{
"success": true,
"message": "Active tenant updated successfully"
}GET /api/xero/contacts
Query parameters:
page(optional): Page numberpageSize(optional): Page sizewhere(optional): Filter criteriaorder(optional): Sort order
Response:
{
"success": true,
"data": {
"contacts": [
{
"contactID": "contact123",
"name": "ABC Ltd",
"emailAddress": "info@abcltd.com",
"phones": [...],
"addresses": [...]
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 45
}
}
}GET /api/xero/accounts
Query parameters:
page(optional): Page numberpageSize(optional): Page sizewhere(optional): Filter criteriaorder(optional): Sort order
Response:
{
"success": true,
"data": {
"accounts": [
{
"accountID": "account123",
"code": "1000",
"name": "Sales",
"type": "REVENUE",
"status": "ACTIVE"
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 3,
"totalItems": 25
}
}
}GET /api/xero/invoices
Query parameters:
page(optional): Page numberpageSize(optional): Page sizewhere(optional): Filter criteriaorder(optional): Sort orderstatus(optional): Invoice status
Response:
{
"success": true,
"data": {
"invoices": [
{
"invoiceID": "invoice123",
"type": "ACCREC",
"contact": {
"contactID": "contact123",
"name": "ABC Ltd"
},
"date": "2023-01-01",
"dueDate": "2023-01-15",
"status": "AUTHORISED",
"lineItems": [...],
"total": 100.00,
"amountDue": 100.00,
"amountPaid": 0.00
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 45
}
}
}GET /api/xero/bills
Query parameters:
page(optional): Page numberpageSize(optional): Page sizewhere(optional): Filter criteriaorder(optional): Sort orderstatus(optional): Bill status
Response:
{
"success": true,
"data": {
"bills": [
{
"invoiceID": "bill123",
"type": "ACCPAY",
"contact": {
"contactID": "contact123",
"name": "Supplier Ltd"
},
"date": "2023-01-01",
"dueDate": "2023-01-15",
"status": "AUTHORISED",
"lineItems": [...],
"total": 100.00,
"amountDue": 100.00,
"amountPaid": 0.00
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 45
}
}
}GET /api/xero/bank-transactions
Query parameters:
page(optional): Page numberpageSize(optional): Page sizewhere(optional): Filter criteriaorder(optional): Sort orderbankAccountId(optional): Bank account IDfrom(optional): Start dateto(optional): End date
Response:
{
"success": true,
"data": {
"bankTransactions": [
{
"bankTransactionID": "transaction123",
"type": "RECEIVE",
"date": "2023-01-01",
"status": "AUTHORISED",
"bankAccount": {
"accountID": "account123",
"code": "1000",
"name": "Main Account"
},
"amount": 100.00,
"reference": "Payment for invoice #123",
"isReconciled": false
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 45
}
}
}POST /api/bookkeeping/reconcile
Request body:
{
"bankTransactionId": "transaction123",
"invoiceId": "invoice123"
}Response:
{
"success": true,
"data": {
"reconciled": true,
"bankTransaction": {
"bankTransactionID": "transaction123",
"isReconciled": true
},
"invoice": {
"invoiceID": "invoice123",
"status": "PAID",
"amountDue": 0.00,
"amountPaid": 100.00
}
},
"message": "Transaction reconciled successfully"
}POST /api/bookkeeping/categorize
Request body:
{
"bankTransactionId": "transaction123",
"categoryId": "category123"
}Response:
{
"success": true,
"data": {
"transaction": {
"transactionId": "transaction123",
"categoryId": "category123",
"categoryName": "Office Supplies"
}
},
"message": "Transaction categorized successfully"
}GET /api/bookkeeping/categories
Response:
{
"success": true,
"data": {
"categories": [
{
"id": "category123",
"name": "Office Supplies",
"description": "Office supplies and equipment"
},
{
"id": "category456",
"name": "Rent",
"description": "Rent and lease payments"
}
]
}
}POST /api/bookkeeping/categories
Request body:
{
"name": "Marketing",
"description": "Marketing and advertising expenses"
}Response:
{
"success": true,
"data": {
"category": {
"id": "category789",
"name": "Marketing",
"description": "Marketing and advertising expenses"
}
},
"message": "Category created successfully"
}GET /api/bookkeeping/rules
Response:
{
"success": true,
"data": {
"rules": [
{
"id": "rule123",
"name": "Office Supplies Rule",
"pattern": "Staples|Office Depot",
"categoryId": "category123",
"isActive": true
}
]
}
}POST /api/bookkeeping/rules
Request body:
{
"name": "Marketing Rule",
"pattern": "Facebook|Google Ads|Twitter",
"categoryId": "category789",
"isActive": true
}Response:
{
"success": true,
"data": {
"rule": {
"id": "rule456",
"name": "Marketing Rule",
"pattern": "Facebook|Google Ads|Twitter",
"categoryId": "category789",
"isActive": true
}
},
"message": "Rule created successfully"
}GET /api/analysis/kpis
Query parameters:
months(optional): Number of months to analyze (default: 3)compareWithPrevious(optional): Whether to compare with previous period (default: true)
Response:
{
"success": true,
"data": {
"healthScore": 85,
"profitability": {
"grossProfitMargin": {
"current": 0.45,
"previous": 0.42,
"change": 0.03
},
"netProfitMargin": {
"current": 0.15,
"previous": 0.12,
"change": 0.03
}
},
"liquidity": {
"currentRatio": {
"current": 2.5,
"previous": 2.2,
"change": 0.3
},
"quickRatio": {
"current": 1.8,
"previous": 1.5,
"change": 0.3
}
},
"efficiency": {
"daysReceivablesOutstanding": {
"current": 35,
"previous": 40,
"change": -5
},
"daysPayablesOutstanding": {
"current": 30,
"previous": 28,
"change": 2
}
}
}
}GET /api/analysis/cash-flow/forecast
Query parameters:
days(optional): Number of days to forecast (default: 90)
Response:
{
"success": true,
"data": {
"startingBalance": 10000.00,
"netCashFlow": 5000.00,
"lowestBalance": 8000.00,
"lowestBalanceDate": "2023-02-15",
"monthlyForecasts": [
{
"month": 1,
"year": 2023,
"totalInflow": 20000.00,
"totalOutflow": 15000.00,
"netCashFlow": 5000.00,
"endingBalance": 15000.00
},
{
"month": 2,
"year": 2023,
"totalInflow": 18000.00,
"totalOutflow": 16000.00,
"netCashFlow": 2000.00,
"endingBalance": 17000.00
},
{
"month": 3,
"year": 2023,
"totalInflow": 22000.00,
"totalOutflow": 17000.00,
"netCashFlow": 5000.00,
"endingBalance": 22000.00
}
],
"inflows": [...],
"outflows": [...]
}
}GET /api/analysis/anomalies
Query parameters:
months(optional): Number of months to analyze (default: 1)threshold(optional): Anomaly detection threshold (default: 0.2)
Response:
{
"success": true,
"data": {
"anomalies": [
{
"id": "anomaly123",
"type": "UNUSUAL_EXPENSE",
"description": "Unusually high expense in Office Supplies category",
"severity": "MEDIUM",
"date": "2023-01-15",
"amount": 5000.00,
"expectedAmount": 1000.00,
"category": "Office Supplies"
},
{
"id": "anomaly456",
"type": "LATE_PAYMENT",
"description": "Customer ABC Ltd has paid 30 days late",
"severity": "HIGH",
"date": "2023-01-20",
"amount": 10000.00,
"contactId": "contact123",
"contactName": "ABC Ltd"
}
]
}
}GET /api/analysis/reports
Query parameters:
page(optional): Page numberpageSize(optional): Page sizetype(optional): Report type
Response:
{
"success": true,
"data": {
"reports": [
{
"id": "report123",
"type": "MONTHLY",
"title": "Monthly Financial Report - January 2023",
"createdAt": "2023-02-01T00:00:00.000Z",
"period": {
"fromDate": "2023-01-01",
"toDate": "2023-01-31"
}
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 45
}
}
}GET /api/analysis/reports/:id
Response:
{
"success": true,
"data": {
"report": {
"id": "report123",
"type": "MONTHLY",
"title": "Monthly Financial Report - January 2023",
"createdAt": "2023-02-01T00:00:00.000Z",
"period": {
"fromDate": "2023-01-01",
"toDate": "2023-01-31"
},
"content": "# Monthly Financial Report: January 2023\n\n## Executive Summary\n\nFinancial Health Score: 85/100 (Good)\n\nGross Profit Margin: 45.0%\n\nCurrent Ratio: 2.5\n\nProjected Cash Position (90 days): $22,000.00\n\n...",
"kpis": {...},
"cashFlow": {...},
"anomalies": [...]
}
}
}GET /api/n8n/kpis
Query parameters:
months(optional): Number of months to analyze (default: 3)compareWithPrevious(optional): Whether to compare with previous period (default: true)
Authentication:
- JWT token or API key
Response: Same as /api/analysis/kpis
GET /api/n8n/cash-flow/forecast
Query parameters:
days(optional): Number of days to forecast (default: 90)
Authentication:
- JWT token or API key
Response: Same as /api/analysis/cash-flow/forecast
GET /api/n8n/cash-flow/issues
Query parameters:
days(optional): Number of days to check (default: 90)threshold(optional): Minimum severity level (default: "MEDIUM")
Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"issues": [
{
"id": "issue123",
"type": "NEGATIVE_BALANCE",
"description": "Projected negative balance on 2023-02-15",
"severity": "HIGH",
"date": "2023-02-15",
"amount": -2000.00
},
{
"id": "issue456",
"type": "LOW_BALANCE",
"description": "Projected low balance (below 5000) on 2023-03-01",
"severity": "MEDIUM",
"date": "2023-03-01",
"amount": 3000.00
}
]
}
}GET /api/n8n/anomalies
Query parameters:
months(optional): Number of months to analyze (default: 1)threshold(optional): Anomaly detection threshold (default: 0.2)
Authentication:
- JWT token or API key
Response: Same as /api/analysis/anomalies
POST /api/n8n/transactions/sync
Request body:
{
"fromDate": "2023-01-01",
"toDate": "2023-01-31"
}Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"syncedTransactions": 45,
"newTransactions": 10,
"updatedTransactions": 5,
"categorizedTransactions": 8
},
"message": "Transactions synced successfully"
}GET /api/n8n/transactions/:transactionId/matches
Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"transaction": {
"id": "transaction123",
"date": "2023-01-15",
"amount": 100.00,
"description": "Payment from ABC Ltd"
},
"matches": [
{
"id": "invoice123",
"type": "INVOICE",
"date": "2023-01-01",
"dueDate": "2023-01-15",
"amount": 100.00,
"reference": "INV-001",
"contact": {
"id": "contact123",
"name": "ABC Ltd"
},
"matchScore": 0.95
}
]
}
}POST /api/n8n/transactions/categorize
Request body:
{
"transactions": [
{
"transactionId": "transaction123",
"categoryId": "category123"
},
{
"transactionId": "transaction456",
"categoryId": "category456"
}
]
}Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"categorizedTransactions": 2,
"transactions": [
{
"transactionId": "transaction123",
"categoryId": "category123",
"categoryName": "Office Supplies"
},
{
"transactionId": "transaction456",
"categoryId": "category456",
"categoryName": "Rent"
}
]
},
"message": "Transactions categorized successfully"
}GET /api/n8n/invoices/overdue
Query parameters:
daysOverdue(optional): Minimum days overdue (default: 1)maxResults(optional): Maximum number of results (default: 100)
Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"overdueInvoices": [
{
"invoiceId": "invoice123",
"contactId": "contact123",
"contactName": "ABC Ltd",
"contactEmail": "info@abcltd.com",
"amount": 100.00,
"dueDate": "2023-01-15",
"daysOverdue": 10,
"reference": "INV-001"
}
]
}
}GET /api/n8n/contacts/:contactId/payment-reminder
Query parameters:
template(optional): Reminder template (default: "standard")
Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"contact": {
"id": "contact123",
"name": "ABC Ltd",
"email": "info@abcltd.com"
},
"overdueInvoices": [...],
"totalAmount": 500.00,
"reminderSubject": "Payment Reminder - ABC Ltd",
"reminderBody": "Dear ABC Ltd,\n\nThis is a friendly reminder that you have 5 overdue invoices totaling $500.00. Please arrange payment at your earliest convenience.\n\n..."
}
}POST /api/n8n/contacts/:contactId/payment-reminder
Request body:
{
"template": "standard",
"subject": "Payment Reminder - ABC Ltd",
"body": "Dear ABC Ltd,\n\nThis is a friendly reminder that you have 5 overdue invoices totaling $500.00. Please arrange payment at your earliest convenience.\n\n...",
"sendEmail": true
}Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"contact": {
"id": "contact123",
"name": "ABC Ltd",
"email": "info@abcltd.com"
},
"reminderSent": true,
"sentAt": "2023-01-25T12:00:00.000Z"
},
"message": "Payment reminder sent successfully"
}GET /api/n8n/bills/upcoming
Query parameters:
days(optional): Number of days to look ahead (default: 30)maxResults(optional): Maximum number of results (default: 100)
Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"upcomingBills": [
{
"billId": "bill123",
"contactId": "contact456",
"contactName": "Supplier Ltd",
"amount": 200.00,
"dueDate": "2023-02-15",
"daysUntilDue": 20,
"reference": "BILL-001"
}
],
"totalAmount": 200.00
}
}GET /api/n8n/bills/payment-schedule
Query parameters:
days(optional): Number of days to look ahead (default: 90)
Authentication:
- JWT token or API key
Response:
{
"success": true,
"data": {
"schedule": [
{
"date": "2023-02-15",
"bills": [
{
"billId": "bill123",
"contactName": "Supplier Ltd",
"amount": 200.00,
"reference": "BILL-001"
}
],
"totalAmount": 200.00
},
{
"date": "2023-03-01",
"bills": [
{
"billId": "bill456",
"contactName": "Another Supplier",
"amount": 300.00,
"reference": "BILL-002"
}
],
"totalAmount": 300.00
}
],
"totalAmount": 500.00
}
}POST /api/webhooks/xero
This endpoint is called by Xero when events occur in the connected Xero account.
POST /api/webhooks/register
Request body:
{
"name": "Invoice Paid Webhook",
"url": "https://example.com/webhook",
"events": ["invoice.paid", "invoice.updated"],
"isActive": true
}Response:
{
"success": true,
"data": {
"webhook": {
"id": "webhook123",
"name": "Invoice Paid Webhook",
"url": "https://example.com/webhook",
"events": ["invoice.paid", "invoice.updated"],
"isActive": true,
"secret": "webhook_secret_here"
}
},
"message": "Webhook registered successfully"
}GET /api/webhooks/list
Response:
{
"success": true,
"data": {
"webhooks": [
{
"id": "webhook123",
"name": "Invoice Paid Webhook",
"url": "https://example.com/webhook",
"events": ["invoice.paid", "invoice.updated"],
"isActive": true
}
]
}
}PUT /api/webhooks/:webhookId
Request body:
{
"name": "Updated Webhook Name",
"url": "https://example.com/new-webhook",
"events": ["invoice.paid"],
"isActive": true
}Response:
{
"success": true,
"data": {
"webhook": {
"id": "webhook123",
"name": "Updated Webhook Name",
"url": "https://example.com/new-webhook",
"events": ["invoice.paid"],
"isActive": true
}
},
"message": "Webhook updated successfully"
}DELETE /api/webhooks/:webhookId
Response:
{
"success": true,
"message": "Webhook deleted successfully"
}POST /api/webhooks/:webhookId/regenerate-secret
Response:
{
"success": true,
"data": {
"webhook": {
"id": "webhook123",
"secret": "new_webhook_secret_here"
}
},
"message": "Webhook secret regenerated successfully"
}POST /api/webhooks/:webhookId/test
Response:
{
"success": true,
"data": {
"testResult": {
"success": true,
"statusCode": 200,
"response": "Webhook received"
}
},
"message": "Webhook test completed successfully"
}The API uses standard HTTP status codes to indicate the success or failure of a request:
200 OK: The request was successful201 Created: The resource was successfully created400 Bad Request: The request was invalid or cannot be served401 Unauthorized: Authentication is required or failed403 Forbidden: The authenticated user does not have permission404 Not Found: The requested resource does not exist422 Unprocessable Entity: The request was well-formed but contains semantic errors429 Too Many Requests: Rate limit exceeded500 Internal Server Error: An error occurred on the server
The API implements rate limiting to prevent abuse:
- Standard endpoints: 100 requests per 15 minutes
- Authentication endpoints: 10 requests per hour
- n8n integration endpoints: 60 requests per minute
When a rate limit is exceeded, the API returns a 429 Too Many Requests response with a Retry-After header indicating when the client can retry the request.
Endpoints that return lists of resources support pagination using the following query parameters:
page: Page number (1-based)pageSize: Number of items per page
The response includes pagination information:
{
"pagination": {
"page": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 45
}
}Many endpoints support filtering and sorting using the following query parameters:
where: Filter criteria (e.g.,Status=="DRAFT")order: Sort order (e.g.,DueDate ASC)
The API version is included in the URL path:
/api/v1/...
The current version is v1.
For API support, contact support@xero-cfo-assistant.com or open an issue on GitHub.