Back to Employee Offboarding

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

Employee Offboarding Automation

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

This document is the definitive integration reference for the Employee Offboarding automation. It covers every tool in the stack, the exact API scopes and auth methods required, field mappings between systems, orchestration architecture, and error-handling behaviour for every integration point. The FullSpec team uses this specification to build and configure the automation. Your team is responsible for supplying credentials and validating that the field values in BambooHR, Xero, and Jira match the mappings defined in Section 03 before the first live run.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agent(s)
Orchestration layer
Workflow automation platform hosting all agent workflows, credential store, and retry logic
Internal (platform auth)
N/A
All
BambooHR
Departure trigger source and final record closure destination
API key (per-user token)
Essentials or higher
Agent 1, Agent 2
Okta
SSO account suspension for all connected SaaS applications
OAuth 2.0 (service app) + API token
Workforce Identity (any paid tier)
Agent 1
Google Workspace
Account disable, out-of-office reply, Drive ownership transfer, exit survey dispatch
OAuth 2.0 service account (domain-wide delegation)
Business Starter or higher
Agent 1, Agent 2
Jira
Offboarding task board creation with assigned subtasks per owner
API token (basic auth over HTTPS)
Free or higher (Cloud)
Agent 2
Xero
Structured payroll notification to finance lead
OAuth 2.0 (authorization code flow)
Starter or higher
Agent 2
Slack
Completion summary posted to HR channel
OAuth 2.0 (Bot token via Slack App)
Free or higher
Agent 2
Before you connect anything: every integration must be validated against a sandbox or test environment before production credentials are entered into the credential store. For BambooHR, use a test employee record. For Okta and Google Workspace, use a dedicated test user account that holds no real data. For Xero, use the Xero demo company. For Jira and Slack, use a non-production workspace or test channel. No production API call should be made until the end-to-end sandbox test passes without error.
Integration and API SpecPage 1 of 4
FS-DOC-05Technical

02Per-tool integration detail

BambooHR

Primary trigger source for the automation. A webhook fires when an employee record is updated with a departure date or the employment status changes to a configured offboarding value. Also the destination for final record closure at the end of the workflow.

Auth method
API key passed as Basic Auth username (password field left blank). Key is scoped to the HR Manager's account or a dedicated integration user.
Required scopes
employees:read, employees:write, webhooks:create, webhooks:read. These map to the BambooHR API permission set 'Employee Access' plus 'Webhook Management' granted via Settings > API Keys.
Webhook setup
Create a webhook at Settings > API > Webhooks. Event: 'Employee changed'. Monitor fields: 'status' (value = 'Terminated' or configured offboarding label) and 'terminationDate'. Payload format: JSON. Secret key must be stored in the credential store and used to validate the HMAC-SHA256 signature on every incoming request. The orchestration layer must reject any request where the signature does not match.
Required configuration
Store in credential store: bamboohr_api_key, bamboohr_subdomain (e.g. yourcompany.bamboohr.com), bamboohr_webhook_secret. The field name for departure date must be confirmed against the live account (default: terminationDate). The employee status value that triggers the workflow (e.g. 'Terminated') must be set in the workflow config, not hardcoded.
Rate limits
BambooHR enforces a limit of approximately 400 API requests per minute per subdomain. At 2 to 4 offboardings per month, peak usage is well under 50 API calls per offboarding event. No throttling layer is required at current volume.
Constraints
BambooHR does not support per-field webhook filtering natively; the orchestration layer must filter on the received payload to confirm the relevant fields changed before proceeding. API key rotation requires manual update of the credential store.
// Trigger payload (abbreviated)
{
  "employeeId": "<bamboohr_employee_id>",
  "changedFields": ["status", "terminationDate"],
  "status": "Terminated",
  "terminationDate": "YYYY-MM-DD",
  "firstName": "<string>",
  "lastName": "<string>",
  "workEmail": "<string>",
  "managerId": "<bamboohr_manager_id>"
}
// Record closure PATCH (end of workflow)
PATCH /v1/employees/{employeeId}
Body: { "status": "Offboarded", "offboardingCompletedDate": "YYYY-MM-DD" }
Okta

