Back to Event & Webinar Promotion

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

Event and Webinar Promotion Automation

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

This document is the authoritative technical reference for every integration point in the Event and Webinar Promotion automation. It covers tool inventory, exact OAuth scopes, webhook and trigger configuration, field mappings between agents, credential store layout, orchestration design, and failure behaviour at each integration boundary. The FullSpec team uses this specification to build and validate all connections. No credentials or integration identifiers should ever be hardcoded in workflow definitions; every value listed here belongs in the shared credential store.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agents
Google Sheets
Event brief input trigger; metrics write-back
OAuth 2.0 (service account)
Google Workspace Business Starter (or free with service account)
Agent 1, Agent 3
Zoom
Webinar registration creation; post-event attendance pull
OAuth 2.0 (Server-to-Server app)
Zoom Pro or higher (Webinar add-on required)
Agent 1, Agent 3
HubSpot
Email sequence activation; contact create/update; follow-up send
Private App token (OAuth 2.0)
Marketing Hub Starter (sequences require Sales Hub Starter or higher)
Agent 1, Agent 3
LinkedIn
Schedule three promotional posts to a LinkedIn Page
OAuth 2.0 (LinkedIn Marketing Developer Platform)
LinkedIn Page with admin access; approved Marketing API access
Agent 2
Slack
Internal launch notification to designated channel
Bot token (OAuth 2.0 Bot scope)
Slack Free or higher
Agent 2
Automation platform
Orchestration layer; workflow scheduling; credential store; retry logic
N/A (internal)
N/A
All agents
Before you connect anything: create isolated sandbox or test accounts for every tool listed above and validate all credentials and scope grants in those environments before promoting any connection to production. Do not use live HubSpot contact lists, the production Zoom account, or the active LinkedIn Page during initial build and QA.

02Per-tool integration detail

Google Sheets

Used as the event brief source of truth and as the metrics write-back destination. The automation platform polls the designated event sheet for new rows where the Status column equals 'Confirmed'. It also writes registration count, attendance count, and email engagement figures back to the same row after the event completes.

Auth method
OAuth 2.0 via a Google Cloud service account. The service account JSON key is stored in the credential store (key: GSHEETS_SERVICE_ACCOUNT_JSON). The target spreadsheet must be shared with the service account email as Editor.
Required scopes
https://www.googleapis.com/auth/spreadsheets | https://www.googleapis.com/auth/drive.readonly
Trigger setup
Poll-based. The orchestration layer polls the sheet every 5 minutes via the Google Sheets API v4 GET /v4/spreadsheets/{spreadsheetId}/values/{range} endpoint. New rows where column Status = 'Confirmed' and column Processed = '' (empty) are treated as trigger events. After processing, the platform writes 'Processed' into that column to prevent duplicate runs.
Required configuration
GSHEETS_SPREADSHEET_ID stored in credential store. Named ranges must be defined: EventBriefInput (columns A through M, starting row 2) and MetricsOutput (columns N through R). Sheet tab name must be 'Event Calendar'. Column headers must match field mapping exactly (see Section 03).
Rate limits
Google Sheets API: 300 read requests/minute per project, 60 read requests/minute per user. At a volume of 3 to 6 events/month with 5-minute polling, peak read load is approximately 288 requests/day, well within quota. No throttling needed at current volume. Write operations for metrics: 1 write per event, negligible.
Constraints
Service account must not be revoked or the key rotated without updating the credential store. Rows deleted from the sheet will not trigger the automation. The sheet must remain in the format defined at build time; adding or removing columns requires a mapping update.
// Trigger read
GET /v4/spreadsheets/{GSHEETS_SPREADSHEET_ID}/values/EventBriefInput
// Metrics write-back
PUT /v4/spreadsheets/{GSHEETS_SPREADSHEET_ID}/values/MetricsOutput!N{row}:R{row}
  body: { values: [[registrant_count, attendee_count, no_show_count, email_open_rate, processed_at]] }
Zoom

Used by Agent 1 (Event Setup) to create the webinar registration and capture the registration URL, and by Agent 3 (Post-Event Sync) to retrieve the participant report after the event ends.

