Integration and API Spec
The reference during the build: every tool connection, auth scope, field mapping, and error-handling rule.
Integration and API Spec
Referral Programme Management
[YourCompany.com] · Sales Department · Prepared by FullSpec · [Today's Date]
This document defines every integration point, authentication method, required scope, field mapping, and error-handling behaviour for the Referral Programme Management automation. It is written for the FullSpec build team and covers the six production tools (Typeform, HubSpot, Google Sheets, Gmail, Slack, and Xero) plus the orchestration layer that connects them. All credential references, rate limits, and retry rules in this document are mandatory implementation requirements, not suggestions. Nothing in this document requires action from the process owner; the FullSpec team owns the full build, configuration, and validation of every integration described here.
01Tool inventory
02Per-tool integration detail
Typeform acts as the entry-point trigger for the entire automation. The webhook fires immediately on form submission and carries all referral field values in the response payload. Signature validation is mandatory before any downstream action is taken.
// Inbound webhook payload (key fields) event_id: string // unique per delivery attempt token: string // unique per form response, use as idempotency key form_response.answers[] // array of field objects field.ref: string // use this, not field title text | email: string // answer value by type // Fields extracted for downstream agents referrer_name: answers[ref=referrer_name].text referrer_email: answers[ref=referrer_email].email referred_contact_name: answers[ref=referred_contact_name].text referred_contact_email: answers[ref=referred_contact_email].email referred_contact_company: answers[ref=referred_contact_company].text referral_notes: answers[ref=referral_notes].text
HubSpot is used by two agents: Agent 1 queries and writes contact and deal records on intake; Agent 3 listens for deal stage change events via webhook subscription to sync the register and trigger reward processing.
// Contact search request
POST /crm/v3/objects/contacts/search
{ filterGroups: [{ filters: [{ propertyName: 'email', operator: 'EQ', value: referred_contact_email }] }] }
// Contact create request
POST /crm/v3/objects/contacts
{ properties: { firstname, lastname, email, referrer_name, referrer_email, reward_tier, referral_submission_date } }
// Deal create request
POST /crm/v3/objects/deals
{ properties: { dealname, pipeline, dealstage, referral_source, reward_amount, referral_register_row_id } }
// Stage change webhook event (inbound)
objectId: number // HubSpot deal ID
propertyName: string // 'dealstage'
propertyValue: string // new stage ID
occurredAt: ISO8601 // event timestampGoogle Sheets is the programme register. Agent 1 appends a new row on intake; Agent 3 updates the matching row on every deal stage change and again when the reward bill is created in Xero. The sheet structure is fixed and must not be altered after go-live without updating the field mappings in the orchestration layer.
// Append new row on intake
POST /v4/spreadsheets/{spreadsheetId}/values/{range}:append
range: 'Referral Register!A:L'
valueInputOption: RAW
values: [[submission_date, referrer_name, referrer_email, referred_name, referred_email,
referred_company, reward_tier, reward_amount, deal_stage, hubspot_deal_id,
status, notes]]
// Update existing row on stage change
PUT /v4/spreadsheets/{spreadsheetId}/values/'Referral Register!I{rowNum}:L{rowNum}'
values: [[new_deal_stage, hubspot_deal_id, new_status, updated_notes]]Gmail sends two categories of email managed by Agent 2: (1) an acknowledgement email sent to the referrer immediately after a new referral is logged, and (2) a reward notification email sent to the referrer when the deal reaches Closed Won. Both emails use stored templates with named placeholders substituted at runtime.
// Send message request
POST /gmail/v1/users/me/messages/send
{ raw: base64url(RFC2822 formatted message) }
// RFC2822 headers
From: {{GMAIL_SENDER_NAME}} <{{GMAIL_SENDER_ADDRESS}}>
To: referrer_email
Reply-To: {{GMAIL_REPLY_TO}}
Subject: [Acknowledgement] Your referral of {{referred_contact_name}} has been received
Content-Type: text/plain; charset=utf-8
// Template substitution at runtime
body = GMAIL_TEMPLATE_ACKNOWLEDGEMENT
.replace('{{referrer_name}}', referrer_name)
.replace('{{referred_contact_name}}', referred_contact_name)
.replace('{{reward_tier}}', reward_tier)Slack is used by Agent 2 to post a formatted lead alert to the designated sales rep channel immediately after a new referral is logged and the HubSpot deal is created. A second alert is posted to a separate channel (or the same channel) if a duplicate contact is detected, flagging the case for manager review.
// chat.postMessage request
POST https://slack.com/api/chat.postMessage
Authorization: Bearer {{SLACK_BOT_TOKEN}}
{
channel: SLACK_SALES_CHANNEL_ID,
blocks: [
{ type: 'header', text: { type: 'plain_text', text: 'New Referral Received' } },
{ type: 'section', fields: [
{ type: 'mrkdwn', text: '*Referrer:* {{referrer_name}}' },
{ type: 'mrkdwn', text: '*Referred:* {{referred_contact_name}} ({{referred_contact_company}})' },
{ type: 'mrkdwn', text: '*Reward Tier:* {{reward_tier}}' },
{ type: 'mrkdwn', text: '*Deal:* <{{hubspot_deal_url}}|Open in HubSpot>' }
]}
]
}Xero is used by Agent 3 to create a draft bill for the referral reward amount when a referred deal reaches Closed Won in HubSpot. The bill is created in draft state so the finance contact retains full approval and payment authority. No automated payment or approval action is taken.
// Create bill (Account Payable invoice)
POST https://api.xero.com/api.xro/2.0/Invoices
Xero-Tenant-Id: {{XERO_TENANT_ID}}
{
Type: 'ACCPAY',
Status: 'DRAFT',
InvoiceNumber: 'REF-{{hubspot_deal_id}}',
Contact: { ContactID: '{{xero_contact_id}}' },
Date: '{{deal_close_date}}',
DueDate: '{{deal_close_date + 30 days}}',
LineItems: [{
Description: 'Referral reward: {{referrer_name}} referred {{referred_contact_name}}, closed {{deal_close_date}}',
Quantity: 1,
UnitAmount: {{reward_amount}},
AccountCode: '{{XERO_REWARD_ACCOUNT_CODE}}'
}]
}03Field mappings between tools
The tables below define every field handoff between tools at each agent boundary. Use the exact field names shown (monospace) when configuring the orchestration layer. Do not substitute display labels for API field names.
Agent 1 handoff: Typeform to HubSpot (contact and deal creation)
Agent 1 handoff: HubSpot to Google Sheets (register row append)
Agent 3 handoff: HubSpot stage change event to Google Sheets (row update)
Agent 3 handoff: HubSpot Closed Won event to Xero (bill creation)
04Build stack and orchestration
// Credential store contents (all values encrypted at rest)
// Typeform
TYPEFORM_OAUTH_ACCESS_TOKEN = 'tfp_...'
TYPEFORM_WEBHOOK_SECRET = '<32-char HMAC secret from Typeform Connect>'
TYPEFORM_FORM_ID = '<form ID from Typeform dashboard>'
TYPEFORM_FIELD_REF_REFERRER_NAME = '<field ref string>'
TYPEFORM_FIELD_REF_REFERRER_EMAIL = '<field ref string>'
TYPEFORM_FIELD_REF_REFERRED_NAME = '<field ref string>'
TYPEFORM_FIELD_REF_REFERRED_EMAIL = '<field ref string>'
TYPEFORM_FIELD_REF_REFERRED_COMPANY = '<field ref string>'
TYPEFORM_FIELD_REF_REFERRAL_NOTES = '<field ref string>'
// HubSpot
HUBSPOT_PRIVATE_APP_TOKEN = 'pat-na1-...'
HUBSPOT_PORTAL_ID = '<HubSpot portal/account ID>'
HUBSPOT_PIPELINE_ID = '<sales pipeline ID>'
HUBSPOT_CLOSED_WON_STAGE_ID = '<Closed Won stage ID>'
HUBSPOT_APP_CLIENT_SECRET = '<used for webhook signature validation>'
HUBSPOT_DEAL_URL_PATTERN = 'https://app.hubspot.com/contacts/{portalId}/deal/{dealId}'
// Google Sheets
GOOGLE_SERVICE_ACCOUNT_JSON = '<full JSON key object as string>'
GSHEETS_SPREADSHEET_ID = '<spreadsheet ID from URL>'
GSHEETS_REGISTER_TAB = 'Referral Register'
// Gmail
GMAIL_CLIENT_ID = '<OAuth client ID>'
GMAIL_CLIENT_SECRET = '<OAuth client secret>'
GMAIL_REFRESH_TOKEN = '<offline refresh token>'
GMAIL_SENDER_ADDRESS = 'referrals@[YourCompany.com]'
GMAIL_SENDER_NAME = '[YourCompany.com] Referral Programme'
GMAIL_REPLY_TO = 'sales@[YourCompany.com]'
GMAIL_TEMPLATE_ACKNOWLEDGEMENT = '<multiline plain text template string>'
GMAIL_TEMPLATE_REWARD_NOTIFICATION = '<multiline plain text template string>'
// Slack
SLACK_BOT_TOKEN = 'xoxb-...'
SLACK_SALES_CHANNEL_ID = 'C...'
SLACK_EXCEPTION_CHANNEL_ID = 'C...'
// Xero
XERO_CLIENT_ID = '<Xero app client ID>'
XERO_CLIENT_SECRET = '<Xero app client secret>'
XERO_REFRESH_TOKEN = '<current offline refresh token>'
XERO_TENANT_ID = '<Xero organisation tenant ID>'
XERO_REWARD_ACCOUNT_CODE = '420'
XERO_REWARD_TIER_1_AMOUNT = '500'
XERO_REWARD_TIER_2_AMOUNT = '250'
XERO_REWARD_TIER_3_AMOUNT = '100'
XERO_CONTACT_MAP = '{"referrer@example.com": "<XeroContactID>", ...}'05Error handling and retry logic
More documents for this process
Every document generated for Referral Programme Management.