Command Center API
The Command Center API is the Traxs Group platform API — a lightweight, focused backend that serves all Traxs Group products and web properties. It handles contact form submissions, support requests, and feedback routing across traxsgroup.com, roundtrips.app, and future Traxs products.
See ADR-007 for the full architectural decision behind building a separate platform API rather than adding these endpoints to the RoundTrip API.
What the Command Center API Does
| Endpoint | Purpose |
|---|---|
POST /v1/contact | Contact form submissions → SendGrid confirmation + notification |
POST /v1/support | Support requests → SendGrid + Crisp (planned) |
POST /v1/feedback | In-app feedback from RoundTrip → SendGrid (planned) |
GET /health | Health check |
Architecture
Same Clean Architecture as RoundTrip — FastEndpoints, Cyrus Mediator, Infrastructure/UseCases/Core/Web layers. No database initially — pure pass-through to SendGrid.
Contact Form (Astro marketing site)
→ POST /api/contact (Astro server endpoint — keeps API key server-side)
→ POST https://api.traxsgroup.com/v1/contact (Command Center API)
→ SendGrid confirmation email → submitter
→ SendGrid notification email → hello@traxsgroup.com
Solution Structure
CommandCenterAPI/
CommandCenter.API.Core/ ← Interfaces, Models, Enums
CommandCenter.API.UseCases/ ← Commands, Handlers, Validators
CommandCenter.API.Infrastructure/ ← SendGridEmailService
CommandCenter.API.Web/ ← FastEndpoints, Program.cs
Directory.Packages.props ← Central Package Management
Directory.Build.props ← Shared build properties
azure-pipelines.yml ← ADO pipeline
Infrastructure
| Resource | Name | Notes |
|---|---|---|
| App Service | app-commandcenter-production | .NET 10, Linux, Central US |
| Resource Group | rg-commandcenter-production | |
| Key Vault | kv-commandcenter-pro | Managed identity access |
| Custom Domain | api.traxsgroup.com | HTTPS via managed certificate |
| ADO Service Connection | Azure-CommandCenter | Scoped to subscription |
Configuration
Key Vault Secrets
| Secret Name | Config Key | Purpose |
|---|---|---|
SendGrid--ApiKey | SendGrid:ApiKey | SendGrid API key for all outbound email |
App Service Settings
| Setting | Value | Source |
|---|---|---|
ASPNETCORE_ENVIRONMENT | Production | App Service |
SendGrid__ApiKey | Key Vault reference | kv-commandcenter-pro |
SendGrid__FromEmail | noreply@roundtrips.app | App Service |
SendGrid__FromName | RoundTrip by Traxs Group LLC | App Service |
Notifications__Email | hello@traxsgroup.com | App Service |
CORS Allowed Origins
Configured in appsettings.json — no App Service setting needed:
{
"Cors": {
"AllowedOrigins": [
"https://roundtrips.app",
"https://www.roundtrips.app",
"https://traxsgroup.com",
"https://www.traxsgroup.com",
"https://roundtrip-marketing.pages.dev"
]
}
}
Update this list when new frontends are added.
ADO Pipeline
Repo: Traxs-dev/CommandCenterAPI
Pipeline file: azure-pipelines.yml
Trigger: Push to main
Agent: laptop in traxs-self-hosted pool
Pipeline stages:
- Build — restore, build Release, publish Web project, upload artifact
- Deploy — download artifact, deploy to
app-commandcenter-productionviaAzureWebApp@1
Pipeline variables:
- No secrets needed — uses
Azure-CommandCenterservice connection for deployment
DNS Configuration
api.traxsgroup.com is configured in Cloudflare on the traxsgroup.com zone:
| Type | Name | Value | Proxy |
|---|---|---|---|
| TXT | asuid.api | 6e7cae23fa4f4458ded133b38429987a04a1554df29b516678bea13d558c742b | DNS only |
| CNAME | api | app-commandcenter-production.azurewebsites.net | DNS only |
:::caution DNS Only Both records must be set to DNS only (grey cloud) — not proxied. Proxied records break the Azure App Service hostname verification and SSL. :::
Email Flow
Contact Form Submission
When a contact form is submitted:
-
Submitter receives a confirmation email from
noreply@roundtrips.app- Subject: "We received your message — RoundTrip by Traxs Group LLC"
- Branded HTML email with their message quoted back
-
Traxs team receives a notification at
hello@traxsgroup.com- Subject:
[{ContactRequestType}] New contact from {FirstName} {LastName} - Full details: name, email, company, message type, message body
- Subject:
Contact Request Types
| Value | Enum | Use Case |
|---|---|---|
0 | GeneralInquiry | General questions |
1 | Support | Support requests |
2 | Feedback | Product feedback |
3 | DemoRequest | Demo booking requests |
Troubleshooting
Health check failing
curl -v https://api.traxsgroup.com/health
Should return HTTP/2 200. If not:
- Check App Service is running in Azure Portal
- Check App Service logs:
az webapp log tail --name app-commandcenter-production --resource-group rg-commandcenter-production
Contact form returning 500
Check SendGrid API key is resolving correctly:
- Azure Portal →
app-commandcenter-production→ Environment variables - Verify
SendGrid__ApiKeyshows green Key Vault checkmark - If red/yellow — check
kv-commandcenter-prosecrets and managed identity access - Full stop/start App Service after fixing
Emails not arriving
Check SendGrid activity log for both recipient addresses. Common causes:
hello@traxsgroup.comM365 shared mailbox delivery can be slow — check the shared mailbox in Outlook- Spam folder on recipient side
- SendGrid API key expired or revoked
CORS errors from frontend
Add the new origin to AllowedOrigins in appsettings.json, commit, and push — the pipeline will deploy automatically.
Rotating the SendGrid API Key
- Generate a new API key in SendGrid dashboard
- Update
SendGrid--ApiKeyinkv-commandcenter-prowith + New version - Update Bitwarden → "SendGrid"
- Full stop → start
app-commandcenter-production - Test with
curl -X POST https://api.traxsgroup.com/v1/contact ...
Adding New Endpoints
Follow the same pattern as SubmitContactEndpoint:
- Add command/result record to
CommandCenter.API.UseCases/Features/{Feature}/ - Add handler implementing
IRequestHandler<TCommand, TResult> - Add validator extending
AbstractValidator<TCommand> - Add endpoint in
CommandCenter.API.Web/Endpoints/{Feature}/ - Add any new infrastructure services to
InfrastructureServiceExtensions - Commit, push to main — pipeline deploys automatically
Related
- ADR-007: Platform API vs RoundTrip API
- Services: SendGrid
- TRA-337 — Initial scaffold and deployment
- TRA-338 — Astro contact form integration