Auth method
OAuth 2.0 Server-to-Server app. Client ID and Client Secret are stored in the credential store (keys: ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET, ZOOM_ACCOUNT_ID). Access tokens are obtained via POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={ZOOM_ACCOUNT_ID} and cached until expiry (typically 1 hour).
Required scopes
webinar:write:admin | webinar:read:admin | report:read:admin
Webhook setup
No inbound webhook required for the current build. Agent 1 creates the webinar on demand; Agent 3 polls the Zoom Report API after the scheduled event end time. If a real-time registrant webhook is added in a future iteration, the endpoint event type webinar.registration_created must be validated with the Zoom webhook secret token (ZOOM_WEBHOOK_SECRET_TOKEN in the credential store).
Required configuration
ZOOM_WEBINAR_HOST_ID (the Zoom user ID of the host account, stored in credential store). Webinar settings template: registration_type=1 (required), approval_type=0 (automatic approval). The registration link is extracted from the response field join_url and passed downstream.
Rate limits
Zoom API rate limit: 30 requests per second per account for most endpoints; Dashboard and Report endpoints are capped at 20 requests/second. At 3 to 6 events/month with one webinar creation and one report pull per event, peak load is under 15 API calls/month. No throttling needed at current volume.
Constraints
The Webinar add-on must be active on the Zoom account. Attendance report data is only available after the host formally ends the session using the End Meeting for All control. If the host leaves early without ending the session, the report endpoint returns an empty participant list. A manual override mechanism must be implemented (see Section 05).
// Agent 1: Create webinar
POST https://api.zoom.us/v2/users/{ZOOM_WEBINAR_HOST_ID}/webinars
  body: { topic, start_time, duration, agenda, settings: { registration_type: 1, approval_type: 0 } }
// Response: extract join_url -> stored as event.zoom_registration_url
// Agent 3: Pull attendance report
GET https://api.zoom.us/v2/report/webinars/{webinarId}/participants
  query: { page_size: 300 }
// Response: participants[].status ('joined' | 'left') mapped to attendance_status
HubSpot

Used by Agent 1 to activate the pre-built email sequence for the confirmed event contact list, and by Agent 3 to create or update contact records with attendance tags and trigger segmented follow-up emails.

Auth method
HubSpot Private App token. The token is stored in the credential store (key: HUBSPOT_PRIVATE_APP_TOKEN) and passed as the Authorization: Bearer header on all requests. No OAuth redirect flow is required for Private Apps.
Required scopes
crm.objects.contacts.read | crm.objects.contacts.write | crm.lists.read | crm.lists.write | automation.sequences.read | automation.sequences.write | marketing.emails.read | marketing.emails.write | timeline | content
Trigger setup
No inbound webhook required. Agent 1 calls the Sequences Enroll endpoint to activate the sequence. Agent 3 calls the Contacts upsert endpoint. HubSpot workflows may fire downstream on contact property changes; ensure no conflicting internal HubSpot workflows overlap with automation-managed sequences.
Required configuration
HUBSPOT_SEQUENCE_ID (the ID of the pre-built announcement-and-reminder sequence, stored in credential store). HUBSPOT_ATTENDEE_FOLLOW_UP_EMAIL_ID and HUBSPOT_NOSHOW_FOLLOW_UP_EMAIL_ID (stored in credential store). Contact property custom fields required: event_name (single-line text), event_date (date), attendance_status (dropdown: registered, attended, no-show), event_tags (multi-line text). HubSpot list ID for the target audience stored as HUBSPOT_EVENT_LIST_ID.
Rate limits
HubSpot API v3: 100 requests per 10 seconds (burst), 40,000 requests per day on Marketing Hub Starter. At 3 to 6 events/month with up to 300 contacts per event, peak daily volume is approximately 1,800 contact upsert calls plus sequence enrolments, well within limits. Implement a 100ms delay between batched contact upserts to avoid burst limit hits.
Constraints
Sequences can only be enrolled via API if the enrolling user (associated with the Private App) has a paid Sales Hub seat. Confirm seat assignment before build. Sending follow-up emails via the API requires that email templates are published and not in draft state. Contact list structure must match the automation's assumptions before launch.
// Agent 1: Enrol contacts in sequence
POST https://api.hubapi.com/automation/v4/sequences/{HUBSPOT_SEQUENCE_ID}/enrollments
  body: { contactId, startAt: event_date_minus_14_days }
// Agent 3: Upsert contact
PATCH https://api.hubapi.com/crm/v3/objects/contacts/{contactId}
  body: { properties: { attendance_status, event_name, event_date, event_tags } }
// Agent 3: Send follow-up email (attendee)
POST https://api.hubapi.com/marketing/v3/transactional/single-email/send
  body: { emailId: HUBSPOT_ATTENDEE_FOLLOW_UP_EMAIL_ID, message: { to: contact_email } }
