Multi-Region Strategy — April 2026

Going Global with
Subdomains & Subdirectories

A pragmatic strategy for expanding Unscammed to US, UK, and Australia without fragmenting the brand, the SEO, or the engineering team. Subdirectories for marketing, subdomains for app and API, per-region Aurora for GDPR, DynamoDB Global Tables for shared intelligence.

Prepared for Unscammed Engineering | Confidential

Domains
1 Root
unscammed.com
Regions
3 at Launch
US, UK, AU
Phases
5 Steps
2–8 wks each
KYT Target
<15ms
DAX + DDB

Part I — The Strategy

The decision framework: why subdomains for the app, subdirectories for marketing, and per-region infrastructure for data residency.

Summary

Executive Summary

Three constraints drive the architecture: GDPR data residency for UK/EEA users, engineering economy (one codebase, many regions), and SEO equity for a new brand that cannot afford fragmented domain authority.

The core decision

One domain, two patterns. Use subdirectories (unscammed.com/uk/) for the marketing site to preserve SEO authority. Use subdomains (uk.app.unscammed.com) for the app and API because only DNS-level routing can satisfy data residency requirements.

Path-based routing cannot give us GDPR compliance — /uk/ is parsed by the application after the request has already reached a single origin. Subdomains resolve to distinct regional endpoints before any code executes.

3
Regions at Launch
1
Root Domain
0
ccTLDs Needed
5
Rollout Phases
The thesis in one paragraph: Treat region as a property of the URL, not a property of the request. For marketing content, region is a path segment because content has no residency requirement. For user data, region is a subdomain because only that gives Route 53 the control needed to route UK requests to eu-west-2 without the application ever seeing a cross-region option.

Section 1

Why This Split

Two surfaces, two sets of constraints, two patterns. The marketing site optimises for SEO; the app optimises for data residency and security.

Subdirectories for Marketing

Why it wins: A new brand cannot afford to fragment domain authority across three separate subdomains. Google treats uk.unscammed.com as a separate site that must earn rank from scratch.

  • SEO: unscammed.com/uk/ inherits the root domain's authority
  • Infra: One SSL cert, one CDN config, one Strapi instance
  • Content: Region becomes a locale parameter, not a deployment target
  • New countries: Translation + content task, not infra project

Subdomains for Marketing (rejected)

Why it loses: All the SEO work done on unscammed.com today would not transfer to uk.unscammed.com. We would be starting from zero in each country.

  • Separate backlink profiles per subdomain
  • Separate authority score per subdomain
  • More SSL certs to manage
  • No technical upside for static marketing content

Subdomains for App & API

Why it wins: Only DNS-level routing satisfies data residency. uk.api.unscammed.com resolves to an eu-west-2 endpoint before any application code runs.

  • Residency: UK PII physically cannot be served from us-east-2
  • Security: Eliminates the 4 spoofable detection methods from the dossier
  • Scaling: Each region scales independently
  • Cookies: Natural scoping prevents accidental cross-region auth

Path Routing for App (rejected)

Why it loses: app.unscammed.com/uk reaches a single origin; the /uk is parsed in application code. That is the exact fragile pattern the dossier is moving away from.

  • Cannot satisfy GDPR Art. 44 — data could be in either region
  • Region remains spoofable via URL manipulation
  • Forces app-layer region detection back into code
  • Blocks independent per-region scaling
Critical rejection: Any proposal that puts region in the path for the app is a regression. The security and residency wins described in the Multi-Region Dossier depend on region being resolved at DNS, before a request touches our code.

Section 2

The Domain Pattern

One table, one source of truth. Every URL across the platform follows this pattern.

SurfacePatternWhy
Marketing
SEO
unscammed.com/us/
unscammed.com/uk/
unscammed.com/au/
Subdirectories inherit the root domain's SEO authority. No user data → no residency concern.
App
Product
us.app.unscammed.com
uk.app.unscammed.com
au.app.unscammed.com
Subdomains enable DNS-level routing to regional Aurora clusters. Region is infrastructure, not a header.
API
Backend
us.api.unscammed.com
uk.api.unscammed.com
au.api.unscammed.com
Per-region API Gateway → per-region Aurora. Kills all four spoofable region-detection methods.
KYT API
Banks
kyt.unscammed.com Latency-based Route 53 routing. Nearest region's DynamoDB + DAX. Sub-15ms response time for bank customers.
Admin
Internal
admin.unscammed.com Single global admin UI. Region dropdown selects which regional API to call. One login, any region.

