Back to Software Licence Management

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

Software Licence Management Automation

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

This document is the authoritative technical reference for every integration point in the Software Licence Management automation. It covers tool authentication, required API scopes, webhook and trigger configuration, field mappings between agents, credential store layout, orchestration design, and error handling. The FullSpec team uses this spec to build and test each connection. Nothing in this document is optional: every scope, field name, and retry rule reflects a deliberate decision about how the system behaves under both normal and failure conditions.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agents
Orchestration layer
Schedules workflows, routes data between tools, manages retries and credential store
Internal (platform credential store)
Paid tier with API steps and scheduled triggers
All
Microsoft 365
Source of active user list and assigned licence data
OAuth 2.0 (service principal / application permissions)
Microsoft 365 Business Basic or above; Global Admin or Licence Admin role required
Agent 1 (Licence Discovery Agent)
Notion
Central licence register: read for comparison, write for decisions and status updates
Notion Internal Integration Token
Notion Plus or above (for API access and advanced database features)
Agent 1, Agent 2 (Licence Discovery Agent, Renewal Coordination Agent)
Slack
Sends renewal alerts to tool owners; delivers daily digest to IT manager; captures owner responses
OAuth 2.0 (Slack app with Bot Token)
Slack Pro or above (for workflow steps and message history access)
Agent 2 (Renewal Coordination Agent)
Xero
Receives consolidated finance notes for licence changes and cancellations
OAuth 2.0 (Xero connected app, PKCE flow)
Xero Starter or above; Adviser or Standard user role
Agent 2 (Renewal Coordination Agent)
Before you connect anything: create a sandbox or developer tenant for every tool that supports one (Microsoft 365 developer tenant, Notion test workspace, Xero demo company, Slack dev app). Validate all auth flows, scope grants, and data reads in the sandbox environment before any production credential is entered into the credential store. Do not use production credentials during initial build or testing.
Integration and API SpecPage 1 of 4
FS-DOC-05Technical

02Per-tool integration detail

Microsoft 365

Queried by the Licence Discovery Agent (Agent 1) on a daily schedule to retrieve the current list of all user accounts (active and disabled) and their assigned licence SKUs. The integration uses application-level permissions so no interactive user sign-in is required at runtime.

Auth method
OAuth 2.0, client credentials grant (application permissions). Register an Azure AD app registration. Store tenant_id, client_id, and client_secret in the credential store. Token endpoint: https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
Required scopes
User.Read.All, Directory.Read.All, Organization.Read.All, LicenseAssignment.ReadWrite.All (ReadWrite required only if automated seat removal is later enabled; read-only builds use .Read.All variants)
Webhook / trigger
No webhook used. The orchestration layer polls the Microsoft Graph API on a daily schedule at 07:00 in the configured timezone. Endpoint: GET https://graph.microsoft.com/v1.0/users?$select=id,displayName,userPrincipalName,accountEnabled,assignedLicenses&$top=999. Use $skipToken pagination for tenants with more than 999 users.
Required configuration
Azure AD app registration must have admin consent granted for all application permissions listed above. Store the following in the credential store (never hardcode): MS365_TENANT_ID, MS365_CLIENT_ID, MS365_CLIENT_SECRET. The $select query parameter must include assignedLicenses to capture SKU data.
Rate limits
Microsoft Graph enforces a per-app throttle of approximately 10,000 requests per 10 minutes per tenant. At current volume (approximately 35 licences, estimated user list under 200 accounts), a single daily poll generates fewer than 5 requests. Throttling logic is not required at current volume but the orchestration layer must handle HTTP 429 responses with exponential backoff (see Section 05).
Constraints
Application permissions require explicit admin consent; a Global Admin must approve the app registration. Licence deprovisioning (write-back) is not enabled by default in this build. If enabled in a future phase, the LicenseAssignment.ReadWrite.All scope must be re-consented and the security implications reviewed with the process owner.
// Output (to Licence Discovery Agent logic)
users[]: { id, displayName, userPrincipalName, accountEnabled, assignedLicenses[{ skuId, skuPartNumber }] }
// Pagination token
@odata.nextLink: string | null
Notion

Used by both agents. Agent 1 reads the licence register to compare against live Microsoft 365 data and writes flagged anomalies. Agent 2 reads flagged records, writes owner decisions back, and updates status fields and next review dates.