// Agent 3: Send follow-up email (no-show)
POST https://api.hubapi.com/marketing/v3/transactional/single-email/send
  body: { emailId: HUBSPOT_NOSHOW_FOLLOW_UP_EMAIL_ID, message: { to: contact_email } }
Integration and API SpecPage 1 of 3
FS-DOC-05Technical
LinkedIn

Used by Agent 2 (Social Promotion) to schedule three promotional posts to the company LinkedIn Page: an announcement post, a mid-cycle reminder post, and a day-of post. All posting is to a LinkedIn Page, not a personal profile. Post copy is AI-generated and must pass the human approval step before the scheduling API call is made.

Auth method
OAuth 2.0 Authorization Code flow. The access token and refresh token are stored in the credential store (keys: LINKEDIN_ACCESS_TOKEN, LINKEDIN_REFRESH_TOKEN). The access token expires after 60 days; the refresh token expires after 365 days. The orchestration layer must auto-refresh the access token using the refresh token before expiry. Client ID and Client Secret stored as LINKEDIN_CLIENT_ID and LINKEDIN_CLIENT_SECRET.
Required scopes
w_organization_social | r_organization_social | rw_organization_admin
Webhook setup
No inbound webhook required for the current build. Posts are scheduled by passing a publishedAt timestamp in the future within the UGC Posts API request body.
Required configuration
LINKEDIN_ORGANIZATION_ID (the LinkedIn Page URN in the format urn:li:organization:{id}, stored in credential store). Post schedule offsets relative to event date: announcement post at event_date minus 14 days, mid-cycle post at event_date minus 7 days, day-of post at event_date (09:00 local time). Approval status flag must be set to 'approved' in the orchestration state before the scheduling call is attempted.
Rate limits
LinkedIn Marketing API: 100 calls per day per app for the UGC Posts endpoint under the standard Marketing Developer Platform tier. At 3 posts per event and up to 6 events/month, peak volume is 18 scheduling calls per month. No throttling needed at current volume. Application must remain compliant with LinkedIn's API usage policy to avoid access suspension.
Constraints
API access requires approval from LinkedIn's Marketing Developer Platform programme. Personal profile posting is not supported via the API and must not be attempted. Image or media attachments require a separate Assets API upload step before the post call. The current build uses text-only posts unless a future iteration adds image support. Token refresh must be monitored; a failed refresh will silently block all LinkedIn scheduling.
// Schedule a LinkedIn Page post
POST https://api.linkedin.com/v2/ugcPosts
  headers: { Authorization: Bearer {LINKEDIN_ACCESS_TOKEN}, X-Restli-Protocol-Version: 2.0.0 }
  body: {
    author: 'urn:li:organization:{LINKEDIN_ORGANIZATION_ID}',
    lifecycleState: 'PUBLISHED',
    publishedAt: {unix_timestamp_ms},
    specificContent: { com.linkedin.ugc.ShareContent: {
      shareCommentary: { text: post_copy },
      shareMediaCategory: 'NONE'
    }},
    visibility: { com.linkedin.ugc.MemberNetworkVisibility: 'PUBLIC' }
  }
Slack

Used by Agent 2 to post a single internal launch notification to a designated Slack channel immediately after LinkedIn posts are scheduled. The message includes the event name, date, and Zoom registration URL.

Auth method
Slack Bot token (xoxb-). The bot token is stored in the credential store (key: SLACK_BOT_TOKEN). The Slack app must be installed to the workspace and granted the required bot scopes.
Required scopes
chat:write | chat:write.public
Webhook setup
No inbound webhook required. Outbound message is posted via the Slack Web API chat.postMessage method. Alternatively, an Incoming Webhook URL may be used (stored as SLACK_WEBHOOK_URL) for simplicity if bot token management is not preferred; both approaches are acceptable.
Required configuration
SLACK_CHANNEL_ID (the ID of the internal marketing or events channel, stored in credential store, format: C0XXXXXXXXX). Message template: 'EVENT LIVE: {event_name} on {event_date} at {event_time}. Registration link: {zoom_registration_url}. Please share with your prospects.' Channel must have the bot app installed.
Rate limits
Slack Web API: 1 message per second per channel (Tier 3). At 3 to 6 notifications per month, rate limits are not a concern at current volume.
Constraints
The bot must be added to the target channel before the first run. If SLACK_CHANNEL_ID resolves to a private channel, the bot must be explicitly invited. Do not store channel names; always store and use channel IDs, as channel names can change.
// Post launch notification
POST https://slack.com/api/chat.postMessage
  headers: { Authorization: Bearer {SLACK_BOT_TOKEN} }
  body: {
    channel: '{SLACK_CHANNEL_ID}',
    text: 'EVENT LIVE: {event_name} on {event_date_formatted}. Registration: {zoom_registration_url}'
  }

