Back to Vendor Performance Tracking

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

Vendor Performance Tracking

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

This document is the authoritative integration reference for the Vendor Performance Tracking automation. It covers every tool connection, exact OAuth scopes, webhook configuration, field mappings between agents, credential store layout, and error handling requirements. The FullSpec team uses this specification to build and test all integrations end to end. No credentials should be hardcoded; all secrets must reside in the shared credential store described in Section 04.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agents
Xero
Invoice and PO data source; trigger origin
OAuth 2.0 (PKCE)
Xero Starter or above
Agent 1 (Vendor Data Collection)
Airtable
Vendor record store and event log
Personal Access Token (PAT)
Airtable Free (Team recommended for API rate limits)
Agent 1, Agent 2, Agent 3
Google Sheets
Master scorecard and monthly summary report
OAuth 2.0 via Google service account
Google Workspace or personal Google account with Sheets API enabled
Agent 2, Agent 3
Slack
Ops manager alert channel
OAuth 2.0 Bot Token (xoxb)
Slack Free or above
Agent 3 (Escalation and Reporting)
Gmail
Vendor escalation email sender
OAuth 2.0 (Gmail API, delegated send)
Google Workspace or Gmail account with API access enabled
Agent 3 (Escalation and Reporting)
Workflow automation platform
Orchestration layer: hosts all agent workflows, manages triggers, credential store, and inter-agent handoffs
N/A (internal)
Subscription required; platform selected at build kick-off
All agents
Before you connect anything: sandbox-test every API connection using test credentials or a development environment before promoting to production. For Xero, use the Xero Demo Company. For Airtable and Google Sheets, use a cloned base/sheet prefixed 'TEST_'. For Slack, use a private #automation-test channel. Never write production credentials into workflow configs directly.

02Per-tool integration detail

Xero

Primary data source for invoice records and purchase order status. The automation connects to Xero via OAuth 2.0 with PKCE to read invoice and PO data on each trigger event. No write operations are performed against Xero.

Auth method
OAuth 2.0 with PKCE. Register a Xero app at developer.xero.com. Store client_id and client_secret in the credential store. Refresh tokens must be persisted and rotated automatically by the orchestration layer.
Required scopes
openid profile email accounting.transactions.read accounting.contacts.read offline_access
Webhook / trigger setup
Xero supports webhooks for invoice and purchase order events. Register a webhook endpoint in the Xero developer portal under your app's Webhooks section. Events to subscribe: Invoice.Created, Invoice.Updated, PurchaseOrder.Updated. Xero signs each webhook payload with HMAC-SHA256 using the webhook key stored in the credential store. The orchestration layer must validate the X-Xero-Signature header on every inbound request before processing; reject and log any request that fails signature validation.
Required configuration
Xero Tenant ID stored in credential store (not hardcoded). PO numbering convention must be standardised before build so cross-referencing is reliable. Invoice status filter: only process invoices with status AUTHORISED or PAID.
Rate limits
Xero API: 60 calls/minute per app, 5,000 calls/day per app. At ~40 vendor events/month plus polling fallback, estimated peak is under 120 calls/day. Throttling is not required at current volume but the orchestration layer must handle 429 responses with exponential backoff (initial delay 2 s, max 3 retries).
Constraints
Xero refresh tokens expire after 60 days of inactivity. The orchestration layer must schedule a token-refresh heartbeat every 30 days. Xero does not expose PO line-item delivery status natively; the automation derives delivery variance from the PO expected delivery date field versus the invoice date.
// Input
Webhook POST or poll response: Xero invoice or PO event payload

// Key fields extracted
InvoiceID, Contact.ContactID, Contact.Name (vendor name)
InvoiceNumber, DateString, DueDateString
AmountDue, AmountPaid, SubTotal, TotalTax
LineItems[].Quantity, LineItems[].UnitAmount, LineItems[].Description
PurchaseOrderID (linked via Invoice.PurchaseOrders[].PurchaseOrderID)
PurchaseOrder.DeliveryDate, PurchaseOrder.Status