Auth method
Notion Internal Integration Token (Bearer token). Create a Notion integration at https://www.notion.so/my-integrations. The integration must be shared with every database page it needs to access. Store the token as NOTION_API_TOKEN in the credential store.
Required scopes
Read content, Update content, Insert content (set at integration creation). No OAuth user-level scopes are required for an internal integration. The integration must be added as a connection on: the Licence Register database, the Flagged Anomalies database (or view), and the Renewal Decisions log database.
Webhook / trigger
Notion does not provide native outbound webhooks. Agent 2 is triggered by the orchestration layer polling a Notion database filter for records where Status = 'Flagged' and Assigned_Agent is null. Poll interval: every 5 minutes after Agent 1 completes its daily run. Store the Notion database IDs as NOTION_LICENCE_DB_ID and NOTION_DECISIONS_DB_ID in the credential store.
Required configuration
Licence Register database must contain the following properties (exact names): Tool_Name (title), Vendor (rich_text), Renewal_Date (date), Seat_Count (number), Monthly_Cost_USD (number), Annual_Cost_USD (number), Assigned_Owner_Slack_ID (rich_text), Status (select: Active, Flagged, Pending_Decision, Cancelled, Renewed), Last_Reviewed (date), Next_Review_Date (date), Assigned_Agent (rich_text), Decision (select: Renew, Reduce, Cancel, Defer), Decision_Notes (rich_text). All database IDs stored in credential store, never hardcoded.
Rate limits
Notion API enforces a rate limit of 3 requests per second per integration. At current volume (35 licences, up to 8 renewals per month), peak usage is approximately 40 to 50 API calls per daily run. No throttling adapter is required, but the orchestration layer must insert a 350 ms delay between sequential page-update calls to stay within limits.
Constraints
Notion database property names are case-sensitive and must match exactly as specified above. If the integration is removed from a shared database, all reads and writes to that database will fail silently unless error handling checks for HTTP 403 responses. The integration token does not expire but must be rotated if compromised.
// Input (Agent 1 read)
GET /v1/databases/{NOTION_LICENCE_DB_ID}/query -> filter: { Renewal_Date within 60 days OR Status = 'Active' }
// Input (Agent 2 read)
GET /v1/databases/{NOTION_LICENCE_DB_ID}/query -> filter: { Status = 'Flagged' }
// Output (Agent 1 write)
PATCH /v1/pages/{page_id} -> { Status: 'Flagged', Last_Reviewed: today, Assigned_Agent: 'Renewal_Coordination_Agent' }
// Output (Agent 2 write)
PATCH /v1/pages/{page_id} -> { Decision, Decision_Notes, Status: 'Pending_Decision' | 'Renewed' | 'Cancelled', Next_Review_Date }
Slack

Used by Agent 2 (Renewal Coordination Agent) to send structured renewal alert messages to individual tool owners and to deliver the daily digest to the IT manager. Response capture from tool owners is handled via Slack interactive message callbacks or a linked external form where the owner is outside the workspace.

Auth method
OAuth 2.0, Slack app with Bot Token (xoxb-). Create a Slack app at https://api.slack.com/apps. Install to workspace and store the bot token as SLACK_BOT_TOKEN in the credential store. Store the IT manager's Slack user ID as SLACK_IT_MANAGER_USER_ID and the digest channel ID as SLACK_DIGEST_CHANNEL_ID.
Required scopes
chat:write, chat:write.public, users:read, users:read.email, channels:read, im:write, reactions:read (for response tracking). If interactive message buttons are used for owner responses: commands and interactivity must be enabled in the app manifest, and the Request URL for interactivity must point to the orchestration layer's webhook receiver endpoint.
Webhook / trigger
Outbound: the orchestration layer calls POST https://slack.com/api/chat.postMessage with the bot token. Inbound (response capture): enable Interactivity in the Slack app and set the Request URL to the orchestration layer's inbound webhook endpoint. Validate all inbound payloads using the Slack signing secret (stored as SLACK_SIGNING_SECRET in the credential store). Verify the X-Slack-Signature header on every inbound request before processing.
Required configuration
Renewal alert message template must be stored as a Slack Block Kit JSON template in the credential store or configuration layer (not hardcoded in workflow steps). The template must include: tool name, renewal date, current seat count, annual cost, and three action buttons (Renew / Reduce / Cancel). Fallback form URL (SLACK_FALLBACK_FORM_URL) must be stored for owners outside the Slack workspace. IT manager digest channel ID stored as SLACK_DIGEST_CHANNEL_ID.
Rate limits
Slack enforces a Tier 3 rate limit of approximately 50 calls per minute for chat.postMessage. At current volume (up to 8 renewal alerts per day plus 1 digest), peak usage is well under 10 calls per run. No throttling required at current volume. The orchestration layer must handle HTTP 429 with the Retry-After header value.
Constraints
Tool owners must be active members of the connected Slack workspace for direct message delivery. Owners outside the workspace must receive the fallback form link instead. Interactive message callbacks expire after 30 minutes by default; if no response is received, the orchestration layer must re-queue the alert and notify the IT manager. Message payload must not contain PII beyond what is necessary for the renewal decision.
// Outbound: renewal alert
POST /api/chat.postMessage -> { channel: owner_slack_id, blocks: renewal_alert_template, text: fallback_text }
// Outbound: daily digest
POST /api/chat.postMessage -> { channel: SLACK_DIGEST_CHANNEL_ID, blocks: digest_summary_template }
// Inbound: owner response callback
POST {orchestration_webhook_endpoint} <- { payload: { actions[{ action_id, value }], user.id, message.ts, response_url } }
// Validate
X-Slack-Signature: v0=HMAC-SHA256(SLACK_SIGNING_SECRET, v0:{timestamp}:{body})
Xero