03Field mappings between tools

The following tables define the exact field mappings for each agent handoff. All field names are given in monospace format exactly as they appear in the API response or sheet column header. Mapping must be implemented in the orchestration layer using the credential store values for IDs; no ID or token should appear as a literal in the mapping logic.

Agent 1 handoff: Google Sheets to Zoom and HubSpot (Event Setup Agent)

Source tool
Source field
Destination tool
Destination field
Google Sheets
`Status`
Orchestration layer
`trigger_condition` (must equal 'Confirmed')
Google Sheets
`EventTitle`
Zoom
`topic`
Google Sheets
`EventDate`
Zoom
`start_time` (ISO 8601, UTC converted)
Google Sheets
`DurationMinutes`
Zoom
`duration`
Google Sheets
`SpeakerName`
Zoom
`agenda`
Google Sheets
`EventTitle`
HubSpot
`event_name` (contact property)
Google Sheets
`EventDate`
HubSpot
`event_date` (contact property, date format)
Google Sheets
`AudienceListID`
HubSpot
list ID used in sequence enrolment call
Zoom (response)
`join_url`
HubSpot
token substituted into sequence email template `{{zoom_registration_url}}`
Zoom (response)
`id`
Orchestration state
`webinar_id` (stored for Agent 3 use)

Agent 2 handoff: Google Sheets and orchestration state to LinkedIn and Slack (Social Promotion Agent)

Source tool
Source field
Destination tool
Destination field
Google Sheets
`EventTitle`
LinkedIn
`shareCommentary.text` (interpolated into AI-generated copy)
Google Sheets
`EventDate`
LinkedIn
`publishedAt` (calculated: date minus 14 days, minus 7 days, day-of)
Google Sheets
`KeyMessageLine`
LinkedIn
`shareCommentary.text` (interpolated into AI copy body)
Zoom (state)
`join_url`
LinkedIn
`shareCommentary.text` (appended as registration link)
Zoom (state)
`join_url`
Slack
`text` (registration link field in Slack message)
Google Sheets
`EventTitle`
Slack
`text` (event name in Slack message)
Google Sheets
`EventDate`
Slack
`text` (formatted date in Slack message)
Google Sheets
`EventTime`
Slack
`text` (formatted time in Slack message)

Agent 3 handoff: Zoom attendance report to HubSpot and Google Sheets (Post-Event Sync Agent)