// Output (passed to Agent 1 internal record)
Structured vendor event object: see Section 03 field mapping
Airtable

Central vendor record store and event log. Agent 1 writes new event records; Agent 2 updates scores and flags; Agent 3 reads event history to assemble the monthly report. All Airtable access uses a single Personal Access Token scoped to the relevant base.

Auth method
Personal Access Token (PAT). Generate in Airtable account settings under Developer Hub. Store as AIRTABLE_PAT in the credential store. Token must have base-scoped permissions only.
Required scopes
data.records:read data.records:write schema.bases:read
Webhook / trigger setup
Airtable is not used as a trigger source. Agent 2 is triggered by a new record creation event within the orchestration layer (record-created event on the VendorEvents table), not by an Airtable webhook. This avoids polling overhead.
Required configuration
Base ID stored as AIRTABLE_BASE_ID in credential store. Table IDs (not names) stored as: AIRTABLE_VENDORS_TABLE_ID, AIRTABLE_EVENTS_TABLE_ID. Table structure: Vendors table (VendorID, VendorName, CurrentScore, FlagStatus, LastEventDate, PerformanceSummary). VendorEvents table (EventID, VendorID [linked record], EventDate, DeliveryVarianceDays, InvoiceAccuracyPct, BilledAmount, OrderedAmount, ScoreAtEvent, EventNotes). Field IDs must be confirmed post-base-creation and stored in config; never reference field names in API calls.
Rate limits
Airtable API: 5 requests/second per base. At ~40 events/month plus score updates, peak load is well under 1 request/second. Throttling is not required at current volume. Implement 200 ms inter-request delay as a precaution.
Constraints
Linked record fields require the record ID of the related Vendors record, not the vendor name string. Agent 1 must look up the Vendors table to resolve VendorID before writing to VendorEvents. If a vendor does not exist in the Vendors table, the automation must create a stub record and alert the ops channel before proceeding.
// Input (Agent 1 write)
POST /v0/{baseId}/{eventsTableId}
Body: { fields: { VendorID: [recXXXX], EventDate, DeliveryVarianceDays,
        InvoiceAccuracyPct, BilledAmount, OrderedAmount, EventNotes } }

// Input (Agent 2 update)
PATCH /v0/{baseId}/{vendorsTableId}/{recordId}
Body: { fields: { CurrentScore, FlagStatus, PerformanceSummary, LastEventDate } }

// Output (Agent 3 read for monthly report)
GET /v0/{baseId}/{eventsTableId}?filterByFormula=...
Returns array of event records for the current month
Google Sheets

Hosts the master vendor scorecard and receives the monthly summary report. Agent 2 writes flag status per vendor row; Agent 3 appends monthly report rows at end-of-month. Access uses a Google service account with the Sheets API enabled.

Auth method
OAuth 2.0 via Google service account. Create a service account in Google Cloud Console, enable the Google Sheets API, and share the target spreadsheet with the service account email as Editor. Store the service account JSON key as GOOGLE_SA_KEY in the credential store.
Required scopes
https://www.googleapis.com/auth/spreadsheets
Webhook / trigger setup
Google Sheets is not used as a trigger source in this automation. No push notification setup is required.
Required configuration
SHEETS_SCORECARD_ID: spreadsheet ID of the master scorecard, stored in credential store. SHEETS_SCORECARD_TAB: exact tab name for the vendor scorecard (e.g. 'VendorScorecard'). SHEETS_REPORT_TAB: exact tab name for the monthly report (e.g. 'MonthlyReport'). Column layout for VendorScorecard must be fixed: A=VendorID, B=VendorName, C=CurrentScore, D=FlagStatus, E=LastUpdated, F=EventCount. Column layout for MonthlyReport: A=ReportMonth, B=VendorID, C=VendorName, D=AvgScore, E=FlagCount, F=Resolution, G=GeneratedAt. Header rows must not be overwritten; all writes use append or targeted row updates by VendorID lookup.
Rate limits
Google Sheets API: 300 requests/minute per project, 60 requests/minute per user. At current volume, estimated Sheets calls are under 50/day. Throttling is not required. Handle 429 and 503 responses with exponential backoff (initial delay 1 s, max 5 retries).
Constraints
Row lookup by VendorID must use a batchGet or values.get call before writing to ensure the correct row is targeted. Never blindly append to the scorecard tab; always find and update the existing vendor row. If the vendor row does not exist, create it and send a Slack alert to the ops channel.
// Scorecard update (Agent 2)
PUT /v4/spreadsheets/{spreadsheetId}/values/{range}
Range: VendorScorecard!C{rowNum}:E{rowNum}
Values: [[CurrentScore, FlagStatus, LastUpdated]]