Used by Agent 2 to post a consolidated finance note to the relevant Xero contact or bill record after renewal decisions are collected. This gives the finance team a structured record of licence changes without requiring a separate email or manual entry.

Auth method
OAuth 2.0, authorization code grant with PKCE. Register a connected app at https://developer.xero.com/app/manage. Store XERO_CLIENT_ID, XERO_CLIENT_SECRET, XERO_TENANT_ID, and the refresh token (XERO_REFRESH_TOKEN) in the credential store. Tokens expire after 30 minutes; the orchestration layer must refresh automatically using the refresh token before each run.
Required scopes
accounting.contacts.read, accounting.transactions.read, accounting.transactions, accounting.attachments (for attaching finance note PDFs if required). Minimum viable scope set for note-only posting: accounting.transactions.
Webhook / trigger
No inbound webhook from Xero is used in this build. The orchestration layer posts to Xero after Agent 2 has written decisions back to Notion. Endpoint: POST https://api.xero.com/api.xro/2.0/ManualJournals or POST to /Contacts/{ContactID}/Attachments for note attachment. The Xero tenant ID must be included in the Xero-Tenant-Id header on every request.
Required configuration
The Xero contact ID for the IT or Operations cost centre must be stored as XERO_IT_CONTACT_ID in the credential store. Finance note template (plain text or PDF) must be defined in the configuration layer. The note must include: list of tools with decisions (renew, reduce, cancel), seat count changes, estimated monthly cost delta, and the date of the IT manager's review. Do not hardcode contact IDs or account codes.
Rate limits
Xero enforces a limit of 60 API calls per minute and 5,000 calls per day per connected app. At current volume (one finance note post per daily run, up to 8 line items), usage is negligible. No throttling adapter is required. The orchestration layer must handle HTTP 429 and HTTP 503 with exponential backoff.
Constraints
The Xero refresh token expires after 60 days of inactivity. The orchestration layer must perform a token refresh at least once every 30 days regardless of run activity. If the refresh token is invalid, the integration must alert the IT manager via Slack before the next scheduled run. Xero does not support free-text notes on transactions in all account types; confirm the note attachment approach with the finance contact before go-live.
// Output: finance note post
POST https://api.xero.com/api.xro/2.0/Contacts/{XERO_IT_CONTACT_ID}/Attachments
Headers: { Xero-Tenant-Id: XERO_TENANT_ID, Authorization: Bearer {access_token}, Content-Type: application/pdf }
Body: { filename: 'licence_change_note_{YYYY-MM-DD}.pdf', content: base64_encoded_note }
// Token refresh
POST https://identity.xero.com/connect/token
Body: { grant_type: refresh_token, refresh_token: XERO_REFRESH_TOKEN, client_id: XERO_CLIENT_ID, client_secret: XERO_CLIENT_SECRET }
Integration and API SpecPage 2 of 4
FS-DOC-05Technical

03Field mappings between tools

The tables below define every field translation across agent handoffs. Field names are exact and case-sensitive. The orchestration layer is responsible for all transformation logic between source and destination formats.

