Technical Appendix

Production

Under the hood. API endpoints, authentication, data models, and technical reference for CTOs and developers.

API Overview

All Campaign Brain services expose RESTful APIs with consistent patterns:

Base URL: https://[service].nominate.ai/api/v1
Authentication: Bearer token (JWT)
Content-Type: application/json

Common Endpoints

MethodEndpointDescription
GET/healthService health check
GET/meCurrent user info
GET/[resource]List resources
GET/[resource]/[id]Get single resource
POST/[resource]Create resource
PUT/[resource]/[id]Update resource
DELETE/[resource]/[id]Delete resource

Authentication

Campaign Brain uses JWT-based authentication with refresh tokens.

Token Flow

  1. Login: POST /auth/login with credentials
  2. Receive: Access token (15 min) + Refresh token (7 days)
  3. Use: Include Authorization: Bearer [access_token] in requests
  4. Refresh: POST /auth/refresh with refresh token when expired

Scopes

ScopeAccess Level
read:votersView voter records
write:votersModify voter records
read:campaignsView campaign data
admin:campaignsManage campaigns
read:analyticsView dashboards and reports

Data Models

Voter Record

{
  "id": "uuid",
  "voter_file_id": "state-assigned-id",
  "first_name": "string",
  "last_name": "string",
  "address": {
    "street": "string",
    "city": "string",
    "state": "string",
    "zip": "string"
  },
  "demographics": {
    "age": "number",
    "gender": "string",
    "party": "string"
  },
  "scores": {
    "turnout": "number (0-100)",
    "support": "number (0-100)",
    "persuadable": "number (0-100)"
  },
  "contact_history": ["ContactEvent"],
  "tags": ["string"],
  "created_at": "timestamp",
  "updated_at": "timestamp"
}

Contact Event

{
  "id": "uuid",
  "voter_id": "uuid",
  "type": "door|phone|sms|email|mail",
  "outcome": "contact|not_home|refused|wrong_number|moved",
  "notes": "string",
  "survey_responses": {},
  "created_by": "uuid",
  "created_at": "timestamp"
}

Workflow Definition

{
  "id": "uuid",
  "name": "string",
  "status": "draft|active|paused|archived",
  "trigger": {
    "type": "segment|event|schedule",
    "config": {}
  },
  "nodes": ["WorkflowNode"],
  "created_at": "timestamp",
  "updated_at": "timestamp"
}

Service Ports

Development and internal routing reference:

ServicePortSubdomain
cbpublic3000nominate.ai
cbtenant3001tenant.nominate.ai
cbapp3002{tenant}.nominate.ai
cbworkflow3003workflow.nominate.ai
cbsurveys3004surveys.nominate.ai
cbdistricts3005districts.nominate.ai
cbmodels3006models.nominate.ai
cbradio3007ruralamfm.nominate.ai
cbfiles3008files.nominate.ai
cbinfra3009— (internal)
cbai3010— (internal)
cbetl3011— (internal)

GitHub Repositories

Nominate-AI/cbpublic     — Public website
Nominate-AI/cbtenant     — Tenant manager
Nominate-AI/cbapp        — Campaign app
Nominate-AI/cbworkflow   — Workflow engine
Nominate-AI/cbsurveys    — Survey platform
Nominate-AI/cbdistricts  — District service
Nominate-AI/cbmodels     — Analytics
Nominate-AI/cbradio      — Radio advertising
Nominate-AI/cbfiles      — File storage
Nominate-AI/cbinfra      — Infrastructure
Nominate-AI/cbai         — AI service
Nominate-AI/cbetl        — ETL pipeline

Rate Limits

TierRequests/minBurst
Free6010
Standard30050
Pro1000100
EnterpriseCustomCustom

Rate limit headers included in all responses:


Error Codes

CodeDescription
400Bad request - validation error
401Unauthorized - invalid or expired token
403Forbidden - insufficient permissions
404Not found - resource doesn't exist
409Conflict - duplicate or state conflict
429Too many requests - rate limited
500Internal error - please retry

Error response format:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human-readable description",
    "details": {}
  }
}

Full API Documentation

Complete API documentation with interactive examples is available at docs.nominate.ai.