// Monthly report append (Agent 3)
POST /v4/spreadsheets/{spreadsheetId}/values/{range}:append
Range: MonthlyReport!A:G
Values: [[ReportMonth, VendorID, VendorName, AvgScore, FlagCount, Resolution, GeneratedAt]]
Integration and API SpecPage 1 of 3
FS-DOC-05Technical
Slack

Receives flagged-vendor alerts from Agent 3 posted to the ops channel. Uses a Slack Bot Token installed into the workspace. No interactive components are required at current scope; the approval step is handled outside Slack.

Auth method
OAuth 2.0 Bot Token (xoxb-...). Create a Slack app at api.slack.com/apps, add to workspace, and install with the required scopes. Store token as SLACK_BOT_TOKEN in the credential store.
Required scopes
chat:write chat:write.public channels:read
Webhook / trigger setup
Slack is an output-only tool in this automation. No incoming webhooks or event subscriptions are configured. If future iterations require interactive approval buttons in Slack, an additional app manifest update and the actions:read scope will be needed.
Required configuration
SLACK_OPS_CHANNEL_ID: the channel ID (not name) of the ops alerts channel, stored in credential store. Message template must include: vendor name, current score, score threshold, event type (late delivery or invoice discrepancy), event date, and a link to the Airtable vendor record. Channel ID is used rather than channel name to avoid breakage if the channel is renamed.
Rate limits
Slack Web API: Tier 3 methods (chat.postMessage) allow 50+ calls/minute. At ~40 flag events/month plus monthly report alerts, peak load is negligible. Throttling is not required.
Constraints
Bot must be invited to the ops channel before the first message can be sent. Verify channel membership in QA before go-live. If the bot is removed from the channel, the integration will return a not_in_channel error; this must be caught and escalated via email to support@gofullspec.com.
// Slack alert payload (Agent 3 output)
POST https://slack.com/api/chat.postMessage
Headers: { Authorization: 'Bearer {SLACK_BOT_TOKEN}' }
Body: {
  channel: '{SLACK_OPS_CHANNEL_ID}',
  text: 'Vendor flagged: {VendorName} | Score: {CurrentScore} (threshold: {ScoreThreshold})',
  blocks: [
    { type: 'section', text: { type: 'mrkdwn',
      text: '*{VendorName}* scored *{CurrentScore}* on {EventDate}\n
             Reason: {EventType}\n<{AirtableRecordURL}|View vendor record>' } }
  ]
}
Gmail

Sends vendor escalation emails after the ops manager approves the draft. Agent 3 composes the message using a stored template and sends it via the Gmail API on behalf of the ops manager's Google Workspace account.

Auth method
OAuth 2.0 with delegated send. The ops manager's Google Workspace account grants domain-wide delegation to the service account, or alternatively the ops manager completes a one-time OAuth consent flow and the refresh token is stored in the credential store as GMAIL_REFRESH_TOKEN. Preferred: delegated send so the email appears from the manager's address.
Required scopes
https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.compose
Webhook / trigger setup
Gmail is output-only in this automation. No Gmail push notification or watch endpoint is configured. The send action is triggered by the ops manager's approval signal passed through the orchestration layer (approval recorded as a status update in Airtable or via a secure approval URL in the Slack message, depending on final build decision).
Required configuration
GMAIL_SENDER_ADDRESS: the From address (ops manager's email), stored in credential store. GMAIL_TEMPLATE_SUBJECT: subject line template string with {VendorName} placeholder. GMAIL_TEMPLATE_BODY_ID: identifier for the approved email body template stored in the credential store or a dedicated config table in Airtable. Placeholders in template: {VendorName}, {EventSummary}, {ResponseDeadlineDays} (default 5). The template must be approved by the ops manager before go-live and stored; changes to the template require a deliberate config update, not a code change.
Rate limits
Gmail API: 250 quota units/second per user, 1,000,000 units/day. Each send costs 100 units. At under 40 escalation emails/month, usage is negligible. Throttling is not required.
Constraints
The automation must never send a vendor email without a recorded approval event in the orchestration layer. The approval gate is non-negotiable and must be enforced in the workflow logic, not assumed. If the approval signal is absent or expired (more than 48 hours old), the draft must be discarded and the ops manager re-alerted via Slack.
// Gmail send payload (Agent 3 output, post-approval only)
POST https://gmail.googleapis.com/gmail/v1/users/me/messages/send
Headers: { Authorization: 'Bearer {access_token}' }
Body: {
  raw: base64url(RFC2822 message string)
}

// RFC2822 fields
From: {GMAIL_SENDER_ADDRESS}
To: {VendorContactEmail}  // sourced from Airtable Vendors record
Subject: {GMAIL_TEMPLATE_SUBJECT} (populated with VendorName)
Content-Type: text/plain; charset=UTF-8
Body: rendered template with {VendorName}, {EventSummary}, {ResponseDeadlineDays}

03Field mappings between tools

The following tables define the exact field mappings for each agent handoff. All field names are shown as they appear in the source and destination tool APIs. Use these mappings as the authoritative reference when configuring the orchestration layer.

Handoff 1: Xero to Airtable (Agent 1, Vendor Data Collection Agent)

Source tool
Source field
Destination tool
Destination field
Xero
`Contact.ContactID`
Airtable
`VendorID` (used to look up Vendors record ID)
Xero
`Contact.Name`
Airtable
`VendorName` (stub creation only if new vendor)
Xero
`InvoiceNumber`
Airtable
`EventNotes` (prefixed: 'Invoice: ')
Xero
`DateString`
Airtable
`EventDate`
Xero
`PurchaseOrder.DeliveryDate`
Airtable
`DeliveryVarianceDays` (computed: EventDate minus DeliveryDate in days)
Xero
`SubTotal`
Airtable
`BilledAmount`
Xero
`PurchaseOrder.SubTotal`
Airtable
`OrderedAmount`
Xero (computed)
`(BilledAmount / OrderedAmount) * 100`
Airtable
`InvoiceAccuracyPct`
Xero
`InvoiceID`
Airtable
`EventNotes` (appended: 'XeroID: {InvoiceID}')

Handoff 2: Airtable to Airtable and Google Sheets (Agent 2, Performance Scoring Agent)

Source tool
Source field
Destination tool
Destination field
Airtable (VendorEvents)
`DeliveryVarianceDays`
Airtable (Vendors)
`CurrentScore` (scoring model input)
Airtable (VendorEvents)
`InvoiceAccuracyPct`
Airtable (Vendors)
`CurrentScore` (scoring model input)
Airtable (Vendors)
`CurrentScore` (computed)
Airtable (Vendors)
`FlagStatus` ('Flagged' if below threshold, 'Clear' otherwise)
Airtable (Vendors)
`CurrentScore` (computed)
Airtable (Vendors)
`PerformanceSummary` (plain-English text generated by scoring agent)
Airtable (VendorEvents)
`EventDate`
Airtable (Vendors)
`LastEventDate`
Airtable (Vendors)
`CurrentScore`
Google Sheets
`CurrentScore` (column C, VendorScorecard tab)
Airtable (Vendors)
`FlagStatus`
Google Sheets
`FlagStatus` (column D, VendorScorecard tab)
Airtable (VendorEvents)
`EventDate`
Google Sheets
`LastUpdated` (column E, VendorScorecard tab)

Handoff 3: Airtable to Slack and Gmail (Agent 3, Escalation and Reporting Agent)

Source tool
Source field
Destination tool
Destination field
Airtable (Vendors)
`VendorName`
Slack
`text` and `blocks[].text.text` (vendor name in alert message)
Airtable (Vendors)
`CurrentScore`
Slack
`blocks[].text.text` (score value in alert message)
Airtable (Vendors)
`FlagStatus`
Slack
Conditional trigger: message sent only when FlagStatus = 'Flagged'
Airtable (VendorEvents)
`EventDate`
Slack
`blocks[].text.text` (event date in alert message)
Airtable (VendorEvents)
`EventNotes`
Slack
`blocks[].text.text` (event type / reason line)
Airtable (Vendors)
`VendorName`
Gmail
`{VendorName}` template placeholder in subject and body
Airtable (Vendors)
`PerformanceSummary`
Gmail
`{EventSummary}` template placeholder in body
Airtable (Vendors)
`VendorContactEmail`
Gmail
`To:` header field

Handoff 4: Airtable to Google Sheets (Agent 3, monthly report generation)

Source tool
Source field
Destination tool
Destination field
Airtable (VendorEvents)
`EventDate` (month filter)
Google Sheets
`ReportMonth` (column A, MonthlyReport tab)
Airtable (Vendors)
`VendorID`
Google Sheets
`VendorID` (column B)
Airtable (Vendors)
`VendorName`
Google Sheets
`VendorName` (column C)
Airtable (VendorEvents)
`ScoreAtEvent` (average per vendor per month)
Google Sheets
`AvgScore` (column D)
Airtable (Vendors)
`FlagStatus` count where Flagged
Google Sheets
`FlagCount` (column E)
Airtable (VendorEvents)
`EventNotes` (latest resolution note)
Google Sheets
`Resolution` (column F)
Orchestration layer
Timestamp of report generation
Google Sheets
`GeneratedAt` (column G)
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
One workflow per agent: three named workflows in the automation platform (Workflow_01_VendorDataCollection, Workflow_02_PerformanceScoring, Workflow_03_EscalationReporting). All workflows share a single centralised credential store. Inter-agent data passing is handled by writing a structured record to Airtable (VendorEvents table) at the end of Workflow_01, which triggers Workflow_02 via an internal record-created event. Workflow_03 is triggered by FlagStatus = 'Flagged' (event-driven) or a scheduled monthly cron (end-of-month report).
Agent 1 trigger mechanism
Webhook (preferred): Xero webhook POST to the orchestration platform's inbound URL on Invoice.Created, Invoice.Updated, and PurchaseOrder.Updated events. Signature validation on every request using HMAC-SHA256 with XERO_WEBHOOK_KEY. Fallback poll: if webhook delivery fails, a scheduled poll runs every 15 minutes querying Xero for invoices modified in the last 30 minutes. Deduplication by InvoiceID or PurchaseOrderID prevents double-processing.
Agent 2 trigger mechanism
Internal event: triggered by the orchestration layer immediately after Workflow_01 writes a new record to the Airtable VendorEvents table. No external webhook. No polling required. If Airtable write fails, Workflow_01 retries before Workflow_02 is invoked.
Agent 3 trigger mechanism (escalation)
Internal event: triggered by Workflow_02 when FlagStatus is set to 'Flagged' on a Vendors record. The flag value is passed directly in the inter-workflow payload; no additional Airtable poll is required for this branch.
Agent 3 trigger mechanism (monthly report)
Scheduled cron: fires at 08:00 local time on the last business day of each month. Business-day calculation must account for weekends; if the last calendar day is Saturday or Sunday, the cron fires on the preceding Friday. The orchestration platform's built-in scheduler handles this.
Approval gate (Gmail send)
After Agent 3 posts the Slack alert, it writes a pending approval record to Airtable (ApprovalStatus = 'Pending', ApprovalExpiry = now + 48 hours). A secure approval URL is included in the Slack message. When the ops manager clicks approve, the orchestration layer updates ApprovalStatus = 'Approved' and proceeds to Gmail send. If expiry is reached without approval, ApprovalStatus = 'Expired' and a follow-up Slack alert is sent.
Deduplication strategy
Xero InvoiceID and PurchaseOrderID are stored in a processed-events log within the credential store or a dedicated Airtable table. Before processing, Workflow_01 checks the log; duplicate IDs are skipped and logged.
Environment separation
Maintain separate credential store entries for TEST and PROD environments. All tool connections in TEST use sandbox/demo accounts. Promotion from TEST to PROD requires manual credential swap and a sign-off checklist review.

The following code block defines all entries required in the shared credential store. Every value listed here must be configured before any workflow is activated. No secret or ID may appear inline in any workflow step configuration.

All credential store entries. Values in angle brackets are set per environment (TEST / PROD). Never commit real values to version control.
// CREDENTIAL STORE CONTENTS
// Xero
XERO_CLIENT_ID           = '<Xero app client ID>'
XERO_CLIENT_SECRET       = '<Xero app client secret>'
XERO_TENANT_ID           = '<Xero organisation tenant ID>'
XERO_WEBHOOK_KEY         = '<Xero webhook signing key>'
XERO_REFRESH_TOKEN       = '<persisted OAuth refresh token>'

// Airtable
AIRTABLE_PAT             = '<Airtable Personal Access Token>'
AIRTABLE_BASE_ID         = '<base ID, format: appXXXXXXXXXXXXXX>'
AIRTABLE_VENDORS_TABLE_ID   = '<table ID for Vendors table>'
AIRTABLE_EVENTS_TABLE_ID    = '<table ID for VendorEvents table>'
AIRTABLE_APPROVAL_TABLE_ID  = '<table ID for Approvals table>'

// Google (shared service account for Sheets and Gmail)
GOOGLE_SA_KEY            = '<service account JSON key, base64-encoded>'
GMAIL_SENDER_ADDRESS     = '<ops manager email address>'
GMAIL_REFRESH_TOKEN      = '<OAuth refresh token for Gmail send, if not using SA delegation>'
SHEETS_SCORECARD_ID      = '<Google Sheets spreadsheet ID>'
SHEETS_SCORECARD_TAB     = 'VendorScorecard'
SHEETS_REPORT_TAB        = 'MonthlyReport'

// Slack
SLACK_BOT_TOKEN          = '<xoxb-... bot token>'
SLACK_OPS_CHANNEL_ID     = '<channel ID, format: CXXXXXXXXXX>'

// Gmail template config
GMAIL_TEMPLATE_SUBJECT   = 'Performance Notice: {VendorName}'
GMAIL_TEMPLATE_BODY_ID   = '<key referencing approved body template in config>'

// Scoring config
SCORE_THRESHOLD_FLAG     = '<numeric threshold below which vendor is flagged, e.g. 60>'
SCORE_THRESHOLD_CRITICAL = '<numeric threshold for critical flag, e.g. 40>'
APPROVAL_EXPIRY_HOURS    = '48'

// Processing log
PROCESSED_EVENTS_TABLE_ID = '<table ID for deduplication log>'

05Error handling and retry logic

Unhandled exceptions must never fail silently. Every integration point must write a structured error log entry and trigger a notification (Slack ops channel or email to support@gofullspec.com) when a failure cannot be resolved by the retry policy. Silent failures in a vendor scoring automation lead to missed flags, which directly defeats the purpose of the system.
Integration
Scenario
Required behaviour
Xero webhook
Inbound webhook signature validation fails
Reject with HTTP 401. Log the raw payload and headers. Do not process. Alert Slack ops channel. If 3 consecutive validation failures occur within 5 minutes, pause the webhook listener and alert support@gofullspec.com.
Xero API (data fetch)
401 Unauthorized (token expired)
Attempt token refresh using XERO_REFRESH_TOKEN. If refresh succeeds, retry the original request once. If refresh fails, log the error, send Slack alert to ops channel, and halt Workflow_01 until token is manually renewed. Do not proceed to Airtable write.
Xero API (data fetch)
429 Too Many Requests
Pause execution. Apply exponential backoff: retry after 2 s, then 4 s, then 8 s (max 3 retries). If all retries fail, log the event ID and add to a retry queue for processing at the next 15-minute poll cycle. Alert Slack ops channel if queue depth exceeds 10.
Xero API (data fetch)
500 or 503 Server Error from Xero
Apply exponential backoff as above (3 retries). If all fail, store the raw Xero event payload in the orchestration layer's error queue and retry after 30 minutes. Log and alert Slack ops channel. Do not drop the event.
Airtable (record write, Agent 1)
Rate limit exceeded (429) or timeout
Apply 200 ms inter-request delay by default. On 429, back off for 2 s and retry up to 3 times. If all retries fail, store the vendor event payload in the orchestration error queue and alert Slack ops channel. Do not proceed to Workflow_02.
Airtable (vendor lookup, Agent 1)
Vendor not found in Vendors table
Create a stub Vendors record with available fields (VendorID, VendorName from Xero Contact). Post a Slack alert to the ops channel: 'New vendor detected: {VendorName}. Stub record created in Airtable. Manual review required before next scoring run.' Proceed with event write but skip scoring until stub is confirmed.
Google Sheets (scorecard write, Agent 2)
Vendor row not found in scorecard tab
Create a new row for the vendor using the defined column layout. Post a Slack alert to the ops channel notifying of the new scorecard row. Log the action. Do not overwrite existing rows.
Google Sheets (scorecard write, Agent 2)
API returns 403 Forbidden
Log the error with full context. Halt Agent 2 scorecard write. Alert Slack ops channel immediately with the vendor name and score that failed to write. Alert support@gofullspec.com. Manual scorecard update required until access is restored. Do not silently skip the write.
Slack (alert post, Agent 3)
not_in_channel error (bot removed from channel)
Catch the Slack API error. Fall back to sending an alert email to the ops manager's Gmail address (GMAIL_SENDER_ADDRESS) with the same alert content. Log the Slack error. Alert support@gofullspec.com to reinstate the bot. Do not suppress the vendor flag.
Gmail (vendor email send, Agent 3)
Send attempted without valid approval record
Block the send unconditionally. Log the attempt with timestamp and vendor ID. Alert Slack ops channel: 'Gmail send blocked: no approval on record for {VendorName}. Manual review required.' This scenario must never result in an email being sent. The approval gate is enforced at the workflow logic level, not at the API call level alone.
Gmail (vendor email send, Agent 3)
Approval record expired (over 48 hours old)
Discard the draft. Update Airtable ApprovalStatus to 'Expired'. Post a follow-up Slack alert to the ops manager: 'Approval window expired for vendor email to {VendorName}. Please review and re-approve if action is still required.' Reset the approval flow if the manager responds.
Monthly report cron (Agent 3)
Airtable query returns no records for the month
Log the empty result. Write a placeholder row to the MonthlyReport tab: ReportMonth, 'No events recorded this month', GeneratedAt. Post a Slack alert to the ops channel noting the empty report. Do not skip the report generation step, as a missing row in the report tab is itself an anomaly flag.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Vendor Performance Tracking.

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