Agent 1 handoff: Microsoft 365 to Notion (Licence Discovery Agent writes mismatch and renewal flag data to the licence register)

Source tool
Source field
Destination tool
Destination field
Transformation
Microsoft 365
`users[].id`
Notion
`MS365_User_ID` (rich_text)
Direct string copy; stored for dedup
Microsoft 365
`users[].displayName`
Notion
`Assigned_Owner_Display_Name` (rich_text)
Direct string copy
Microsoft 365
`users[].userPrincipalName`
Notion
`Assigned_Owner_Email` (rich_text)
Direct string copy; used for Slack lookup
Microsoft 365
`users[].accountEnabled`
Notion
`User_Active` (checkbox)
Boolean direct map: true = checked
Microsoft 365
`users[].assignedLicenses[].skuPartNumber`
Notion
`Tool_Name` (title)
SKU-to-friendly-name lookup table applied; fallback to raw skuPartNumber
Microsoft 365
`users[].assignedLicenses[].skuId`
Notion
`SKU_ID` (rich_text)
Direct string copy; stored for future deprovisioning reference
Notion (computed)
`Renewal_Date` vs today + 60 days
Notion
`Status` (select)
If Renewal_Date within 60 days: set Status = 'Flagged'; else no change
Notion (computed)
`User_Active = false AND Status = 'Active'`
Notion
`Status` (select)
Set Status = 'Flagged'; set Decision_Notes = 'Inactive user still holds licence'
Orchestration
`run_timestamp`
Notion
`Last_Reviewed` (date)
ISO 8601 date of current run

Agent 1 to Agent 2 handoff: Notion flagged records consumed by the Renewal Coordination Agent

Source tool
Source field
Destination tool
Destination field
Transformation
Notion
`page_id`
Orchestration (internal)
`notion_page_ref`
Stored as job context for write-back after decision
Notion
`Tool_Name`
Slack (alert message)
`tool_name` block field
Direct string; rendered in Block Kit template
Notion
`Renewal_Date`
Slack (alert message)
`renewal_date` block field
Formatted as 'DD MMM YYYY' for display
Notion
`Seat_Count`
Slack (alert message)
`seat_count` block field
Direct integer; displayed as 'X seats'
Notion
`Annual_Cost_USD`
Slack (alert message)
`annual_cost` block field
Formatted as '$X,XXX/year' for display
Notion
`Assigned_Owner_Slack_ID`
Slack API
`channel` parameter in chat.postMessage
Direct string; must be pre-populated in Notion register
Notion
`Assigned_Owner_Email`
Slack API (fallback)
`users.lookupByEmail` call
Used if Assigned_Owner_Slack_ID is empty; email-to-Slack-ID resolution

Agent 2 handoff: Slack response to Notion and Xero (Renewal Coordination Agent writes decisions and posts finance note)