Source tool
Source field
Destination tool
Destination field
Zoom report
`participants[].email`
HubSpot
`email` (contact lookup/upsert key)
Zoom report
`participants[].name`
HubSpot
`firstname` + `lastname` (split on first space)
Zoom report
`participants[].status`
HubSpot
`attendance_status` ('joined' -> 'attended'; absent -> 'no-show')
Zoom report
`participants[].duration`
HubSpot
`event_attendance_duration_minutes` (custom property)
Orchestration state
`event_name`
HubSpot
`event_name` (contact property, applied to all upserted contacts)
Orchestration state
`event_date`
HubSpot
`event_date` (contact property, applied to all upserted contacts)
HubSpot (derived)
`attendance_status == 'attended'`
HubSpot
trigger `HUBSPOT_ATTENDEE_FOLLOW_UP_EMAIL_ID` send
HubSpot (derived)
`attendance_status == 'no-show'`
HubSpot
trigger `HUBSPOT_NOSHOW_FOLLOW_UP_EMAIL_ID` send
Zoom report (aggregate)
`total_registrants`
Google Sheets
`RegistrantCount` (column N)
Zoom report (aggregate)
`total_attendees`
Google Sheets
`AttendeeCount` (column O)
Zoom report (aggregate)
`total_no_shows`
Google Sheets
`NoShowCount` (column P)
HubSpot (derived)
announcement email `open_rate`
Google Sheets
`EmailOpenRate` (column Q)
Orchestration state
`processed_at` (ISO timestamp)
Google Sheets
`SyncCompletedAt` (column R)
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
One workflow per agent: three workflows total (Event Setup Agent workflow, Social Promotion Agent workflow, Post-Event Sync Agent workflow). All three workflows share a single credential store. Workflows are logically independent but Agent 2 is triggered by a completion event emitted by Agent 1, and Agent 3 runs on a scheduled trigger anchored to the event end time stored in orchestration state.
Agent 1 trigger
Poll-based. The Event Setup Agent workflow polls the Google Sheets event calendar every 5 minutes via the Sheets API. New rows matching Status = 'Confirmed' and Processed = '' initiate the workflow run. Poll interval may be reduced to 1 minute if near-real-time setup is required by the business.
Agent 2 trigger
Event-based (internal). The Social Promotion Agent workflow is triggered by a completion event fired at the end of Agent 1 once the Zoom registration URL is confirmed and stored in orchestration state. No external webhook is required. The human approval step is implemented as a pause state: the workflow halts and sends a Slack message or email to the coordinator with the draft copy and an approve/reject link before proceeding to LinkedIn scheduling.
Agent 3 trigger
Scheduled. The Post-Event Sync Agent workflow is scheduled to run at event_end_time plus 60 minutes (calculated from EventDate plus DurationMinutes, read from the Google Sheets brief row and stored in orchestration state at Agent 1 runtime). The scheduler must use UTC timestamps internally and convert for display only. Signature validation is not applicable to this trigger type.
Credential store
All secrets, IDs, and tokens are stored in the orchestration platform's encrypted credential store. No credential appears as a literal value in any workflow definition, code block, or mapping rule. Credential keys are referenced by name only.
Human approval pause state
Agent 2 pauses after AI copy generation. The coordinator receives a notification containing the three draft LinkedIn posts and a time-limited approval link (valid 48 hours). On approval, the workflow resumes and calls the LinkedIn scheduling API. On rejection, the workflow routes to a revision sub-flow where the coordinator can edit copy and resubmit. If the approval link expires without action, the workflow enters an error state and alerts via Slack (see Section 05).
Credential store keys, all environments. Replace placeholder values at setup. Never commit real secrets to version control.
// Credential store contents
// Google Sheets
GSHEETS_SERVICE_ACCOUNT_JSON      = { ...service_account_key_json... }
GSHEETS_SPREADSHEET_ID            = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms'  // replace at setup

// Zoom
ZOOM_CLIENT_ID                    = 'xxxxxxxxxxxxxxxxxxxx'
ZOOM_CLIENT_SECRET                = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
ZOOM_ACCOUNT_ID                   = 'xxxxxxxxxxxx'
ZOOM_WEBINAR_HOST_ID              = 'xxxxxxxxxxxx'
ZOOM_WEBHOOK_SECRET_TOKEN         = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'  // reserved for future webhook

// HubSpot
HUBSPOT_PRIVATE_APP_TOKEN         = 'pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
HUBSPOT_SEQUENCE_ID               = '12345678'  // ID of pre-built announcement+reminder sequence
HUBSPOT_EVENT_LIST_ID             = '87654321'  // active list of target audience contacts
HUBSPOT_ATTENDEE_FOLLOW_UP_EMAIL_ID  = '11111111'  // published email template ID
HUBSPOT_NOSHOW_FOLLOW_UP_EMAIL_ID    = '22222222'  // published email template ID

// LinkedIn
LINKEDIN_CLIENT_ID                = 'xxxxxxxxxxxx'
LINKEDIN_CLIENT_SECRET            = 'xxxxxxxxxxxxxxxx'
LINKEDIN_ACCESS_TOKEN             = 'AQV...'  // refresh before 60-day expiry
LINKEDIN_REFRESH_TOKEN            = 'AQX...'  // refresh before 365-day expiry
LINKEDIN_ORGANIZATION_ID          = 'urn:li:organization:12345678'

// Slack
SLACK_BOT_TOKEN                   = 'xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
SLACK_CHANNEL_ID                  = 'C0XXXXXXXXX'  // internal events/marketing channel ID
SLACK_WEBHOOK_URL                 = 'https://hooks.slack.com/services/T.../B.../...'  // optional fallback

// Orchestration internals
APPROVAL_LINK_EXPIRY_HOURS        = 48
GSHEETS_POLL_INTERVAL_MINUTES     = 5
ZOOM_REPORT_DELAY_MINUTES         = 60  // offset after event end before Agent 3 runs
The LinkedIn access token must be refreshed before its 60-day expiry. Build a scheduled token-refresh check into the orchestration layer that runs every 30 days and alerts via Slack if the refresh fails. A silently expired LinkedIn token will block all social scheduling without any visible error in the main workflow.

05Error handling and retry logic