Receives a suspension instruction from the Access Revocation Agent. Immediately suspends the user's SSO session, which revokes access to all Okta-connected SaaS applications in a single API call.

Auth method
OAuth 2.0 client credentials flow (service app). A dedicated Okta service application is created in the Okta Admin Console with no user interaction required at runtime. Alternatively, an SSWS API token may be used for simpler setups; however, the OAuth 2.0 service app is preferred for auditability.
Required scopes
okta.users.manage (to suspend and deactivate users). If user profile read is required for lookup: okta.users.read. Scopes are granted to the service application under Security > API > Authorization Servers.
Webhook / trigger setup
Okta is called outbound only (no inbound webhook from Okta in this workflow). The orchestration layer issues POST /api/v1/users/{userId}/lifecycle/suspend immediately after the BambooHR trigger is validated.
Required configuration
Store in credential store: okta_domain (e.g. yourcompany.okta.com), okta_client_id, okta_client_secret, okta_api_token (if using SSWS fallback). The Okta userId must be resolved at runtime by querying GET /api/v1/users?search=profile.login eq "{workEmail}" using the employee's work email from BambooHR. Do not hardcode user IDs.
Rate limits
Okta enforces 600 requests per minute on the /users endpoint for most paid plans. At current volume (2 to 4 offboardings per month), there is no risk of hitting this limit. No throttling needed.
Constraints
Suspending a user is reversible; deactivation is not. The workflow uses suspend, not deactivate, so a restoration path exists if the trigger fires incorrectly. A separate manual deactivation step after 30 days is recommended but is outside this automation's scope. The service app must be granted the 'Application Administrator' role in Okta if it needs to unassign app assignments.
// Step 1: Resolve Okta userId by email
GET https://{okta_domain}/api/v1/users?search=profile.login+eq+"{workEmail}"
Response: [{ "id": "<okta_user_id>", "status": "ACTIVE", ... }]

// Step 2: Suspend user
POST https://{okta_domain}/api/v1/users/{okta_user_id}/lifecycle/suspend
Authorization: Bearer {access_token}
Expected response: 200 OK (empty body)

// On success: pass okta_user_id and suspension_timestamp to next step
Google Workspace

Used by both agents. Agent 1 calls the Admin SDK to disable the user account, configure an out-of-office reply, and transfer Drive file ownership to the departing employee's manager. Agent 2 uses the Gmail API to send the exit survey to the employee's personal email.