Source tool
Source field
Destination tool
Destination field
Transformation
Slack (callback)
`actions[0].action_id`
Notion
`Decision` (select)
Map: 'action_renew' = 'Renew', 'action_reduce' = 'Reduce', 'action_cancel' = 'Cancel'
Slack (callback)
`actions[0].value`
Notion
`Decision_Notes` (rich_text)
Free-text value from button payload or modal input
Slack (callback)
`user.id`
Notion
`Decision_By_Slack_ID` (rich_text)
Records which Slack user submitted the response
Slack (callback)
`message.ts`
Orchestration (internal)
`response_timestamp`
Stored for audit; not written to Notion
Orchestration (computed)
`today + renewal_interval_days`
Notion
`Next_Review_Date` (date)
Renew: today + 365 or 90 based on contract type; Cancel: no next review
Orchestration (computed)
`Decision = 'Renewed' OR 'Cancelled'`
Notion
`Status` (select)
Renewed = 'Renewed'; Cancelled = 'Cancelled'; Reduce = 'Pending_Decision' until seat change confirmed
Notion (aggregated)
`all Flagged records with Decision set`
Xero
Finance note body
Serialised to PDF: Tool_Name, Decision, Seat_Count delta, Annual_Cost_USD delta, Decision_By
Orchestration (computed)
`run_date`
Xero
Attachment filename
Format: 'licence_change_note_YYYY-MM-DD.pdf'
Integration and API SpecPage 3 of 4
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
Two separate workflows, one per agent. Workflow 1: Licence Discovery Agent (daily schedule trigger). Workflow 2: Renewal Coordination Agent (poll-based trigger on Notion 'Flagged' records). Both workflows share a single credential store. No cross-workflow direct calls; Agent 2 is triggered by data state in Notion, not by a direct call from Agent 1. This decoupling allows each agent to be tested and redeployed independently.
Agent 1 trigger mechanism
Scheduled poll. Runs daily at 07:00 in the business timezone (store as ENV_TIMEZONE in configuration). No inbound webhook. The schedule fires the Microsoft 365 Graph API call, processes the response, and writes results to Notion. If the scheduled run fails, the orchestration platform must retry up to 3 times with a 5-minute backoff before raising a failure alert to SLACK_IT_MANAGER_USER_ID.
Agent 2 trigger mechanism
Poll-based on Notion database state. After Agent 1 completes (or on a 5-minute independent poll), Workflow 2 queries the Notion Licence Register for records with Status = 'Flagged' AND Assigned_Agent is null. Matching records are claimed by setting Assigned_Agent = 'Renewal_Coordination_Agent' before Slack messages are dispatched, preventing duplicate sends. Inbound Slack interaction callbacks arrive via a configured Request URL pointing to the orchestration layer's webhook receiver; the Slack signing secret (SLACK_SIGNING_SECRET) must be used to validate every inbound payload.
Slack signature validation
On every inbound Slack callback: extract X-Slack-Request-Timestamp and X-Slack-Signature headers. Reject requests where the timestamp is more than 5 minutes old (replay attack prevention). Compute HMAC-SHA256 over 'v0:{timestamp}:{raw_body}' using SLACK_SIGNING_SECRET. Compare to the v0= prefix of X-Slack-Signature using a constant-time comparison. Return HTTP 403 and log the event if validation fails.
Credential store structure
All secrets stored in the automation platform's built-in encrypted credential store. No secrets in workflow step configurations, environment variable files checked into version control, or hardcoded strings. See code block below for full contents.
Xero token refresh
The orchestration layer must check the Xero access token age before every Xero API call. If the token is older than 25 minutes, refresh proactively using XERO_REFRESH_TOKEN. Store the new access token and refresh token back to the credential store immediately after a successful refresh. Log a WARN event if the refresh token is within 10 days of its 60-day expiry and notify SLACK_IT_MANAGER_USER_ID.
Notion polling interval
5 minutes, starting from the scheduled completion time of Agent 1's daily run. The poll runs continuously throughout the business day to capture late owner responses. Outside business hours (configurable as ENV_BUSINESS_HOURS_START and ENV_BUSINESS_HOURS_END), the poll interval increases to 30 minutes to reduce unnecessary API calls.
Logging and audit
Every workflow run must log: run start timestamp, trigger source, number of records processed, number of Slack messages sent, number of Notion records updated, number of Xero posts made, and any errors with full response payloads. Logs are retained for a minimum of 90 days. Sensitive field values (client_secret, refresh_token) must never appear in logs.
All values are placeholders. Replace with actual credentials in the credential store before any test run. Never commit real values to version control.
// Credential store contents
// Microsoft 365
MS365_TENANT_ID          = '<azure-ad-tenant-id>'
MS365_CLIENT_ID          = '<azure-ad-app-client-id>'
MS365_CLIENT_SECRET      = '<azure-ad-app-client-secret>'

// Notion
NOTION_API_TOKEN         = 'secret_<internal-integration-token>'
NOTION_LICENCE_DB_ID     = '<notion-licence-register-database-id>'
NOTION_DECISIONS_DB_ID   = '<notion-renewal-decisions-log-database-id>'

// Slack
SLACK_BOT_TOKEN          = 'xoxb-<slack-bot-token>'
SLACK_SIGNING_SECRET     = '<slack-app-signing-secret>'
SLACK_IT_MANAGER_USER_ID = 'U<slack-user-id-of-it-manager>'
SLACK_DIGEST_CHANNEL_ID  = 'C<slack-channel-id-for-digest>'
SLACK_FALLBACK_FORM_URL  = 'https://<form-host>/renewal-response'

// Xero
XERO_CLIENT_ID           = '<xero-connected-app-client-id>'
XERO_CLIENT_SECRET       = '<xero-connected-app-client-secret>'
XERO_TENANT_ID           = '<xero-organisation-tenant-id>'
XERO_REFRESH_TOKEN       = '<xero-oauth2-refresh-token>'
XERO_IT_CONTACT_ID       = '<xero-contact-id-for-it-cost-centre>'

