ADR-007: Platform API vs RoundTrip API
Date: 2026-07-04
Status: Accepted
Deciders: Pete Carroll
Context
As Traxs Group LLC grows beyond RoundTrip to include Apex, Waypoint, and Relay, certain cross-cutting concerns need a home. The immediate trigger was the need to handle contact forms on traxsgroup.com and roundtrips.app without using mailto: links — which are unprofessional and provide no control over routing, formatting, or delivery confirmation.
Two options were evaluated:
- Add contact form endpoints directly to the RoundTrip API
- Build a separate Platform API (
api.traxsgroup.com) that serves all Traxs Group products
Additionally, the existing RoundTrip API is a multi-tenant SaaS backend with JWT authentication, tenant scoping, EF Core, Hangfire, and SignalR — significant infrastructure that is overkill and inappropriate for serving unauthenticated public contact forms from a marketing website.
Decision
Build a separate Command Center API hosted at api.traxsgroup.com as the company-level platform API for Traxs Group LLC.
The Command Center API:
- Follows the same Clean Architecture as RoundTrip (FastEndpoints, Cyrus Mediator, same patterns and conventions)
- Has no database initially — pure pass-through to SendGrid and Crisp
- Is unauthenticated for public endpoints (contact forms)
- Will gain authentication and persistence as scope expands
- Serves all Traxs Group products, not just RoundTrip
Initial endpoints:
POST /v1/contact ← contact form submissions (traxsgroup.com, roundtrips.app)
POST /v1/support ← support requests
POST /v1/feedback ← in-app feedback from RoundTrip
GET /health
Alternatives Considered
Option A — Add endpoints to RoundTrip API
Rejected. The RoundTrip API is a tenant-scoped, authenticated SaaS backend. Adding unauthenticated public endpoints violates the architectural intent and creates security surface area. It also couples company-level concerns (contact forms for traxsgroup.com) to a product-level API, making it harder to serve future Traxs products. Any developer working on RoundTrip would need to understand company-level routing concerns that have nothing to do with field service management.
Option B — Use a third-party form service (Formspree, Netlify Forms)
Rejected. Creates a dependency on a third-party service for a core business function. No control over email formatting, delivery confirmation, or routing logic. Cannot integrate with Crisp for support ticket creation. Cannot be extended as needs grow.
Option C — Astro server endpoints only (no separate API)
Partially adopted. Astro server endpoints handle the browser-facing form submission and keep API keys server-side. However, they delegate to the Command Center API rather than calling SendGrid directly — this keeps email delivery logic centralized and reusable across multiple frontends (traxsgroup.com, roundtrips.app, future products).
Consequences
What becomes easier:
- Any Traxs Group product can send emails, handle contact forms, or create support tickets by calling
api.traxsgroup.com— one integration point - RoundTrip API stays clean and focused on field service management concerns
- Future products (Apex, Waypoint, Relay) have a ready-made API to integrate with
- A developer familiar with RoundTrip can work on the Command Center API immediately — same patterns, same conventions
- The Command Center API is the natural home for future cross-product features: unified billing webhooks, tenant provisioning, platform-level notifications
What becomes harder:
- One more Azure App Service to maintain, monitor, and deploy
- One more ADO pipeline to manage
- Cross-product features require coordination between two APIs until a shared library pattern is established
What this enables long-term:
- Relay — the AI-powered support platform — will be built on top of the Command Center API infrastructure
- Tenant provisioning — when a customer signs up for any Traxs product, the Command Center API will handle the provisioning workflow
- Platform billing — Stripe webhook handling at the platform level rather than per-product
Architecture
TRAXS GROUP PLATFORM
Browser / PWA
│
├─ roundtrips.app ─────────────► RoundTrip API (api.roundtrips.app)
│ (Astro marketing site) Multi-tenant SaaS backend
│ (React app) JWT auth, tenant scoping
│ EF Core, Hangfire, SignalR
│
├─ traxsgroup.com ─────────────► Command Center API (api.traxsgroup.com)
│ (contact forms) No database (initially)
│ Unauthenticated public endpoints
└─ Any future product SendGrid, Crisp integration
Same Clean Architecture as RoundTrip
Implementation Notes
- Same solution structure as RoundTrip:
Domain,UseCases,Infrastructure,Webprojects - No
DbContextinitially — add when persistence is needed SendGridEmailServiceextracted to a shared NuGet package when both APIs need it (future)- Deployed to Azure App Service, Central US, same region as RoundTrip
- Custom domain:
api.traxsgroup.combound via Azure App Service custom domains - ADO pipeline mirrors RoundTrip API pipeline pattern
Related
- TRA-225 — Support platform strategy (Crisp, Relay roadmap)
- TRA-336 — Crisp support platform setup
- ADR-001: Clean Architecture for RoundTrip API
- Services: Command Center API (to be written)