Integration scope and assumptions
These specifications define the technical interface for partners integrating Student Tenant Insurance data with Summit Commercial Solutions in Canada. The guide covers webhook event payloads (submitted, verified, lapsed), HMAC request signing and verification, retry/idempotency behavior, CSV batch ingestion field maps, validation rules, and privacy/residency considerations. Service is available across Canada except Quebec; do not submit Quebec (QC) addresses.
Webhook events
Summit delivers event notifications via HTTPS POST with a JSON body and HMAC-SHA256 signature headers. All payloads include an idempotent event_id, event_type, occurred_at (ISO 8601, UTC), environment, and a policy object. Receivers must respond with HTTP 2xx within 10 seconds.
-
Event types
-
submitted: an application or enrollment was submitted.
-
verified: identity/eligibility and initial billing were verified; coverage is active as of effective_date.
-
lapsed: coverage ended due to cancellation, non-payment, or non-renewal.
Example: submitted
{
"event_id": "8b2f7f3e-0a2f-4c4a-9b1c-12a3b4567890",
"event_type": "submitted",
"occurred_at": "2025-01-15T18:42:11Z",
"environment": "production",
"policy": {
"policy_id": "pol_01JABCDEF12345",
"external_policy_id": "UNIV-2025-000981",
"status": "pending_verification",
"effective_date": "2025-02-01",
"expiry_date": "2026-01-31",
"premium_cad_monthly": 18.00,
"coverage": {
"personal_property_limit_cad": 25000,
"personal_liability_limit_cad": 1000000,
"additional_living_expense_limit_cad": 6000,
"deductible_cad": 500
},
"insured": {
"first_name": "Avery",
"last_name": "Nguyen",
"email": "avery.nguyen@example.edu",
"phone_e164": "+16045551234",
"date_of_birth": "2004-06-12",
"student_id": "S1234567",
"institution_name": "Okanagan University"
},
"residence": {
"housing_type": "on_campus",
"address_line1": "123 University Way",
"address_line2": "Unit 4B",
"city": "Kelowna",
"province": "BC",
"postal_code": "V1Y 6N7",
"country": "CA"
},
"partner": {
"partner_id": "ptnr_0029",
"integration_name": "CampusPortal"
}
},
"consents": {
"terms_accepted_at": "2025-01-15T18:41:50Z",
"marketing_opt_in": false
},
"meta": {
"version": "2025-01-01",
"source": "csv_upload"
}
}
Example: verified
{
"event_id": "a88e9a49-5c4d-4a9a-8f6c-5f8c7f1b2a00",
"event_type": "verified",
"occurred_at": "2025-01-16T14:03:22Z",
"environment": "production",
"policy": {
"policy_id": "pol_01JABCDEF12345",
"external_policy_id": "UNIV-2025-000981",
"status": "active",
"effective_date": "2025-02-01",
"expiry_date": "2026-01-31",
"premium_cad_monthly": 18.00,
"first_bill_status": "paid",
"coverage": {
"personal_property_limit_cad": 25000,
"personal_liability_limit_cad": 1000000,
"additional_living_expense_limit_cad": 6000,
"deductible_cad": 500
},
"insured": {
"first_name": "Avery",
"last_name": "Nguyen",
"email": "avery.nguyen@example.edu"
}
},
"meta": {
"version": "2025-01-01",
"verification_reference": "vrf_78abd2"
}
}
Example: lapsed
{
"event_id": "f9c4b1a2-3d45-4c67-88e2-9a0b1c2d3e4f",
"event_type": "lapsed",
"occurred_at": "2025-10-01T07:30:00Z",
"environment": "production",
"policy": {
"policy_id": "pol_01JABCDEF12345",
"external_policy_id": "UNIV-2025-000981",
"status": "lapsed",
"lapse_reason": "non_payment",
"lapse_effective_date": "2025-09-30",
"earned_premium_cad": 126.00
},
"meta": {
"version": "2025-01-01"
}
}
Security: HMAC request signing
All webhook requests include:
-
Headers
-
SCS-Timestamp: UNIX epoch (seconds) when the signature was generated
-
SCS-Signature: hex HMAC-SHA256 over the signed payload
-
Signed payload construction
-
signing_base = SCS-Timestamp + "." + raw_request_body
-
signature = HMAC_SHA256(secret=webhook_signing_secret, message=signing_base)
-
Verification steps 1) Compute your own signature over the raw request body using the above method. 2) Compare with SCS-Signature using a constant‑time comparison. 3) Enforce a timestamp tolerance window (recommend ≤300 seconds) to prevent replay. 4) Reject if either the signature check or the timestamp check fails.
Node.js verifier (example)
import crypto from 'node:crypto';
export function verifySummitWebhook(headers, rawBody, secret, toleranceSec = 300) {
const ts = parseInt(headers['scs-timestamp'], 10);
const sig = String(headers['scs-signature'] || '');
if (!ts || !sig) return false;
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - ts) > toleranceSec) return false;
const signingBase = `${ts}.${rawBody}`;
const expected = crypto.createHmac('sha256', secret).update(signingBase).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
Python verifier (example)
import hmac, hashlib, time
def verify_summit_webhook(headers, raw_body: bytes, secret: bytes, tolerance_sec: int = 300) -> bool:
ts = int(headers.get('SCS-Timestamp', '0'))
sig = headers.get('SCS-Signature', '')
if not ts or not sig:
return False
now = int(time.time())
if abs(now - ts) > tolerance_sec:
return False
signing_base = f"{ts}.".encode('utf-8') + raw_body
expected = hmac.new(secret, signing_base, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)
Delivery, retries, and idempotency
-
Acknowledgement: respond with HTTP 200–204 on success. Do not parse/transform before ack if processing may exceed 10 seconds.
-
Retries: exponential backoff up to 24 hours for non‑2xx responses or network timeouts.
-
Idempotency: de‑duplicate by event_id. Treat repeated deliveries of the same event_id as the same event.
-
Ordering: not guaranteed across event types; rely on occurred_at and policy.status for final state.
Environments and IPs
-
Environments: sandbox and production. Secrets are environment‑scoped.
-
Allowlist: if you enforce IP allowlisting, your Summit partnership manager can provide current egress ranges.
CSV upload field map (batch enrollments)
Upload a UTF‑8 CSV with the following headers. Dates are ISO 8601 (YYYY‑MM‑DD). Province must not be QC (Quebec is not supported).
| Header | Required | Type/Format | Example | Notes |
|---|---|---|---|---|
| first_name | yes | string | Avery | |
| last_name | yes | string | Nguyen | |
| yes | avery.nguyen@example.edu | Student or school email | ||
| phone_e164 | no | +E.164 | +16045551234 | Country code required |
| date_of_birth | yes | date | 2004-06-12 | 16+ recommended minimum |
| institution_name | yes | string | Okanagan University | Official name |
| campus | no | string | Main Campus | |
| student_id | yes | string | S1234567 | Unique per institution |
| housing_type | yes | enum | on_campus | on_campus, off_campus |
| address_line1 | yes | string | 123 University Way | |
| address_line2 | no | string | Unit 4B | |
| city | yes | string | Kelowna | |
| province | yes | ISO‑3166‑2:CA | BC | Exclude QC |
| postal_code | yes | Canada postal | V1Y 6N7 | Uppercase with space |
| country | yes | ISO‑3166‑1 alpha‑2 | CA | Canada only |
| lease_start_date | yes | date | 2025-09-01 | |
| lease_end_date | yes | date | 2026-08-31 | ≥ start date |
| personal_property_limit_cad | yes | number | 25000 | Integer dollars |
| personal_liability_limit_cad | yes | number | 1000000 | Minimum recommended ≥ $1M |
| additional_living_expense_limit_cad | no | number | 6000 | |
| deductible_cad | no | number | 500 | |
| monthly_premium_cad | no | number | 18.00 | If absent, rated by Summit |
| external_policy_id | no | string | UNIV-2025-000981 | Partner reference |
| additional_insured_name | no | string | Okanagan University | If required by contract |
| consent_collected_at | yes | datetime (UTC) | 2025-01-15T18:41:50Z | Terms/privacy consent |
| marketing_opt_in | no | boolean | false | |
| status | no | enum | pending_verification | pending_verification, active, lapsed |
CSV validation rules
-
Postal code: uppercase Canadian format A1A 1A1 with a space; reject non‑conforming values.
-
Province: one of AB, BC, MB, NB, NL, NS, NT, NU, ON, PE, SK, YT; QC not supported.
-
Dates: lease_end_date must be on/after lease_start_date; date_of_birth must be a valid past date.
-
Amounts: non‑negative; liability limit must be ≥ 500,000 CAD; property limit ≥ 10,000 CAD recommended.
-
Duplicates: treat rows with the same student_id + lease_start_date as potential duplicates; partners should upsert using external_policy_id where possible.
Error reporting (CSV ingestion)
-
Row‑level errors are returned with 422 Unprocessable Entity and a JSON body indicating row number, field, and message.
-
Valid rows in a partially invalid file may still be accepted if you pass allow_partial=true (contact your Summit manager to enable per environment).
Data flow reference
-
CSV accepted → submitted webhook emitted per valid row.
-
After verification (identity/billing) → verified webhook.
-
Cancellation/non‑renewal → lapsed webhook.
Change management and versioning
-
Payloads include meta.version in YYYY‑MM‑DD format.
-
Backwards compatibility: additive changes (new nullable fields) will be version‑minor; breaking changes trigger a new version and coordinated migration.
-
Subscribe to change notices through your Summit partnership manager.
Privacy, residency, and compliance (Canada)
-
PII minimization: send only fields required by the field map.
-
Residency: Summit stores personal information exclusively in Canada, per its Company Privacy Policy.
-
Consent: partners are responsible for collecting and logging student consent to terms and privacy prior to transmission; include consent_collected_at.
Security hardening checklist
-
Verify HMAC signature and timestamp on every webhook.
-
Serve HTTPS with TLS 1.2+; prefer TLS 1.3.
-
Rotate webhook_signing_secret at least annually or on exposure.
-
Principle of least privilege for keys and logs; avoid logging full payloads containing PII.
-
Implement replay protection and idempotency by event_id.
Implementation checklist
-
Provision sandbox and production signing secrets.
-
Stand up a webhook endpoint: idempotent processing, 2xx ack, retries safe.
-
Build CSV generation and validation per field map; exclude QC addresses.
-
Store policy_id ↔ external_policy_id mapping.
-
Monitor for submitted/verified/lapsed and update student records accordingly.
Support
For credentials, IP ranges, sandbox endpoints, and feature flags (e.g., allow_partial), contact Summit at Contact Us. For claims process context, see Claim Services.