// Orchestration configuration
ENV_TIMEZONE             = 'Australia/Sydney'   // adjust to business timezone
ENV_BUSINESS_HOURS_START = '08:00'
ENV_BUSINESS_HOURS_END   = '18:00'
ENV_RENEWAL_WINDOW_DAYS  = '60'
ENV_ALERT_RETRY_MAX      = '3'
ENV_ALERT_RETRY_BACKOFF_MIN = '5'

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 defined below, the orchestration layer must send an alert to SLACK_IT_MANAGER_USER_ID with the error type, affected record or workflow, and timestamp before halting the affected step.

Integration
Scenario
Required behaviour
Microsoft 365 (Graph API)
HTTP 401 Unauthorized on token request
Check MS365_CLIENT_SECRET validity. If expired or revoked, alert IT manager via Slack immediately and halt Agent 1 run. Do not retry with invalid credentials. Log full error response.
Microsoft 365 (Graph API)
HTTP 429 Too Many Requests
Pause the current step. Read the Retry-After response header. Wait for the specified duration (minimum 30 seconds if header absent). Retry up to 3 times. If 3 retries exhausted, log error and alert IT manager via Slack. Do not skip the step.
Microsoft 365 (Graph API)
Paginated response: @odata.nextLink present
Follow all nextLink pages before processing. Store partial page results in memory. If a page request fails mid-pagination, retry that page up to 3 times before aborting the full run and alerting.
Notion (licence register read)
HTTP 403 Forbidden (integration not shared with database)
Alert IT manager via Slack with the database ID and instruction to re-share the integration. Halt the affected workflow step. Do not proceed with partial data. Log the event.
Notion (licence register write)
HTTP 409 Conflict or stale page revision
Fetch the current page to get the latest last_edited_time. Reapply the intended patch to the current version. Retry once. If conflict persists, log and alert IT manager. Do not overwrite with stale data.
Notion (Agent 2 poll)
Zero flagged records returned (expected after Agent 1 run)
Log as INFO: no anomalies or renewals detected. Send a reduced daily digest to IT manager confirming clean run. Do not treat as an error.
Slack (chat.postMessage)
HTTP 429 rate limit or Slack API error
Wait for the Retry-After duration. Retry up to 3 times with exponential backoff (5 s, 15 s, 45 s). If all retries fail, log the unsent message and include it in the daily digest as an undelivered alert. Alert IT manager directly.
Slack (owner response callback)
No response received within 24 hours of alert send
Re-send the renewal alert once with a reminder prefix. If still no response after a further 24 hours, mark the Notion record Status = 'Pending_Decision', include in the IT manager digest as 'Awaiting owner response', and log. Do not leave the record in 'Flagged' state indefinitely.
Slack (inbound callback)
Signature validation failure (HMAC mismatch or stale timestamp)
Return HTTP 403 immediately. Log the source IP, timestamp, and raw payload header. Do not process the callback. Alert IT manager if more than 3 validation failures occur within one hour.
Xero (token refresh)
Refresh token expired or revoked
Alert IT manager via Slack with instructions to re-authorise the Xero connected app. Halt all Xero steps for the current run. Log the failure. The finance note for this run must be queued and re-attempted after re-authorisation, not discarded.
Xero (finance note post)
HTTP 400 Bad Request (malformed payload or invalid contact ID)
Log the full request and response payload. Alert IT manager with the affected run date and error detail. Do not retry automatically. Requires manual investigation of the Xero contact ID and note template before re-run.
Orchestration (any agent)
Unhandled exception or platform timeout
Catch-all error handler must fire on any unhandled exception. Log the full stack trace and the last successfully completed step. Send an alert to SLACK_IT_MANAGER_USER_ID with: workflow name, step that failed, timestamp, and error summary. Never allow an unhandled exception to terminate the run silently.
Unhandled exceptions must never fail silently. Every workflow must have a catch-all error branch as its final node. If this branch fires, it must always produce a Slack alert to SLACK_IT_MANAGER_USER_ID regardless of the nature of the exception. The alert must include enough context for the FullSpec team or the IT manager to identify and resolve the issue without access to internal logs. Contact support@gofullspec.com for escalation if an error cannot be resolved within one business day.
Integration and API SpecPage 4 of 4

More documents for this process

Every document generated for Software Licence Management.

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