Part II — Technical Design

How the frontend, backend, data layer, and DNS fit together. The design follows directly from the domain pattern above.

Section 3

Frontend Strategy

Marketing stays as one SvelteKit deployment with region as a URL segment. The React app ships as a separate build per region, each with its API URL baked in at build time.

3.1 Marketing Site (unscammed-website)

Single SvelteKit deployment on the existing Website Prod EC2. Region is a URL segment resolved in the [region] layout route. Strapi provides localised content via a locale field on each entry.

// Route structure src/routes/[region=region]/+layout.ts // validates region, loads config src/routes/[region=region]/+page.svelte // regional landing src/routes/[region=region]/pricing/+page.svelte src/routes/[region=region]/for-banks/+page.svelte src/params/region.ts // matcher: us | uk | au
hreflang is mandatory. Every marketing page must include hreflang tags pointing to the other regional variants so Google indexes each version correctly instead of flagging duplicate content.

3.2 Landing Redirect (CloudFront Function)

A CloudFront Function on the root domain performs the geo-redirect. Keep it small — CloudFront Functions have a ~1ms CPU budget.

function handler(event) { const req = event.request; // 1. Respect explicit preference const pref = getCookie(req.cookies, 'preferred_region'); if (pref && ['us', 'uk', 'au'].includes(pref)) { return redirect(`/${pref}/`); } // 2. Skip redirect for crawlers — they index each region const ua = req.headers['user-agent']?.value || ''; if (/googlebot|bingbot|slurp/i.test(ua)) return req; // 3. Geo lookup const country = req.headers['cloudfront-viewer-country']?.value; const region = country === 'GB' ? 'uk' : country === 'AU' ? 'au' : 'us'; return redirect(`/${region}/`); }

3.3 App Frontend (unscammy-frontend)

The React/Vite app ships as one build per region, each with its own baked-in VITE_API_URL and VITE_REGION. This eliminates all client-side region detection — the one-liner window.location.hostname.replace('.com', '.co.uk') currently in Constants.js must go.

BuildBuild-time envDeploy target
us-app VITE_API_URL=https://us.api.unscammed.com
VITE_REGION=US
ECS task in us-east-2 → us.app.unscammed.com
uk-app VITE_API_URL=https://uk.api.unscammed.com
VITE_REGION=UK
ECS task in eu-west-2 → uk.app.unscammed.com
au-app VITE_API_URL=https://au.api.unscammed.com
VITE_REGION=AU
ECS task in ap-southeast-2 → au.app.unscammed.com
Rule: The app does not geo-redirect on load. A user's region is established at signup and stored in their JWT. If a UK user lands on us.app. while logged in, show a "switch region" banner — never auto-redirect an authenticated session. It breaks in-flight forms and auth state.

Section 4

Linking Marketing → App

Every CTA on the marketing site links to the matching regional app subdomain. Region is a property of the page, not the user.

4.1 Region Config (single source of truth)

// config/regions.ts (unscammed-website) export const REGIONS = { us: { appUrl: 'https://us.app.unscammed.com', apiUrl: 'https://us.api.unscammed.com', currency: 'USD', locale: 'en-US', phoneCode: '+1', supportEmail: 'support@unscammed.com' }, uk: { appUrl: 'https://uk.app.unscammed.com', apiUrl: 'https://uk.api.unscammed.com', currency: 'GBP', locale: 'en-GB', phoneCode: '+44', supportEmail: 'uk-support@unscammed.com' }, au: { /* ... */ }, } as const;

SvelteKit reads the region from the URL param in the layout, passes it into every page via context, and every CTA becomes <a href={region.appUrl + '/signup'}>. No hardcoded URLs anywhere.

4.2 CTA Behaviour Matrix

PageCTATarget URL
/uk/ Get Started https://uk.app.unscammed.com/signup?ref=uk-landing
/uk/ Log in https://uk.app.unscammed.com/login
/us/ Report a scam https://us.app.unscammed.com/report?ref=us-landing
/au/ Pricing https://au.app.unscammed.com/pricing?ref=au-landing
/uk/for-banks Request demo https://uk.app.unscammed.com/demo?ref=uk-for-banks

?ref= captures attribution so funnel analytics can segment app signups by marketing source.

4.3 Cross-Region Edge Cases

ScenarioHandling
User on /us/ but geolocated in UK clicks signup App at us.app. detects mismatch post-signup, shows soft prompt: "Switch to uk.app.unscammed.com?". Does not force. Expats and travellers have legitimate reasons.
Logged-in UK user opens us.app. directly App reads region from JWT on load, redirects to uk.app. preserving the original path. Safe because state is authenticated.
User wants to explicitly switch region Footer dropdown on every marketing page sets the preferred_region cookie. Future visits to unscammed.com skip the geo-redirect.
Marketing site needs to call an API (e.g. "check email exists") Don't. Keep marketing → app as a full-page navigation, not XHR. Clean boundary, no CORS pain, no cross-region auth state.
Auth continuity note: Cookies set on uk.app.unscammed.com do not share with us.app.unscammed.com — that is exactly what we want for data residency. If cross-region SSO is ever needed (probably for admin only), issue tokens on the .unscammed.com scope or use a central identity provider.

Section 5

Backend Strategy

Every backend service deploys per region. Region becomes a deploy-time environment variable, not a request-time detection problem.

ServiceCurrentTarget
unscammy-chat
FastAPI
Single EC2 in us-east-2. Region detected from request headers via detect_region_from_headers(). One ECS service per region. us-east-2 and eu-west-2 at launch. Region is a deploy env var. detect_region_from_headers() deleted entirely.
unscammy-voice
Flask
Single EC2. Region inferred from phone-number prefix — breaks for +1 CA/US overlap. Per-region deploy. Region determined by which regional Twilio number was dialled. Provisioning, not inference.
unscammy-browser-use
FastAPI
Single EC2 serving both markets. Per-region deploy. Data-broker and regulatory targets are jurisdiction-specific anyway (UK ICO vs US state AGs).
unscammed-website
SvelteKit
Single EC2 with Strapi + SvelteKit. Unchanged. Single global deployment with subdirectory routing. Strapi serves locale-specific content.
Alembic migrations: Continue using the REGION env var to select the target cluster. CI runs migrations per-region in parallel. Schema stays identical across regions — what differs is the data, not the structure.
# CI step: migrate all regions in parallel REGION=US alembic upgrade head REGION=UK alembic upgrade head REGION=AU alembic upgrade head

Section 6

Data Layer

Three stores, each with a distinct multi-region pattern. This is where residency and performance both live.

Aurora Serverless v2

Pattern: Per-region cluster. No cross-region replication.

  • US → us-east-2
  • UK → eu-west-2
  • AU → ap-southeast-2

Why: GDPR Art. 44–49 compliance. UK PII physically stays in EEA. Each region scales independently.

DynamoDB Global Tables

Pattern: Shared intelligence index replicated across all regions.

  • Scam patterns
  • Known-bad numbers
  • Domain reputation

Why: Intelligence is anonymised signal, not PII — safe to replicate globally. Eventual consistency is acceptable for lookups.

DAX

Pattern: In-region DAX cluster in front of Global Tables for the KYT API hot path.

  • Sub-15ms response
  • Write-through caching
  • Per-region scaling

Why: The latency number that wins bank deals. This is what the Bank Platform strategy pitches.

Residency rule: PII never crosses regions. Intelligence signal (scam patterns, reputation) always does. The split is deliberate — compliance requires the former, product value requires the latter.

Section 7

Route 53 Routing

All region resolution happens at DNS. By the time a request reaches application code, region is decided and immutable.

┌─ Marketing ─────────────────────────────────────────────────────┐ unscammed.com ──▶ CloudFront (geo-redirect fn) └─▶ /us/, /uk/, /au/ ┌─ App ───────────────────────────────────────────────────────────┐ us.app.unscammed.com ──▶ ALB us-east-2 ──▶ US frontend ECS uk.app.unscammed.com ──▶ ALB eu-west-2 ──▶ UK frontend ECS au.app.unscammed.com ──▶ ALB ap-southeast-2 ──▶ AU frontend ECS ┌─ API ───────────────────────────────────────────────────────────┐ us.api.unscammed.com ──▶ API Gateway us-east-2 ──▶ US Aurora uk.api.unscammed.com ──▶ API Gateway eu-west-2 ──▶ UK Aurora au.api.unscammed.com ──▶ API Gateway ap-southeast-2 ──▶ AU Aurora ┌─ KYT (banks) ───────────────────────────────────────────────────┐ kyt.unscammed.com ──▶ latency-based routing └─▶ nearest API GW ──▶ DAX ──▶ DDB Global ┌─ Admin ─────────────────────────────────────────────────────────┐ admin.unscammed.com ──▶ CloudFront (global admin UI) └─▶ region dropdown calls us/uk/au API
HostRoute 53 RecordTarget
unscammed.comA → CloudFrontMarketing CDN; geo-redirect function
us.app.unscammed.comA-ALIAS → ALBUS frontend build in us-east-2
uk.app.unscammed.comA-ALIAS → ALBUK frontend build in eu-west-2
us.api.unscammed.comA-ALIAS → API GWunscammy-chat US → US Aurora
uk.api.unscammed.comA-ALIAS → API GWunscammy-chat UK → UK Aurora
kyt.unscammed.comLatency-basedNearest API GW → DAX → DDB Global
admin.unscammed.comA-ALIAS → CloudFrontSingle admin UI; calls regional APIs via dropdown

Section 8

Admin Cross-Region Access

The AdminDataRegionMiddleware UX problem from the dossier is solved cleanly at this layer.

The Problem Today

Admins cannot access cross-region data without logging into the matching domain. A UK admin at .com cannot authenticate because their credentials are in the UK database. This is a UX dead-end the dossier explicitly called out.

The Solution

Single admin UI at admin.unscammed.com with a region selector. The UI calls the target region's API directly (us.api. vs uk.api.) based on dropdown selection. Admin identity lives in a separate global auth store (Cognito or a dedicated admin Aurora), so one login works across all regions.

Key split: Admin identity is global. Regional APIs enforce authorisation (does this admin have access to UK data?) but they do not own admin identity. This lets us scope admins across regions without replicating PII.

Part III — Rollout

Five phases, each independently deployable and independently valuable. Phases 1 and 2 require no backend changes and can ship in parallel.

Section 9

Phased Rollout Plan

Delivered in five phases. Phase 3 is the GDPR milestone; Phase 4 is the bank-deal unlock.

Phase 1 — Marketing Subdirectories 2 weeks

Scope

  • Restructure unscammed-website routes under [region]
  • Deploy CloudFront Function for geo-redirect
  • Add hreflang tags across all marketing pages
  • 301 redirects from every legacy URL to its /us/ equivalent
  • Update sitemap; resubmit in Google Search Console

Outcome

SEO-visible regional content. Zero infrastructure risk. Immediately usable for localised marketing campaigns. No backend touched.

Risks

~2 week ranking dip as 301s propagate. Recovers fully as redirects are crawled.

Phase 2 — Regional App Frontends 4 weeks

Scope

  • Split unscammy-frontend into per-region builds with build-time VITE_API_URL
  • Delete all client-side region detection (the .replace('.com', '.co.uk') pattern)
  • Deploy us.app. and uk.app. subdomains
  • Ship admin region dropdown ahead of Phase 3 so admins get familiar with the UX

Outcome

Kills all client-side region detection. Clean URL separation in place before data layer changes. Backend still single-region — two frontends hit one API.

Phase 3 — UK Aurora (GDPR Milestone) 6–8 weeks

Scope

  • Stand up UK Aurora Serverless v2 cluster in eu-west-2
  • Migrate UK rows from shared cluster to new UK cluster
  • Deploy UK API stack (unscammy-chat, unscammy-voice, unscammy-browser-use) in eu-west-2
  • Flip uk.api. DNS to eu-west-2 endpoint
  • US stack untouched throughout

Outcome

GDPR-compliant data residency. The single biggest legal and sales unblocker for UK expansion and bank deals in the EEA. Removes the GDPR Art. 44 exposure identified in the dossier.

Phase 4 — KYT + DAX 4 weeks

Scope

  • Migrate shared scam-intelligence index from Aurora to DynamoDB Global Tables
  • Deploy DAX clusters in each region for the KYT API hot path
  • Stand up kyt.unscammed.com with latency-based Route 53 routing
  • Define the eventual-consistency contract in the public KYT API spec

Outcome

Sub-15ms KYT API. The technical differentiator pitched in the Bank Platform strategy — the latency number that wins RFPs against Socure and Alloy.

Phase 5 — Australia 2 weeks

Scope

  • New Aurora cluster in ap-southeast-2
  • New ECS services for each backend
  • New Route 53 records: au.app., au.api.
  • New /au/ marketing subdirectory with translated content

Outcome

Validates the architecture's scalability. If adding AU takes more than 2 weeks, something upstream was over-fitted to the US/UK case and needs refactoring.


Part IV — Analysis

Risks, mitigations, and the full decisions log showing what was considered and rejected at every fork.

Risks

Risks & Mitigations

Known risks across SEO, user migration, consistency, admin UX, and cost. Each with an explicit mitigation.

1

SEO dilution during Phase 1

Existing unscammed.com URLs become unscammed.com/us/.... Some ranking loss is inevitable. Mitigation: 301 redirects from every legacy URL, updated sitemap, resubmission in Search Console. Expect a ~2 week dip; recovers fully as redirects are crawled.

2

Cross-region user migration

A US user who relocates to the UK cannot easily move their account. Mitigation: Not a Day 1 problem. When it comes up, build a one-time, user-initiated migration flow with explicit GDPR consent. Do not attempt automated detection — it will misfire for VPN users and travellers.

3

Intelligence Index consistency

A scam signal reported in UK should appear in US lookups within seconds. Mitigation: DynamoDB Global Tables replication is typically sub-1-second. For security-critical lookups (known-bad numbers during a live call) this is acceptable. Document the eventual-consistency contract in the KYT API spec so bank customers know what to expect.

4

Admin productivity during migration

Cross-region debugging is harder when data is physically split. Mitigation: Ship the admin region dropdown in Phase 2, before the data split in Phase 3. Admins get familiar with the UX before it becomes load-bearing.

5

Operational cost

Per-region infrastructure is more expensive than shared. Mitigation: Aurora Serverless v2 scales to near-zero when idle. ECS tasks are sized per-region traffic. Expected incremental monthly cost for the UK cluster: ~$400–600 at launch load, scaling with adoption. Cost is justified by GDPR compliance alone, before any revenue upside.


Decisions

Decisions Log

Every architectural fork, what was chosen, and what was rejected. Keep this section short; add to it as the strategy evolves.

DecisionChosenRejected alternatives
Domain strategy Single unscammed.com with subdomains + subdirectories Per-country ccTLDs (.co.uk, .com.au) — fragments SEO, higher ops cost, more certs to manage
Marketing routing Subdirectories (/uk/, /us/) Subdomains (uk.unscammed.com) — fragments domain authority for a new brand
App routing Subdomains (uk.app.) Paths (app.unscammed.com/uk) — cannot satisfy DNS-level residency requirement
Region resolution DNS (Route 53) Headers, JWT claims, hostname parsing, phone-prefix inference — all four current methods are spoofable
Cross-region user data No replication of PII; per-region Aurora Global tables for user data — violates GDPR Art. 44
Cross-region intelligence DynamoDB Global Tables + DAX Aurora read replicas across regions — slower, more expensive, no value for anonymised data
Landing page behaviour Geo-redirect with cookie override; skip for crawlers Show a region picker on first visit — worse UX, lower conversion
App region switching Soft prompt for unauthenticated; redirect preserving path for authenticated Hard auto-redirect on every visit — breaks expats, travellers, and in-flight sessions
Admin identity Global admin auth store; regional APIs enforce authorisation Per-region admin accounts — creates the UX dead-end the dossier called out
Marketing ↔ app handoff Full-page navigation with ?ref= attribution XHR/fetch from marketing to app API — CORS pain, cross-region auth state complexity
Final statement: Every decision above flows from two principles: (1) region must be resolved at infrastructure, not application, and (2) shared SEO authority is more valuable than shared infrastructure. Once those are fixed, the rest of the architecture falls out.