API Response Types
This document describes the API response type definitions and validation for the GP3MixMedia TrailMix platform.
Overview
The API provides:
- Type Safety: Full TypeScript types for requests and responses
- Runtime Validation: Zod schemas for input validation
- API Documentation: OpenAPI 3.0 specification
- Client Generation: OpenAPI spec for generating client libraries
Type Definitions Location
All type definitions are in the /types directory:
| File | Contents |
|---|---|
/types/api-responses.ts | Common API response types |
/types/campaign-types.ts | Campaign-specific types |
/types/api-schemas.ts | Zod validation schemas |
Common Response Types
Pagination
Cursor-based pagination:
interface PaginationInfo {
cursor: number | null;
nextCursor: number | null;
hasNextPage: boolean;
limit: number;
}
Offset-based pagination:
interface OffsetPaginationInfo {
page: number;
limit: number;
total: number;
totalPages: number;
}
Error Responses
// Single error
interface ErrorResponse {
error: string;
}
// Multiple errors
interface ErrorsResponse {
errors: string[];
}
// Success message
interface SuccessResponse {
message: string;
}
Health Check
interface HealthCheckResponse {
status: 'healthy' | 'unhealthy';
timestamp: string;
checks?: {
database: boolean;
redis?: boolean;
s3?: boolean;
};
}
Campaign Types
Campaign Status
type CampaignStatus = 'draft' | 'active' | 'paused' | 'completed' | 'archived';
Campaign Summary
interface CampaignSummary {
id: number;
candidateNames: string;
campaignName: string;
status: CampaignStatus;
lastUpdatedAt: string;
lastStationRefreshAt: string | null;
stationCount: number;
markets: string[];
lastIngestionAt: string | null;
ingestionRecordCount: number;
}
Campaign List Response
interface CampaignListResponse {
campaigns: CampaignSummary[];
pageInfo: PaginationInfo;
}
Using Types in API Routes
Typed GET Handler
import { NextRequest, NextResponse } from 'next/server';
import type { CampaignListResponse } from '@/types/campaign-types';
export async function GET(request: NextRequest): Promise<NextResponse<CampaignListResponse>> {
// ... implementation
return NextResponse.json({
campaigns: summaries,
pageInfo: { cursor, nextCursor, limit, hasNextPage },
});
}
Typed POST Handler
import { NextRequest, NextResponse } from 'next/server';
import type { CampaignCreationResponse } from '@/types/campaign-types';
export async function POST(request: NextRequest): Promise<NextResponse<CampaignCreationResponse>> {
// ... implementation
return NextResponse.json(result, { status: 201 });
}
Validation with Zod
Request Validation
import { CampaignCreationRequestSchema } from '@/types/campaign-schemas';
export async function POST(request: NextRequest) {
const payload = await request.json();
const result = CampaignCreationRequestSchema.safeParse(payload);
if (!result.success) {
return NextResponse.json(
{ errors: result.error.errors.map((e) => e.message) },
{ status: 400 }
);
}
const validatedData = result.data;
// ... continue with validated data
}
OpenAPI Specification
Generating the Spec
npm run generate:openapi
Creates: /public/api-docs/openapi.json
Viewing Documentation
- Swagger UI: Upload to Swagger Editor
- Redoc: Use Redoc
- Local Preview:
npx @redocly/cli preview-docs public/api-docs/openapi.json
Data Type Enums
Medium Types
type MediumType =
| 'broadcast'
| 'cable'
| 'radio'
| 'digital'
| 'ott'
| 'ctv'
| 'mail'
| 'phones'
| 'social'
| 'other'
| 'unknown';
Dedupe Status
type DedupeStatus = 'pending' | 'resolved' | 'skipped';
Email Send Status
type EmailSendStatus = 'queued' | 'scheduled' | 'sent' | 'delivered' | 'bounced' | 'failed';
Alert Channels
type AlertChannel = 'email' | 'push' | 'in_app';
Notification Types
type NotificationType = 'info' | 'success' | 'warning' | 'error';
Frontend Usage
Fetching with Types
import type { CampaignListResponse } from '@/types/campaign-types';
async function fetchCampaigns(cursor?: number): Promise<CampaignListResponse> {
const params = new URLSearchParams();
if (cursor) params.set('cursor', cursor.toString());
const response = await fetch(`/api/v1/campaigns?${params}`);
if (!response.ok) throw new Error('Failed to fetch');
return response.json();
}
Best Practices
- Always use types for API route handlers
- Validate input with Zod schemas
- Generate OpenAPI spec after adding new endpoints
- Keep types in sync with actual responses
- Use strict TypeScript settings
Adding New Endpoints
- Define TypeScript types in
/types/ - Create Zod schemas with OpenAPI extensions
- Register schemas in
/scripts/generate-openapi.ts - Register paths in OpenAPI generator
- Generate spec:
npm run generate:openapi - Update route handlers to use typed responses
Last Updated: March 2026
Was this helpful? If you have feedback or questions, please contact your administrator.