FS-DOC-05Technical
Integration and API Spec
Data Quality Monitoring
[YourCompany.com] · IT Department · Prepared by FullSpec · [Today's Date]
This document is the authoritative technical reference for every external tool connection used in the Data Quality Monitoring automation. It covers authentication methods, required OAuth scopes, webhook and trigger configuration, field-level data mappings between agents, the credential store layout, and the full error-handling and retry behaviour at each integration point. The FullSpec team uses this specification during build and QA; it is the source of truth for any credential, scope, or mapping decision made during development.
01Tool inventory
Tool
Role in automation
Auth method
Min plan required
Used by agents
Orchestration layer
Hosts all three workflow agents, manages scheduling, credential store, and inter-agent handoffs
Internal service account (platform-managed)
N/A
All agents
PostgreSQL
Primary data source; queried on schedule by the Data Check Agent to retrieve records for quality rule evaluation
Service account credentials (host, port, db name, read-only username, password)
Any self-hosted or managed instance with network access
Agent 1
Airtable
Issue log and audit trail; receives every detected issue row; also read by the Reporting Agent for weekly aggregation
Personal Access Token (PAT)
Team plan ($20/month)
Agents 1, 2, 3
Google Sheets
Ruleset configuration store and legacy reference data; read at the start of each check run to load active rules
OAuth 2.0 (service account JSON key)
Google Workspace or free account with API enabled
Agent 1
Jira
Ticket creation for critical and high-severity issues; updated by the Issue Routing and Notification Agent
OAuth 2.0 (3-legged) or API token (Basic Auth)
Free or Standard plan (Cloud)
Agent 2
Slack
Real-time formatted alert to the IT channel after each check run; posted by the Issue Routing and Notification Agent
Bot token (OAuth 2.0)
Free or Pro plan
Agent 2
Datadog
Weekly quality metrics dashboard; receives aggregated issue counts and severity breakdown from the Reporting Agent
API key + Application key
Free tier or Infrastructure plan ($15+/host/month)
Agent 3
Before you connect anything: sandbox-test every integration against a non-production environment before entering live credentials. For PostgreSQL use a read-only replica or a dev schema. For Airtable, Jira, and Datadog create dedicated sandbox bases, projects, and orgs. Confirm that all firewall rules permit outbound connections from the automation platform's IP range before beginning the Standard build.
Integration and API SpecPage 1 of 4
FS-DOC-05Technical
02Per-tool integration detail
PostgreSQL
Read-only connection to the primary database. The Data Check Agent issues parameterised SELECT queries against configured tables on each scheduled run. No write operations are performed against PostgreSQL by any agent.
Auth method
Username and password over TLS. A dedicated read-only service account (e.g. dq_monitor_ro) must be created with SELECT privileges on the target schemas only. Password stored in the credential store, never hardcoded.
Required scopes
Database-level: CONNECT; Schema-level: USAGE; Table-level: SELECT on all monitored tables. No INSERT, UPDATE, DELETE, or DDL privileges granted.
Trigger / connection setup
No webhook. The orchestration layer opens a connection on the scheduled trigger (daily, configurable time) and closes it after each query batch. Connection pooling max 5 concurrent connections. SSL mode: require.
Required configuration
PG_HOST, PG_PORT (default 5432), PG_DBNAME, PG_USER, PG_PASSWORD stored in credential store. Target table names and monitored field names loaded from the Google Sheets ruleset config at runtime, not hardcoded. Firewall must whitelist the automation platform's egress IP range.
Rate limits
No enforced API rate limit. At ~120 check events/month (roughly 4/day), query load is negligible. No throttling needed at current volume. Monitor query execution time; add a 30-second timeout to prevent runaway queries.
Constraints
Connection must be TLS-encrypted. Service account must not have superuser or replication privileges. If the database is behind a VPN, a static egress IP or VPN tunnel configuration is required before build starts.
// Input
Ruleset array loaded from Google Sheets (table_name, field_name, rule_type, threshold)
// Query pattern
SELECT <monitored_fields> FROM <table_name> WHERE updated_at >= NOW() - INTERVAL '24 hours'
// Output
Row array: { table, field, row_id, raw_value, rule_violated, severity_score }Airtable
Used in two roles: as a write target for the issue log (Agents 1 and 2) and as a read source for weekly aggregation (Agent 3). A single base contains the Issues table and the Runs table.
Auth method
Personal Access Token (PAT). Generate a PAT with the minimum required scopes below. Store as AIRTABLE_PAT in the credential store.
Required scopes
data.records:read, data.records:write, schema.bases:read. No schema.bases:write required unless the Issues table structure is managed programmatically (not recommended).
Webhook / trigger setup
Airtable webhooks are used optionally to notify Agent 2 of manual status updates made by the IT analyst (e.g. marking an issue resolved). Configure via POST /v0/bases/{baseId}/webhooks with event type: tableData.changed on the Issues table. Webhook delivery is to the orchestration layer's inbound webhook URL. Validate the X-Airtable-Client-Secret header on receipt.
Required configuration
AIRTABLE_BASE_ID and AIRTABLE_ISSUES_TABLE_ID stored in credential store. Table structure: Issues table must contain fields: issue_id (autonumber), source_table (text), field_name (text), rule_violated (text), affected_row_count (number), severity (single select: Critical/High/Moderate/Low), jira_ticket_key (text), status (single select: Open/In Progress/Resolved), detected_at (datetime), resolved_at (datetime). Do not rename these fields post-launch without updating field mappings.
Rate limits
Airtable REST API: 5 requests/second per base. At ~120 check events/month with an average of 15 issue rows per run, peak write load is approximately 75 writes in a burst. Add a 200ms inter-request delay in the write loop. No sustained throttling required at current volume.
Constraints
PAT must be rotated every 90 days. The base must be on the Team plan to support the required record count and API access. Airtable field type changes (e.g. text to select) will break writes silently; document any schema changes in the runbook before applying them.
// Input (Agent 1 write)
Issue object: { source_table, field_name, rule_violated, affected_row_count, severity, detected_at }
// Output (Agent 3 read)
Filtered records: issues WHERE detected_at >= start_of_week AND detected_at <= end_of_week
// Aggregated output to Reporting Agent
{ total_issues, critical_count, high_count, moderate_count, low_count, resolved_count, open_count }Google Sheets
Read-only at runtime. The Data Check Agent reads the active ruleset from a designated Google Sheet at the start of each check run. This sheet is the single source of truth for which tables, fields, and rule types are active.
Auth method
OAuth 2.0 using a Google service account JSON key. The key file path or JSON content is stored as GOOGLE_SERVICE_ACCOUNT_JSON in the credential store. The service account is granted Viewer access to the ruleset sheet only.
Required scopes
https://www.googleapis.com/auth/spreadsheets.readonly, https://www.googleapis.com/auth/drive.readonly (required to resolve sheet ID from filename if not using direct spreadsheet ID).
Trigger / webhook setup
No webhook. The sheet is read via a single GET call to the Sheets API (spreadsheets.values.get) at the start of each scheduled run. No push notification required.
Required configuration
GOOGLE_SHEETS_RULESET_ID (the spreadsheet ID, not the URL) stored in credential store. Sheet tab name must be Rules (case-sensitive). Expected columns: table_name, field_name, rule_type, parameter, severity_weight, active (boolean). The service account email must be added as a Viewer on the sheet; sharing via a link is not sufficient for service account access.
Rate limits
Google Sheets API: 300 read requests/minute per project, 60 per minute per user. A single read per daily run produces approximately 30 requests/month. No throttling needed.
Constraints
The service account JSON key must not be committed to version control. If the sheet is moved to a new spreadsheet ID, GOOGLE_SHEETS_RULESET_ID must be updated in the credential store and the agent redeployed. Column order in the Rules tab must not change without updating the parsing logic.
// Input
GET https://sheets.googleapis.com/v4/spreadsheets/{RULESET_ID}/values/Rules
// Output
Ruleset array: [{ table_name, field_name, rule_type, parameter, severity_weight, active }]
// Filtered at runtime
Only rows where active == true are passed to the rules engineJira
Used by the Issue Routing and Notification Agent to create tickets for Critical and High severity issues. Each ticket is pre-filled with structured issue detail. No ticket update or deletion operations are performed by the automation.
Auth method
API token with Basic Auth (Base64-encoded user:token). Recommended over OAuth 2.0 for server-to-server use. Store as JIRA_BASE_URL, JIRA_USER_EMAIL, and JIRA_API_TOKEN in the credential store.
Required scopes
Jira Cloud API token scopes are tied to the user account. The service account user must have: Create Issues permission on the target project; Browse Projects permission; no admin privileges required. For OAuth 2.0 (if preferred): write:jira-work, read:jira-work.
Webhook / trigger setup
No inbound webhook to Jira required for this build. Outbound only: POST /rest/api/3/issue. The Jira project key and issue type ID must be stored in the credential store, not hardcoded.
Required configuration
JIRA_PROJECT_KEY (e.g. DQ), JIRA_ISSUE_TYPE_ID (retrieve via GET /rest/api/3/issuetype and store the numeric ID for Bug or Task), JIRA_BASE_URL stored in credential store. Ticket fields populated: summary (Issue: {field_name} in {source_table} - {rule_violated}), description (structured ADF body with affected_row_count, severity, detected_at, Airtable record link), priority mapped from severity (Critical=Highest, High=High), labels: [data-quality, automated].
Rate limits
Jira Cloud REST API: 10 requests/second sustained, burst to 20. At 120 check events/month with an average of 5 critical/high issues per run, peak is approximately 25 ticket creates in a single run. No throttling required at current volume. Add 100ms delay between sequential creates as a safeguard.
Constraints
The Jira project must exist before build starts; the automation does not create projects. The JIRA_ISSUE_TYPE_ID is numeric and environment-specific: retrieve and store it separately for sandbox and production. API tokens are tied to a user account; use a dedicated service account (e.g. dq-automation@yourdomain.com) so tokens survive staff changes.
// Input
Critical/High issues from Airtable write: { field_name, source_table, rule_violated, affected_row_count, severity, airtable_record_url }
// POST /rest/api/3/issue
{ project: { key: JIRA_PROJECT_KEY }, issuetype: { id: JIRA_ISSUE_TYPE_ID }, summary, description (ADF), priority, labels }
// Output
{ id, key, self } -> key stored back to Airtable Issues row as jira_ticket_keySlack
Used by the Issue Routing and Notification Agent to post a formatted summary message to the IT channel after each check run. One message per run, not one message per issue.
Auth method
Bot token (xoxb-...) generated via a Slack App with the required scopes. Store as SLACK_BOT_TOKEN in the credential store. The app must be installed to the workspace and invited to the target channel.
Required scopes
chat:write (post messages as the bot), chat:write.public (post to public channels without being a member, optional), channels:read (verify channel ID at startup). No files:write or users:read required.
Webhook / trigger setup
Outbound only: POST https://slack.com/api/chat.postMessage. The SLACK_CHANNEL_ID (not channel name) is stored in the credential store. Channel name can change; ID does not. Alternatively, an Incoming Webhook URL may be used (SLACK_WEBHOOK_URL) for simpler setup, but does not support block kit threading without the bot token approach.
Required configuration
SLACK_CHANNEL_ID or SLACK_WEBHOOK_URL stored in credential store. Message format: Slack Block Kit with a header block (run summary), a section block per severity tier (Critical: N, High: N, Moderate: N, Low: N), and a context block with direct links to newly created Jira tickets and the Airtable Issues view. Message posted only if at least one issue was found; suppress empty-run notifications (configurable flag SLACK_SUPPRESS_CLEAN_RUNS stored in config).
Rate limits
Slack Web API: Tier 3 rate limit on chat.postMessage, 50 requests/minute. One message per daily run yields approximately 30 messages/month. No throttling needed.
Constraints
The bot must be invited to the channel before the first run; the API returns channel_not_found otherwise. Do not post the bot token in message text. The Block Kit payload must not exceed 3000 characters per block or 50 blocks per message; the current template is well within limits.
// Input
Run summary: { run_timestamp, total_issues, critical_count, high_count, moderate_count, low_count, jira_tickets_created: [key, url], airtable_view_url }
// POST https://slack.com/api/chat.postMessage
{ channel: SLACK_CHANNEL_ID, blocks: [...Block Kit JSON...] }
// Output
{ ok: true, ts, channel } -> ts stored for optional thread repliesDatadog
Used by the Reporting and Metrics Agent to push aggregated weekly quality metrics as custom metric series. The Datadog dashboard is pre-configured with widgets that visualise these metrics over time.
Auth method
API key for metric submission (DD-API-KEY header). Application key required for dashboard management operations only (DD-APPLICATION-KEY header). Store as DATADOG_API_KEY and DATADOG_APP_KEY in the credential store.
Required scopes
API key: metrics:write (submit time series). Application key (if dashboard is managed via API): dashboards:read, dashboards:write. No logs:write or monitors:write required for this build.
Webhook / trigger setup
No inbound webhook from Datadog. Outbound only: POST https://api.datadoghq.com/api/v2/series (metrics intake v2). Triggered on the weekly schedule after the final daily check run of the week completes.
Required configuration
DATADOG_API_KEY, DATADOG_APP_KEY, DATADOG_SITE (e.g. datadoghq.com or datadoghq.eu) stored in credential store. Custom metric names (must be agreed and stored in config, not hardcoded): dq.issues.total, dq.issues.critical, dq.issues.high, dq.issues.moderate, dq.issues.low, dq.issues.resolved, dq.resolution_rate. Tags applied to every metric point: env:production, source:data-quality-automation. Dashboard ID stored as DATADOG_DASHBOARD_ID for reference; widgets query by metric name.
Rate limits
Datadog metrics intake: 500,000 metric points/hour by default. The weekly push submits 7 metric series, each with one data point, totalling 7 points per week. No throttling needed.
Constraints
Custom metrics count against the Datadog account's billable metric limit. Seven metrics are introduced; confirm with the account owner that this is within the current plan quota. Metric names, once used in dashboards, should not be renamed without updating dashboard widget queries. The Datadog site parameter must match the account region; mismatches produce silent 403 errors.
// Input
Weekly aggregates from Airtable: { week_start, total_issues, critical, high, moderate, low, resolved, open }
// POST https://api.datadoghq.com/api/v2/series
{ series: [{ metric: 'dq.issues.total', type: 'gauge', points: [{ timestamp, value }], tags }] }
// Output
HTTP 202 Accepted -> log response; non-202 triggers retry with exponential backoffIntegration and API SpecPage 2 of 4
FS-DOC-05Technical
03Field mappings between tools
The following tables define the exact field mappings at each agent handoff point. Use the monospace field names verbatim when configuring the orchestration layer. Any deviation will cause silent mapping failures or schema validation errors.
Handoff A: Data Check Agent output to Airtable Issues log (Agent 1 writes, Agents 2 and 3 read)
Source tool
Source field
Destination tool
Destination field
PostgreSQL / rules engine
table_name
Airtable
source_table
PostgreSQL / rules engine
field_name
Airtable
field_name
PostgreSQL / rules engine
rule_violated
Airtable
rule_violated
PostgreSQL / rules engine
affected_row_count
Airtable
affected_row_count
Rules engine (computed)
severity_score
Airtable
severity
Orchestration layer (system)
run_timestamp
Airtable
detected_at
Static default
"Open"
Airtable
status
Orchestration layer (empty at write)
null
Airtable
jira_ticket_key
Orchestration layer (empty at write)
null
Airtable
resolved_at
Handoff B: Airtable Issues log to Jira ticket creation (Agent 2 reads Airtable, writes Jira)
Source tool
Source field
Destination tool
Destination field
Airtable
field_name
Jira
fields.summary (partial: see template)
Airtable
source_table
Jira
fields.summary (partial)
Airtable
rule_violated
Jira
fields.summary (partial) + fields.description
Airtable
affected_row_count
Jira
fields.description (ADF body)
Airtable
severity
Jira
fields.priority.name (Critical->Highest, High->High)
Airtable
detected_at
Jira
fields.description (ADF body)
Airtable
record_url (computed)
Jira
fields.description (ADF link)
Static config
JIRA_PROJECT_KEY
Jira
fields.project.key
Static config
JIRA_ISSUE_TYPE_ID
Jira
fields.issuetype.id
Static value
["data-quality", "automated"]
Jira
fields.labels
Handoff C: Jira ticket key written back to Airtable (Agent 2, post-create)
Source tool
Source field
Destination tool
Destination field
Jira (create response)
key
Airtable
jira_ticket_key
Jira (create response)
self
Airtable
jira_ticket_key (URL appended)
Handoff D: Airtable Issues log to Slack alert (Agent 2 reads Airtable, writes Slack)
Source tool
Source field
Destination tool
Destination field
Airtable (aggregated)
total_issues_this_run
Slack
blocks[0].text (header)
Airtable (aggregated)
critical_count
Slack
blocks[1].fields[0].text
Airtable (aggregated)
high_count
Slack
blocks[1].fields[1].text
Airtable (aggregated)
moderate_count
Slack
blocks[1].fields[2].text
Airtable (aggregated)
low_count
Slack
blocks[1].fields[3].text
Jira (list of created keys)
ticket_links[]
Slack
blocks[2].elements[].url
Airtable
airtable_view_url (static config)
Slack
blocks[2].elements[-1].url
Handoff E: Airtable Issues log to Datadog metrics (Agent 3 reads Airtable, writes Datadog)
Source tool
Source field
Destination tool
Destination field
Airtable (weekly count)
total_issues
Datadog
dq.issues.total (gauge)
Airtable (weekly count)
critical_count
Datadog
dq.issues.critical (gauge)
Airtable (weekly count)
high_count
Datadog
dq.issues.high (gauge)
Airtable (weekly count)
moderate_count
Datadog
dq.issues.moderate (gauge)
Airtable (weekly count)
low_count
Datadog
dq.issues.low (gauge)
Airtable (weekly count)
resolved_count
Datadog
dq.issues.resolved (gauge)
Computed (resolved/total)
resolution_rate
Datadog
dq.resolution_rate (gauge, 0.0-1.0)
Orchestration layer
week_end_unix_timestamp
Datadog
series[*].points[0].timestamp
Integration and API SpecPage 3 of 4
FS-DOC-05Technical
04Build stack and orchestration
Orchestration layout
Three separate workflows, one per agent. Each workflow is independently deployable and versionable. A shared credential store is referenced by all three workflows; no credentials are stored inside individual workflow definitions.
Agent 1 trigger (Data Check Agent)
Time-based schedule: fires daily at a configurable UTC time (default 02:00 UTC). Also supports an inbound webhook trigger to fire immediately on receipt of a data import event notification. Webhook payload must include a source_id field matching a configured data source. Inbound webhook endpoint requires HMAC-SHA256 signature validation using WEBHOOK_SECRET stored in the credential store; reject any request where the X-Signature-256 header does not match.
Agent 2 trigger (Issue Routing and Notification Agent)
Triggered by Agent 1 completion event via an inter-workflow call or a shared message queue entry. Agent 2 receives the structured issue list as its input payload. No external webhook; internal trigger only.
Agent 3 trigger (Reporting and Metrics Agent)
Weekly schedule: fires every Sunday at 04:00 UTC (after the final daily check of the week completes). No webhook. Reads Airtable for the preceding Monday-to-Sunday window.
Inter-agent data passing
Agent 1 outputs the issue list to a shared workflow variable or a lightweight queue entry. Agent 2 consumes this on trigger. Do not use a database or Airtable as the inter-agent bus; use the orchestration layer's native pass-through mechanism.
Credential store
All secrets are stored in the orchestration platform's encrypted credential store (environment variables or secrets vault). No credential, API key, token, or password appears in workflow logic, code nodes, or log output. See credential store contents below.
Logging and observability
Each workflow emits a structured run log entry on completion: { agent, run_id, status, issues_found, duration_ms, timestamp }. Errors are logged with error_code, tool, and message fields. Logs must be retained for a minimum of 90 days.
All values stored in the orchestration platform's encrypted secrets store. Never hardcode, log, or expose these values in workflow definitions or error messages.
// CREDENTIAL STORE CONTENTS
// PostgreSQL
PG_HOST=<database-hostname-or-ip>
PG_PORT=5432
PG_DBNAME=<target-database-name>
PG_USER=dq_monitor_ro
PG_PASSWORD=<read-only-service-account-password>
// Google Sheets (service account)
GOOGLE_SERVICE_ACCOUNT_JSON=<full JSON key content or file path>
GOOGLE_SHEETS_RULESET_ID=<spreadsheet-id-from-sheet-url>
// Airtable
AIRTABLE_PAT=<personal-access-token>
AIRTABLE_BASE_ID=<base-id-starting-app...>
AIRTABLE_ISSUES_TABLE_ID=<table-id-starting-tbl...>
AIRTABLE_VIEW_URL=<url-of-Issues-view-for-Slack-links>
// Jira
JIRA_BASE_URL=https://<your-subdomain>.atlassian.net
JIRA_USER_EMAIL=dq-automation@yourdomain.com
JIRA_API_TOKEN=<api-token-from-atlassian-account-settings>
JIRA_PROJECT_KEY=DQ
JIRA_ISSUE_TYPE_ID=<numeric-id-retrieved-from-issuetype-endpoint>
// Slack
SLACK_BOT_TOKEN=xoxb-<bot-token>
SLACK_CHANNEL_ID=<channel-id-not-channel-name>
SLACK_SUPPRESS_CLEAN_RUNS=true
// Datadog
DATADOG_API_KEY=<api-key>
DATADOG_APP_KEY=<application-key>
DATADOG_SITE=datadoghq.com
DATADOG_DASHBOARD_ID=<dashboard-id-for-reference>
// Inbound webhook (Agent 1 import event trigger)
WEBHOOK_SECRET=<hmac-sha256-shared-secret>
// Orchestration config
CHECK_SCHEDULE_UTC=02:00
REPORT_SCHEDULE_UTC=Sunday 04:00
Maintain a separate set of sandbox credentials for every tool. Sandbox and production credential sets must be stored in distinct named environments within the credential store (e.g. env: sandbox, env: production). Never use production credentials during development or QA runs.
05Error handling and retry logic
Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently. Every error must be logged with tool, error_code, run_id, timestamp, and message, and must either retry with backoff, route to a manual fallback, or post a degraded-run alert to Slack.
Integration
Scenario
Required behaviour
PostgreSQL
Connection refused or timeout on scheduled query
Retry 3 times with exponential backoff (30s, 2min, 5min). If all retries fail, log error and post a Slack alert to SLACK_CHANNEL_ID: 'Data Check Agent: PostgreSQL connection failed. Manual check required.' Do not proceed to Airtable write or Jira creation for this run.
PostgreSQL
Query returns zero rows (possible empty table or schema change)
Do not treat as a clean run. Log a warning: 'Zero rows returned from {table_name}. Verify table is populated and schema has not changed.' Post a Slack warning alert. Skip issue scoring for that table and continue with remaining tables.
Google Sheets
Ruleset sheet unreadable (permission error or sheet deleted)
Abort the entire check run. Log error: 'Ruleset sheet unavailable. Agent 1 run aborted.' Post Slack alert. Do not run checks with a stale or empty ruleset. Retry once after 60 seconds before aborting.
Airtable
Write fails due to rate limit (429 response)
Respect Retry-After header if present; otherwise wait 1 second and retry up to 5 times with linear backoff. If all retries fail, write the failed issue rows to the orchestration layer's run log as a fallback record. Post a Slack warning: 'Airtable write partial failure. {N} issues not logged. See run log {run_id}.'
Airtable
Schema mismatch (field renamed or deleted)
Catch the 422 Unprocessable Entity response. Log error with field name and table ID. Abort the write for that record. Post a Slack alert: 'Airtable schema mismatch detected. Issues log may be incomplete. Check field mapping for table {table_id}.' Do not silently skip.
Jira
Ticket creation fails (401 Unauthorized)
Log error immediately. Post Slack alert: 'Jira authentication failed. Tickets not created for this run. Verify JIRA_API_TOKEN and JIRA_USER_EMAIL.' Do not retry with the same credentials. Mark affected Airtable issues with jira_ticket_key = 'CREATION_FAILED' so they are identifiable for manual follow-up.
Jira
Ticket creation fails (400 Bad Request, e.g. invalid issue type or project key)
Log the full response body. Do not retry. Post Slack alert with the error detail. Mark affected Airtable rows as CREATION_FAILED. The FullSpec team must be notified via support@gofullspec.com if this occurs in production; it indicates a configuration drift.
Slack
Message post fails (channel_not_found or token revoked)
Log the error. Attempt one retry after 30 seconds. If retry fails, write the alert summary to the orchestration run log only. Do not silently drop the notification. The run log entry must include all fields that would have appeared in the Slack message.
Slack
Message payload exceeds block kit size limits
Truncate the issue list in the Slack message to the top 5 critical issues and append a note: 'And {N} more. View full list in Airtable: {AIRTABLE_VIEW_URL}.' Never reject the run; always send a reduced message rather than nothing.
Datadog
Metric submission returns non-202 (e.g. 403 invalid API key, 400 malformed series)
Retry twice with 60-second backoff. If both retries fail, log the full response. Post a Slack alert: 'Datadog metrics push failed for week ending {date}. Dashboard may be stale. See run log {run_id}.' The weekly aggregates must be retained in the run log so they can be manually submitted if needed.
Inbound webhook (Agent 1)
Request received with invalid or missing HMAC signature
Reject immediately with HTTP 401. Log the source IP and timestamp. Do not trigger the check run. Do not post to Slack for individual rejected requests; log to the orchestration audit trail only. If more than 5 invalid requests arrive within 10 minutes, post a Slack security alert.
All integrations
Unhandled exception or unexpected error type not covered above
Catch all unhandled exceptions at the workflow level. Log with stack trace, tool context, and run_id. Post a Slack alert: 'Unhandled error in {agent_name} run {run_id}. Manual review required. Contact support@gofullspec.com.' Never allow a run to terminate without a log entry.
The Slack channel defined by SLACK_CHANNEL_ID serves as the primary operational alerting surface for all error conditions. If Slack itself is unavailable, the orchestration run log is the fallback record of all errors. Ensure the run log is accessible to the IT analyst without requiring the automation platform UI, for example via a readable log export or a monitoring endpoint.
Integration and API SpecPage 4 of 4