Every integration boundary has a defined failure behaviour. Unhandled exceptions must never fail silently. All retry attempts use exponential backoff unless stated otherwise. After all retries are exhausted, the workflow must alert the designated operator channel (SLACK_CHANNEL_ID) with the workflow ID, agent name, error code, and a short description of the failed step.

Integration
Scenario
Required behaviour
Google Sheets (poll)
Sheets API returns 429 (quota exceeded)
Retry with exponential backoff: 30s, 60s, 120s. After 3 retries, skip the poll cycle and resume at next scheduled interval. Log quota hit to orchestration run history. Alert operator if this occurs on 3 consecutive poll cycles.
Google Sheets (poll)
Row detected but required columns are empty or malformed
Do not proceed. Write 'ValidationFailed' to the Processed column of the offending row. Post a Slack alert to SLACK_CHANNEL_ID identifying the row number and missing fields. Halt Agent 1 for that row only; other rows process normally.
Zoom (webinar create)
Zoom API returns 401 (invalid or expired token)
Attempt token refresh immediately using account_credentials grant. Retry the original request once. If refresh fails, halt Agent 1 and alert operator via Slack with error details. Do not retry further without manual credential review.
Zoom (webinar create)
Zoom API returns 429 (rate limit)
Retry after the Retry-After header value (or 60s if header absent). Retry up to 3 times. If all retries fail, halt Agent 1 for this event and alert operator. Current volume makes this scenario unlikely but must be handled.
Zoom (attendance report)
Report returns empty participant list (host did not end session formally)
Detect empty list condition. Post a Slack alert to operator channel identifying the webinar ID and event name. Expose a manual override webhook endpoint that allows the operator to inject a CSV of attendee data to resume Agent 3 processing. Do not send follow-up emails until attendance data is confirmed.
HubSpot (sequence enrolment)
API returns 400 (contact not in the required list or sequence already active)
Log the contact ID and error response. Skip that contact and continue enrolment for remaining contacts. After batch completes, post a summary to Slack listing skipped contacts and reason codes. Do not halt the entire agent for individual contact failures.
HubSpot (contact upsert)
API returns 409 (conflict: duplicate email)
Switch to an update (PATCH) call using the existing contact ID returned in the 409 response body. Retry once. If the PATCH also fails, log the contact and continue. Include failed contacts in the post-run Slack summary.
HubSpot (follow-up email send)
API returns 400 (email template in draft state or not found)
Halt follow-up sends for this event immediately. Alert operator via Slack with the failing template ID. Do not retry until the operator confirms the template is published and triggers a manual re-run. This is a critical failure as it affects post-event pipeline.
LinkedIn (post scheduling)
Approval link expires after 48 hours with no coordinator action
Transition workflow to 'ApprovalExpired' state. Post a Slack alert to SLACK_CHANNEL_ID tagging the coordinator. Do not schedule posts. Allow the operator to manually restart the approval flow from the orchestration dashboard. Log the expiry with timestamp.
LinkedIn (post scheduling)
OAuth access token expired (token refresh fails)
Halt Agent 2 LinkedIn scheduling step immediately. Alert operator via Slack with token expiry details and a link to the LinkedIn token refresh procedure. Do not attempt to post without a valid token. Posts remain in the approval-complete queue and can be rescheduled once the token is renewed.
Slack (launch notification)
chat.postMessage returns 404 (channel not found or bot not in channel)
Retry once after 10 seconds. If the second attempt fails, log the error to the orchestration run history and write a fallback alert to the orchestration platform's own error log. Do not halt Agent 2 for a Slack notification failure; it is a non-critical step. Alert the operator via email (support@gofullspec.com escalation path) if the channel error persists.
Google Sheets (metrics write-back)
Write operation fails due to permission error or sheet structure change
Retry once after 30 seconds. If the retry fails, store the metrics payload in orchestration state as a pending write and alert the operator via Slack. Provide a manual re-trigger option so the write can be reattempted without re-running the full Agent 3 flow. Agent 3 is otherwise marked complete.
All unhandled exceptions, including network timeouts, unexpected HTTP status codes not listed above, and internal orchestration errors, must be caught by a global error handler in each workflow. The global handler must: log the full error object and stack trace to the orchestration run history, post a Slack alert to SLACK_CHANNEL_ID with the workflow name and run ID, and transition the workflow to a terminal 'Failed' state rather than leaving it in a running or pending state. Workflows must never hang indefinitely. Contact support@gofullspec.com if a workflow enters an unrecoverable state.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Event & Webinar Promotion.

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