Manage 10-100 HubSpot portals for agency clients with credential isolation that prevents cross-portal data contamination, per-portal audit trails for billing and GDPR/CCPA attribution, and a scriptable bulk-onboarding workflow that eliminates one-at-a-time credential setup.
SkillScore83Maintained
Automatic
◆Sales & GTM packhubspotmulti-portalagency
Last verified 8/30/2026
What it changes
Passed 19 of 23 test cases with the skill, and 10 of 23 without it.
Without skill43%
With skill83%
Checks it passed that the model alone missed
Formats timestamps as ISO 8601 strings in the ts property.
Extracts and stores the portal datacenter from the token prefix.
Aggregates call counts and exports structured CSV compliance output.
and 11 more in the full report
9 fixed10 passed either way4 still failing0 broke
Pass-rate lift
+39 pp
Tokens
+173%
Agent turns
0%
Response time
+4%
Model gemini-3.6-flashMeasured 8/30/2026v119 of 23 cases passed with skill
Tokens, turns and time describe resource use, not a dollar price.
See it in action
One of 9 test cases the skill fixed. Same model, same prompt, with and without the skill.
1 of 9
Prompt
Our compliance team requires every API log entry to identify the system component performing the API call. What exact string identifier should be passed in the `actor` field of our audit log records?
What was checked, without and with the skill
Checked
Without skill
With skill
Sets the actor field in the audit record to hubspot-agency-router/2.0.0.
Missed
Passed
Formats timestamps as ISO 8601 strings in the ts property.
Missed
Passed
case-19 · gemini-3.6-flash · 8/30/2026 · answers are capped and redacted
What's inside
The instructions your model reads when the skill loads.
SKILL.md408 lines3 files
HubSpot Agency Multi-Portal
Overview
Operate a fleet of HubSpot portals for agency clients without cross-portal contamination, attribution loss, or onboarding bottlenecks. This is not a getting-started guide — it is the infrastructure your agency runs on day one with client one and scales to client one hundred without revisiting.
The six production failures this skill prevents:
Cross-portal credential contamination — a shared HUBSPOT_ACCESS_TOKEN env var causes API writes intended for Client A to silently land in Client B's CRM. The HubSpot API does not reject the call; it accepts it. Data corruption is silent and may not be discovered for days. Per-portal credential isolation — enforced in code, not convention — is the only fix.
Audit trail gaps — agency billing, SLA compliance, and GDPR/CCPA data-processing agreements all require proof of which API calls were made on behalf of which client. A shared token makes post-hoc attribution impossible. A per-portal structured audit log with portalId, clientSlug, operation, and timestamp makes attribution irrefutable.
Bulk onboarding bottleneck — onboarding 50 new clients one-at-a-time requires 50 manual credential setups, 50 manual verifications, and 50 opportunities for human error. A scriptable bulk onboarding workflow reads a CSV of client names and tokens, validates each against the account-info endpoint, and seeds the credential store in one pass.
Token rotation cascade — rotating one client's private-app token in HubSpot does not update any downstream system. With 50 portals, a partial rotation — some systems updated, some not — leaves stale tokens in production for undetermined periods. A per-portal rotation runbook with a cross-system checklist closes the gap.
Rate-limit aggregation confusion — each portal has its own independent 500K/day quota. An agency analytics system reading all 50 portals is NOT limited to 500K calls total — it has 500K per portal per day, but only if the token used for each portal belongs to that portal. A shared token collapses all quota attribution to one portal, causing artificial exhaustion and incorrect monitoring.
Compliance reporting ambiguity — under GDPR Article 30 and CCPA, a data processor (the agency) must demonstrate which operations were performed on which controller's (client's) data and when. A shared token makes this demonstration impossible after the fact. Per-portal audit logs with structured fields make it a simple query.
Prerequisites
Node.js 18+ or Python 3.10+
One HubSpot private-app token per client portal (Settings → Integrations → Private Apps → Create private app → Auth tab)
A secret store the credential router can read at startup: AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, or pass for local development
jq installed for CLI validation steps
python3 with standard library only for bulk onboarding script (no external deps required)
CSV file of client slugs and tokens for bulk onboarding (format: clientSlug,portalToken,portalId)
Instructions
Build in this order. Each section closes one production failure mode.
1. Credential store design (closes cross-portal contamination)
The credential store is a JSON map of clientSlug → token. It lives in your secret manager, never in source code or environment variables. The key insight is that clientSlug is the primary key — every operation starts by selecting a slug, which deterministically selects the token. There is no ambient credential and no fallback to a global env var.
// Shape of the credential store (stored in secret manager, NOT in git or env vars)
interface PortalCredentialStore {
version: number; // increment on every write; used for drift detection
portals: Record<string, PortalCredential>;
}
interface PortalCredential {
Deduplicate HubSpot contacts at production scale — surviving import storms, wrong-winner
merges, fuzzy-match blind spots, association orphans, rate-limit exhaustion, and silent
merge failures on conflicting lifecycle or opt-out status. Use when cleaning a CRM after
a bulk import, running a nightly dedup pipeline on millions of records, recovering from
a merge that destroyed the wrong timeline, or building fuzzy matching beyond HubSpot's
native email-uniqueness. Trigger with "hubspot dedup", "hub