Auth method
OAuth 2.0 service account with domain-wide delegation (DWD) enabled. The service account is created in Google Cloud Console, a JSON key file is downloaded and stored in the credential store, and DWD is granted in the Google Workspace Admin Console under Security > API Controls > Domain-wide Delegation. The service account impersonates a super-admin to call Admin SDK endpoints.
Required scopes
https://www.googleapis.com/auth/admin.directory.user (suspend/update user), https://www.googleapis.com/auth/admin.directory.user.security (set out-of-office), https://www.googleapis.com/auth/drive (ownership transfer), https://www.googleapis.com/auth/gmail.send (send exit survey email). All four scopes must be listed in the DWD configuration.
Webhook / trigger setup
Google Workspace is called outbound only. No inbound push notifications are used. The orchestration layer calls the Admin SDK and Drive API sequentially after Okta confirms suspension.
Required configuration
Store in credential store: gws_service_account_key_json (full JSON key contents), gws_admin_impersonation_email (a super-admin address used for impersonation), gws_drive_transfer_destination_field (resolved from BambooHR managerId at runtime, mapped to manager's Google email). The out-of-office message template must be stored in the workflow config, not hardcoded. The exit survey URL must be stored in the workflow config.
Rate limits
Admin SDK: 10 queries per second per user; Drive API: 12,000 requests per 60 seconds per project. At current volume these limits are trivially far from being reached. No throttling required.
Constraints
Drive ownership transfer requires the destination user (the manager) to be in the same Google Workspace domain. Cross-domain transfer is not supported via API. If the manager is in a different domain, the workflow must flag this for manual resolution. The service account key JSON must be rotated at least annually and the credential store updated accordingly.
// Disable user account
PATCH https://admin.googleapis.com/admin/directory/v1/users/{userKey}
Body: { "suspended": true }

// Set out-of-office / vacation responder
PUT https://gmail.googleapis.com/gmail/v1/users/{userKey}/settings/vacation
Body: { "enableAutoReply": true, "responseSubject": "Out of Office",
        "responseBodyPlainText": "{vacation_template}" }

// Transfer Drive ownership to manager
POST https://www.googleapis.com/drive/v3/files/{fileId}/permissions
Body: { "role": "owner", "type": "user", "emailAddress": "{manager_google_email}" }

// Send exit survey (Agent 2)
POST https://gmail.googleapis.com/gmail/v1/users/me/messages/send
Body: { "raw": "<base64url-encoded RFC 2822 message with survey_url placeholder>" }
Jira

Used by the Task and Notification Agent to create a structured offboarding task board with subtasks assigned to the correct owner for equipment return, payroll confirmation, and exit interview tracking. Also provides the equipment return confirmation trigger.

Auth method
API token issued per user in Atlassian account settings. Passed as HTTP Basic Auth with the Jira account email as the username and the API token as the password, Base64-encoded. All calls are made over HTTPS.
Required scopes
Jira Cloud API tokens do not use OAuth scopes directly; the token inherits the permissions of the issuing user. The integration user must have: Create Issues, Edit Issues, Assign Issues, and Browse Projects on the target offboarding project. A dedicated integration user (e.g. offboarding-bot@yourcompany.com) is recommended over a personal account.
Webhook / trigger setup
A Jira automation rule (or an outbound webhook from Jira) is configured to POST to the orchestration layer's inbound webhook endpoint when the equipment return subtask transitions to 'Done'. The orchestration layer validates the payload before proceeding to the Slack summary and BambooHR record closure steps. The webhook secret must be stored in the credential store.
Required configuration
Store in credential store: jira_base_url (e.g. https://yourcompany.atlassian.net), jira_api_token, jira_user_email, jira_project_key (the offboarding project key, e.g. OFFB). Issue type IDs and transition IDs must be resolved via the Jira API at setup time and stored in the workflow config, not hardcoded. Subtask assignee account IDs for IT, finance, and manager roles must be stored in the workflow config keyed by role.
Rate limits
Jira Cloud enforces a rate limit of approximately 10 requests per second per integration user. At 2 to 4 offboardings per month, peak demand is roughly 10 to 15 API calls per run. No throttling required.
Constraints
Jira project templates are not accessible via API; the board must be created by posting individual issues and subtasks. The parent epic or story must be created first, then subtasks linked to it. If the offboarding project does not exist, the first run will fail; the project must be pre-created manually and the key stored in config.
// Create parent offboarding issue
POST https://{jira_base_url}/rest/api/3/issue
Body: {
  "fields": {
    "project": { "key": "{jira_project_key}" },
    "summary": "Offboarding: {firstName} {lastName} - {terminationDate}",
    "issuetype": { "id": "{story_issue_type_id}" },
    "assignee": { "accountId": "{hr_manager_account_id}" },
    "duedate": "{terminationDate}"
  }
}

// Create equipment return subtask (repeat pattern for each subtask)
POST https://{jira_base_url}/rest/api/3/issue
Body: {
  "fields": {
    "project": { "key": "{jira_project_key}" },
    "parent": { "key": "{parent_issue_key}" },
    "summary": "Equipment Return: {firstName} {lastName}",
    "issuetype": { "id": "{subtask_issue_type_id}" },
    "assignee": { "accountId": "{manager_account_id}" }
  }
}
Xero

Receives a structured payroll notification from the Task and Notification Agent containing the employee's final working day, accrued leave balance, and any equipment deduction flags. The automation does not write payroll entries directly; it posts a note or sends a notification to the finance lead via Xero's API.

Auth method
OAuth 2.0 authorization code flow. The finance lead completes a one-time browser-based consent to grant the automation access to the Xero organisation. The resulting refresh token is stored in the credential store and used to generate short-lived access tokens at runtime.
Required scopes
openid profile email accounting.contacts.read accounting.transactions payroll.employees payroll.leaveapplications. The payroll.* scopes are only available on Xero plans that include payroll (Starter or higher with payroll add-on, depending on region). Confirm payroll API availability for the organisation's region before build.
Webhook / trigger setup
Xero is called outbound only in this workflow. The orchestration layer posts a payroll note after the Jira board is created. No inbound Xero webhook is used.
Required configuration
Store in credential store: xero_client_id, xero_client_secret, xero_refresh_token, xero_tenant_id. The employee's Xero payroll EmployeeID must be resolved at setup by querying GET /payroll/v1/employees filtered by first and last name or work email. Store the field mapping from BambooHR leave balance field to Xero leave type in the workflow config. Do not hardcode tenant IDs or employee IDs.
Rate limits
Xero enforces a limit of 60 API calls per minute and 5,000 calls per day per connected app. At current volume this automation makes approximately 5 to 8 Xero API calls per offboarding. No throttling required.
Constraints
The Xero refresh token expires if unused for 60 days. A token refresh check must run at the start of each Xero interaction. Payroll API availability varies by region; the AU, UK, and NZ payroll APIs differ from the global accounting API. Confirm the correct base URL for the organisation's payroll region before build. The automation posts a payroll note and does not submit a pay run; final pay calculation remains with the finance lead.
// Resolve Xero EmployeeID
GET https://api.xero.com/payroll/v1/employees?where=FirstName=="{firstName}"&&LastName=="{lastName}"
Headers: Authorization: Bearer {access_token}, Xero-Tenant-Id: {xero_tenant_id}
Response: { "Employees": [{ "EmployeeID": "<uuid>", ... }] }

// Post payroll note
POST https://api.xero.com/payroll/v1/employees/{EmployeeID}/notes
Body: {
  "Title": "Final Pay Notification - Automated",
  "Note": "Last working day: {terminationDate}. Leave balance: {leave_balance_days} days.
            Equipment deduction flag: {equipment_flag}. Generated by offboarding automation."
}
Slack

Receives a completion summary message from the Task and Notification Agent after all automated steps are confirmed. Posts to a designated HR Slack channel listing every completed task and flagging any items still awaiting human confirmation.

Auth method
OAuth 2.0 Bot token. A Slack App is created in the Slack API console, installed to the workspace, and granted the required bot scopes. The bot token (xoxb-*) is stored in the credential store.
Required scopes
chat:write (to post messages to channels), channels:read (to resolve the HR channel ID by name). The Slack App must be invited to the target HR channel before the first run.
Webhook / trigger setup
The orchestration layer calls the Slack Web API chat.postMessage endpoint outbound. No Slack Events API inbound webhook is required for this workflow. An incoming webhook URL may be used as a simpler alternative, stored in the credential store as slack_incoming_webhook_url.
Required configuration
Store in credential store: slack_bot_token (or slack_incoming_webhook_url if using the simpler approach), slack_hr_channel_id. The HR channel ID must be confirmed at setup (do not use channel names at runtime as they can change; use the stable channel ID). The summary message template must be stored in the workflow config.
Rate limits
Slack enforces a Tier 3 rate limit of approximately 50 requests per minute on chat.postMessage. At 2 to 4 offboardings per month this is not a concern. No throttling required.
Constraints
The Slack App must have the chat:write scope and must be a member of the target channel. If the channel is private, the app must be explicitly invited. Block Kit message formatting is recommended for readability of the summary but is not required for functionality.
// Post completion summary
POST https://slack.com/api/chat.postMessage
Headers: Authorization: Bearer {slack_bot_token}, Content-Type: application/json
Body: {
  "channel": "{slack_hr_channel_id}",
  "text": "Offboarding complete: {firstName} {lastName} ({terminationDate})",
  "blocks": [
    { "type": "section", "text": { "type": "mrkdwn",
      "text": "*Offboarding Summary*\n{firstName} {lastName} | Last day: {terminationDate}" } },
    { "type": "section", "text": { "type": "mrkdwn",
      "text": ":white_check_mark: Okta suspended\n:white_check_mark: Google account disabled\n:white_check_mark: Jira board created\n:white_check_mark: Xero notified\n:white_check_mark: Exit survey sent\n:hourglass: Equipment return: {equipment_status}" } }
  ]
}
Integration and API SpecPage 2 of 4
FS-DOC-05Technical

03Field mappings between tools

The tables below define every field handoff between systems at each agent boundary. Use exact field names as shown. Any discrepancy between these names and the live system fields must be resolved in the workflow config before go-live.

Agent 1 handoff: BambooHR trigger to Okta and Google Workspace (Access Revocation Agent)

Source tool
Source field
Destination tool
Destination field
BambooHR
workEmail
Okta
profile.login (used in search filter)
BambooHR
workEmail
Google Workspace Admin SDK
userKey (primary identifier)
BambooHR
terminationDate
Google Workspace
vacation.enableAutoReply trigger date
BambooHR
managerId
Google Workspace Drive API
permission.emailAddress (ownership transfer destination, resolved to manager Google email via BambooHR GET /v1/employees/{managerId})
BambooHR
firstName
Jira (passed downstream)
fields.summary (concatenated with lastName)
BambooHR
lastName
Jira (passed downstream)
fields.summary (concatenated with firstName)
Okta
id (okta_user_id)
Orchestration context
okta_user_id (stored for audit log entry)
Okta
lifecycle status response
Orchestration context
okta_suspension_confirmed (boolean gate for next step)

Agent 2 handoff: Access Revocation Agent output to Task and Notification Agent (Jira, Xero, Google Workspace, Slack)

Source tool
Source field
Destination tool
Destination field
BambooHR
employeeId
Jira
fields.summary (used in issue title)
BambooHR
firstName + lastName
Jira
fields.summary
BambooHR
terminationDate
Jira
fields.duedate
BambooHR
managerId (resolved to account)
Jira
fields.assignee.accountId (equipment return subtask)
BambooHR
terminationDate
Xero
note body field: Last working day
BambooHR
accrualBalance (leave balance field)
Xero
note body field: Leave balance (days)
BambooHR
workEmail
Google Workspace Gmail
message.to (exit survey; overridden by personalEmail if present)
BambooHR
personalEmail
Google Workspace Gmail
message.to (exit survey primary recipient)
BambooHR
terminationDate
Google Workspace Gmail
message send schedule: terminationDate minus 1 day
Jira
equipment_return_subtask.status (= Done)
Orchestration context
equipment_confirmed (boolean gate for Slack post and BambooHR closure)
Orchestration context
all_steps_completed (boolean)
Slack
chat.postMessage body blocks
Orchestration context
all_steps_completed (boolean)
BambooHR
PATCH employees/{employeeId} status = Offboarded
The BambooHR field name for leave balance must be confirmed against the live account before go-live. Common field names include accrualBalance, ptoBalance, and leaveBalance depending on the account configuration. The FullSpec team will validate this mapping during the discovery and field-mapping step in Week 1.

04Build stack and orchestration

Orchestration layout
Two separate workflows in the automation platform, one per agent: (1) Access Revocation Agent workflow, (2) Task and Notification Agent workflow. Both workflows draw credentials from a single shared credential store. The Task and Notification Agent workflow is triggered by a success output event from the Access Revocation Agent workflow, not by a separate external trigger.
Agent 1 trigger mechanism
Inbound webhook (push). BambooHR fires a webhook POST to the orchestration layer endpoint when an employee's status or terminationDate field changes. The orchestration layer validates the HMAC-SHA256 signature using the bamboohr_webhook_secret before processing the payload. Polling is not used for this step.
Agent 2 trigger mechanism
Internal event (chained workflow). The Access Revocation Agent emits a structured success payload (containing employeeId, terminationDate, workEmail, personalEmail, managerId, and okta_suspension_confirmed = true) to the orchestration layer's internal event bus. The Task and Notification Agent workflow listens for this event and begins immediately. No external webhook or poll interval is needed.
Equipment return gate mechanism
Poll (interval-based). After the Jira board is created, the Task and Notification Agent workflow polls the Jira API for the equipment return subtask status every 4 hours, up to a maximum of 10 days. If the subtask reaches 'Done', the Slack summary and BambooHR closure proceed. If the 10-day limit is reached without confirmation, the workflow sends an escalation alert to the HR Slack channel and pauses. Poll interval: 4 hours. Max wait: 10 days (240 hours).
Exit survey send timing
The Google Workspace Gmail send is scheduled within the workflow to fire at 09:00 local time on the day before terminationDate. The orchestration layer computes terminationDate minus 1 calendar day at workflow start and stores this as a delayed execution timestamp.
Credential store type
The automation platform's native encrypted credential store. All secrets are referenced by variable name in workflow steps. No secret value is written into a workflow node directly.
All values in angle brackets must be populated before the first sandbox run. Never commit raw secrets to version control.
// Credential store contents (all values encrypted at rest)

// BambooHR
bamboohr_api_key          = "<BambooHR API key for integration user>"
bamboohr_subdomain        = "yourcompany"   // used to build base URL
bamboohr_webhook_secret   = "<HMAC-SHA256 secret from BambooHR webhook config>"

// Okta
okta_domain               = "yourcompany.okta.com"
okta_client_id            = "<Okta service app client ID>"
okta_client_secret        = "<Okta service app client secret>"
okta_api_token            = "<SSWS token (fallback only)>"

// Google Workspace
gws_service_account_key_json       = "<full JSON key file contents, base64-encoded>"
gws_admin_impersonation_email      = "admin@yourcompany.com"

// Jira
jira_base_url             = "https://yourcompany.atlassian.net"
jira_api_token            = "<Atlassian API token for integration user>"
jira_user_email           = "offboarding-bot@yourcompany.com"
jira_project_key          = "OFFB"
jira_webhook_secret       = "<secret for inbound Jira equipment-return webhook>"

// Xero
xero_client_id            = "<Xero app client ID>"
xero_client_secret        = "<Xero app client secret>"
xero_refresh_token        = "<long-lived refresh token from OAuth consent>"
xero_tenant_id            = "<Xero organisation tenant ID>"

// Slack
slack_bot_token           = "xoxb-<Slack bot OAuth token>"
slack_hr_channel_id       = "C<Slack channel ID for HR channel>"

// Workflow config (non-secret, stored in workflow variables)
offboarding_status_value      = "Terminated"     // BambooHR status string to match
equipment_poll_interval_hrs   = 4
equipment_poll_max_hrs        = 240
exit_survey_url               = "https://yourcompany.com/exit-survey"
ooo_reply_template            = "Thank you for your email. {firstName} {lastName} is no longer at [YourCompany.com]. Please contact hr@yourcompany.com for assistance."
jira_hr_manager_account_id    = "<Atlassian account ID for HR Manager>"
jira_it_admin_account_id      = "<Atlassian account ID for IT Administrator>"
jira_finance_account_id       = "<Atlassian account ID for Finance Lead>"
Integration and API SpecPage 3 of 4
FS-DOC-05Technical

05Error handling and retry logic

Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently. If a step cannot complete after exhausting retries, the orchestration layer must write an error log entry and send an alert to the HR Slack channel with the failing step name, the employee record ID, and the error detail.

Integration
Scenario
Required behaviour
BambooHR (inbound webhook)
Webhook signature validation fails
Reject the request with HTTP 401. Log the event with the raw payload hash. Do not process the trigger. Alert support@gofullspec.com. Do not retry (invalid signatures indicate a configuration or security issue, not a transient fault).
BambooHR (inbound webhook)
Webhook received but terminationDate field is null or status does not match configured value
Discard the event silently (log at debug level only). This is expected for non-departure field changes. No alert required.
Okta (user lookup)
GET /api/v1/users returns no match for the employee work email
Halt the Access Revocation Agent workflow. Log error: 'Okta user not found for {workEmail}'. Post alert to HR Slack channel with employee name and error. Do not proceed to Google Workspace step. Retry: none (user not found is not transient). Requires manual investigation.
Okta (suspension)
POST /lifecycle/suspend returns 5xx
Retry up to 3 times with exponential backoff: 30 seconds, 2 minutes, 8 minutes. If all retries fail, halt workflow, log error, and post alert to HR Slack channel. Do not proceed until suspension is confirmed. Manual fallback: IT Administrator must suspend the user directly in the Okta console.
Google Workspace (account disable)
PATCH /users/{userKey} returns 403 (insufficient permissions)
Halt workflow. Log error: 'GWS account disable failed: 403 for {workEmail}'. Post alert to HR Slack channel. This indicates a scope or DWD configuration issue, not a transient fault. No retry. The FullSpec team must review the service account permissions. Manual fallback: IT Administrator disables the account in the Google Admin Console.
Google Workspace (Drive transfer)
Drive ownership transfer fails because manager is in a different domain
Log error: 'Drive transfer failed: cross-domain transfer not supported for {manager_email}'. Post alert to HR Slack channel. Continue workflow (do not halt). Manual fallback: IT Administrator transfers Drive ownership manually. The error must appear in the Slack completion summary as an open item.
Google Workspace (exit survey send)
Gmail send fails because personalEmail is null and workEmail is already disabled
Log error: 'Exit survey send failed: no valid recipient address for {firstName} {lastName}'. Post alert to HR Slack channel. Do not retry. Flag in Jira offboarding board as an open item for HR to send manually. Continue workflow.
Jira (board creation)
POST /issue returns 400 or 404 (project key not found or invalid issue type)
Retry once after 60 seconds. If retry fails, halt the Task and Notification Agent workflow. Log error with full API response body. Post alert to HR Slack channel. Manual fallback: HR Manager creates the offboarding board manually in Jira. Xero and exit survey steps may proceed independently if triggered manually.
Jira (equipment return poll)
Equipment return subtask not marked Done within 10-day polling window
Stop polling. Post escalation alert to HR Slack channel: 'Equipment return not confirmed for {firstName} {lastName} after 10 days. Manual follow-up required.' Log the timeout. Do not block BambooHR record closure indefinitely; flag the record as 'Equipment return pending' in BambooHR and proceed to closure.
Xero (token refresh)
Refresh token has expired (unused for more than 60 days)
Halt the Xero step. Log error: 'Xero refresh token expired'. Post alert to HR Slack channel and to support@gofullspec.com. The finance lead must re-authorise the Xero connection via the OAuth consent flow. No retry until token is refreshed. Manual fallback: finance lead is notified directly via Slack to process the final pay notification.
Xero (payroll note post)
POST /employees/{id}/notes returns 5xx
Retry up to 3 times with exponential backoff: 30 seconds, 2 minutes, 8 minutes. If all retries fail, log error and post alert to HR Slack channel with the full payroll note content so the finance lead can enter it manually. Continue workflow.
Slack (completion summary)
chat.postMessage returns 4xx or 5xx
Retry up to 2 times with a 60-second interval. If retries fail, log the full summary payload to the orchestration platform's internal log. Post an email alert to the HR Manager's work email (if available from BambooHR payload) as a fallback notification channel. BambooHR record closure proceeds regardless of Slack delivery status.
BambooHR (record closure PATCH)
PATCH /employees/{id} returns 5xx
Retry up to 3 times with exponential backoff: 30 seconds, 2 minutes, 8 minutes. If all retries fail, log error and post alert to HR Slack channel. The HR Manager must manually update the BambooHR record. This is the final step and a failure here does not affect any upstream completed actions.
Orchestration layer (any step)
Unhandled exception or uncaught runtime error
The orchestration layer must catch all unhandled exceptions at the workflow level. On any uncaught error: log the full stack trace and step context, post an alert to the HR Slack channel with step name and employee record ID, and send an email to support@gofullspec.com. The workflow must halt and not attempt further steps. Unhandled exceptions must never fail silently.
Backoff formula for all retry sequences: wait = base_seconds * (2 ^ attempt_number). Attempt 1: base delay. Attempt 2: 2x base. Attempt 3: 4x base. Maximum individual wait cap is 10 minutes. All retry attempts and outcomes must be written to the orchestration platform's execution log with a timestamp, step name, HTTP status code (where applicable), and employee record ID.
Integration and API SpecPage 4 of 4

More documents for this process

Every document generated for Employee Offboarding.

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