Skip to main content

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

EndpointPurpose
POST /v1/contactContact form submissions → SendGrid confirmation + notification
POST /v1/supportSupport requests → SendGrid + Crisp (planned)
POST /v1/feedbackIn-app feedback from RoundTrip → SendGrid (planned)
GET /healthHealth 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

ResourceNameNotes
App Serviceapp-commandcenter-production.NET 10, Linux, Central US
Resource Grouprg-commandcenter-production
Key Vaultkv-commandcenter-proManaged identity access
Custom Domainapi.traxsgroup.comHTTPS via managed certificate
ADO Service ConnectionAzure-CommandCenterScoped to subscription

Configuration

Key Vault Secrets

Secret NameConfig KeyPurpose
SendGrid--ApiKeySendGrid:ApiKeySendGrid API key for all outbound email

App Service Settings

SettingValueSource
ASPNETCORE_ENVIRONMENTProductionApp Service
SendGrid__ApiKeyKey Vault referencekv-commandcenter-pro
SendGrid__FromEmailnoreply@roundtrips.appApp Service
SendGrid__FromNameRoundTrip by Traxs Group LLCApp Service
Notifications__Emailhello@traxsgroup.comApp 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:

  1. Build — restore, build Release, publish Web project, upload artifact
  2. Deploy — download artifact, deploy to app-commandcenter-production via AzureWebApp@1

Pipeline variables:

  • No secrets needed — uses Azure-CommandCenter service connection for deployment

DNS Configuration

api.traxsgroup.com is configured in Cloudflare on the traxsgroup.com zone:

TypeNameValueProxy
TXTasuid.api6e7cae23fa4f4458ded133b38429987a04a1554df29b516678bea13d558c742bDNS only
CNAMEapiapp-commandcenter-production.azurewebsites.netDNS 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:

  1. 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
  2. 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

Contact Request Types

ValueEnumUse Case
0GeneralInquiryGeneral questions
1SupportSupport requests
2FeedbackProduct feedback
3DemoRequestDemo booking requests

Troubleshooting

Health check failing

curl -v https://api.traxsgroup.com/health

Should return HTTP/2 200. If not:

  1. Check App Service is running in Azure Portal
  2. 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:

  1. Azure Portal → app-commandcenter-production → Environment variables
  2. Verify SendGrid__ApiKey shows green Key Vault checkmark
  3. If red/yellow — check kv-commandcenter-pro secrets and managed identity access
  4. Full stop/start App Service after fixing

Emails not arriving

Check SendGrid activity log for both recipient addresses. Common causes:

  • hello@traxsgroup.com M365 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

  1. Generate a new API key in SendGrid dashboard
  2. Update SendGrid--ApiKey in kv-commandcenter-pro with + New version
  3. Update Bitwarden → "SendGrid"
  4. Full stop → start app-commandcenter-production
  5. Test with curl -X POST https://api.traxsgroup.com/v1/contact ...

Adding New Endpoints

Follow the same pattern as SubmitContactEndpoint:

  1. Add command/result record to CommandCenter.API.UseCases/Features/{Feature}/
  2. Add handler implementing IRequestHandler<TCommand, TResult>
  3. Add validator extending AbstractValidator<TCommand>
  4. Add endpoint in CommandCenter.API.Web/Endpoints/{Feature}/
  5. Add any new infrastructure services to InfrastructureServiceExtensions
  6. Commit, push to main — pipeline deploys automatically