Skip to main content

CODITECT Cloud Backend API Reference

Version: 1.0.0 Base URL: https://api.coditect.ai (Production) | http://localhost:8000 (Development) OpenAPI Spec: openapi-schema-generated.yaml Last Updated: 2026-01-08


Table of Contents


Authentication

This API uses JWT (JSON Web Token) authentication via Firebase.

Authentication Header

Authorization: Bearer <your-jwt-token>

Token Lifetime

Token TypeExpiration
Access Token15 minutes
Refresh Token7 days

Public Endpoints (No Auth Required)

  • GET /api/v1/health/
  • GET /api/v1/health/ready/
  • GET /api/v1/subscriptions/plans/
  • POST /api/v1/licenses/validate/
  • POST /api/v1/auth/register/
  • GET /api/v1/auth/verify-email/
  • POST /api/v1/auth/forgot-password/
  • POST /api/v1/auth/reset-password/

Health Endpoints

Health Check

Basic health check endpoint. Returns 200 if service is running.

Endpoint: GET /api/v1/health/

Response (200 OK):

{
"status": "healthy",
"timestamp": "2026-01-08T12:00:00Z",
"service": "coditect-license-platform",
"version": "1.0.0"
}

Readiness Check

Readiness check verifying database connectivity.

Endpoint: GET /api/v1/health/ready/

Response (200 OK):

{
"status": "ready",
"timestamp": "2026-01-08T12:00:00Z",
"checks": {
"database": "connected"
}
}

Response (503 Service Unavailable):

{
"status": "not_ready",
"timestamp": "2026-01-08T12:00:00Z",
"error": "Database connection failed"
}

Auth Endpoints

Register User

Register a new user with email and password. Creates organization and sends verification email.

Endpoint: POST /api/v1/auth/register/

Request Body:

{
"email": "user@example.com",
"password": "SecurePass123!",
"full_name": "John Doe",
"company_name": "Acme Inc"
}

Response (201 Created):

{
"id": "uuid",
"email": "user@example.com",
"full_name": "John Doe",
"company_name": "Acme Inc",
"email_verified": false,
"organization_id": "uuid",
"organization_name": "Acme Inc",
"role": "owner",
"created_at": "2026-01-08T10:00:00Z"
}

Errors:

  • 400 - Validation error
  • 409 - Email already exists

Verify Email

Verify user's email address using token from verification email.

Endpoint: GET /api/v1/auth/verify-email/?token=<token>

Query Parameters:

ParameterTypeRequiredDescription
tokenstringYesVerification token from email

Response (200 OK):

{
"message": "Email verified successfully"
}

Request Password Reset

Request password reset email. Always returns 200 for security.

Endpoint: POST /api/v1/auth/forgot-password/

Request Body:

{
"email": "user@example.com"
}

Response (200 OK):

{
"message": "If this email exists, a password reset link has been sent."
}

Reset Password

Reset password using token from email.

Endpoint: POST /api/v1/auth/reset-password/

Request Body:

{
"token": "reset-token-from-email",
"new_password": "NewSecurePass123!"
}

Response (200 OK):

{
"message": "Password reset successfully"
}

Subscription Endpoints

Get Subscription Plans

Get all available subscription plans with pricing and features.

Endpoint: GET /api/v1/subscriptions/plans/

Response (200 OK):

{
"plans": [
{
"id": "free",
"name": "Free",
"price": 0,
"interval": "month",
"currency": "usd",
"features": ["1 seat", "5 projects"],
"stripe_price_id": null,
"max_seats": 1
},
{
"id": "pro",
"name": "Pro",
"price": 29,
"interval": "month",
"currency": "usd",
"features": ["10 seats", "Unlimited projects", "Priority support"],
"stripe_price_id": "price_pro_monthly",
"max_seats": 10
}
]
}

Create Checkout Session

Create a Stripe Checkout session for subscription purchase.

Endpoint: POST /api/v1/subscriptions/checkout/ Authentication: Required

Request Body:

{
"price_id": "price_pro_monthly",
"seats": 5,
"success_url": "https://app.coditect.ai/success",
"cancel_url": "https://app.coditect.ai/pricing"
}

Response (200 OK):

{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_...",
"session_id": "cs_test_..."
}

Get Current Subscription

Get current organization subscription status.

Endpoint: GET /api/v1/subscriptions/current/ Authentication: Required

Response (200 OK):

{
"plan": "pro",
"subscription_status": "active",
"seats_purchased": 5,
"seats_used": 3,
"seats_remaining": 2,
"current_period_start": "2025-12-01T00:00:00Z",
"current_period_end": "2026-01-01T00:00:00Z",
"trial_end": null,
"cancel_at_period_end": false,
"stripe_subscription_id": "sub_..."
}

Update Subscription

Update subscription seats (proration applied).

Endpoint: POST /api/v1/subscriptions/update/ Authentication: Required

Request Body:

{
"seats": 10
}

Response (200 OK):

{
"message": "Subscription updated successfully",
"new_seats": 10,
"prorated_amount": "Calculated on next invoice"
}

Cancel Subscription

Cancel subscription immediately or at period end.

Endpoint: POST /api/v1/subscriptions/cancel/ Authentication: Required

Request Body:

{
"immediately": false
}

Response (200 OK):

{
"message": "Subscription will be canceled at period end",
"canceled_at": "2026-01-01T00:00:00Z"
}

Stripe Webhook

Stripe webhook endpoint for subscription lifecycle events.

Endpoint: POST /api/v1/subscriptions/webhook/ Authentication: Stripe Signature

Handled Events:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.payment_succeeded
  • invoice.payment_failed

License Endpoints

List Licenses

List all licenses for the authenticated user's organization.

Endpoint: GET /api/v1/licenses/ Authentication: Required

Query Parameters:

ParameterTypeDescription
is_activebooleanFilter by active status
tierstringFilter by tier (FREE, PRO, TEAM, ENTERPRISE)

Response (200 OK):

{
"licenses": [
{
"id": "uuid",
"key_string": "PROD-2025-ABCD-1234",
"tier": "PRO",
"is_active": true,
"is_expired": false,
"expiry_date": "2026-02-01T00:00:00Z",
"created_at": "2025-12-01T00:00:00Z"
}
],
"count": 1,
"active_license": {
"id": "uuid",
"key_string": "PROD-2025-ABCD-1234"
}
}

Get License Details

Get detailed information about a specific license.

Endpoint: GET /api/v1/licenses/{license_id}/ Authentication: Required

Response (200 OK):

{
"id": "uuid",
"key_string": "PROD-2025-ABCD-1234",
"tier": "PRO",
"features": {
"max_seats": 10,
"projects": "unlimited",
"support": "priority"
},
"is_active": true,
"is_expired": false,
"expiry_date": "2026-02-01T00:00:00Z",
"organization": {
"id": "uuid",
"name": "Acme Inc"
}
}

Download License

Download a signed license file (JSON format).

Endpoint: GET /api/v1/licenses/{license_id}/download/ Authentication: Required

Response (200 OK):

Returns a downloadable JSON file with Content-Disposition header.

{
"license": {
"license_key": "PROD-2025-ABCD-1234",
"organization": {
"id": "uuid",
"name": "Acme Inc"
},
"tier": "PRO",
"features": {...},
"expiry_date": "2026-02-01T00:00:00Z"
},
"signature": "base64-encoded-signature",
"metadata": {
"generated_at": "2026-01-08T12:00:00Z",
"format_version": "1.0",
"verification_url": "https://api.coditect.ai/api/v1/licenses/validate/"
}
}

Validate License

Validate a license key (public endpoint, rate-limited).

Endpoint: POST /api/v1/licenses/validate/

Request Body:

{
"key_string": "PROD-2025-ABCD-1234"
}

Response (200 OK - Valid):

{
"valid": true,
"license": {
"key_string": "PROD-2025-ABCD-1234",
"tier": "PRO",
"features": {...},
"expiry_date": "2026-02-01T00:00:00Z",
"is_active": true,
"is_expired": false
},
"organization": {
"id": "uuid",
"name": "Acme Inc"
}
}

Response (200 OK - Invalid):

{
"valid": false,
"reason": "license_expired",
"message": "License expired on 2025-12-31T00:00:00Z"
}

License Seat Management

Acquire License Seat

Atomically acquire a license seat for the authenticated user.

Endpoint: POST /api/v1/licenses/acquire/ Authentication: Required

Request Body:

{
"license_key": "PROD-2025-ABCD-1234",
"hardware_id": "mac-address-hash-xyz",
"ip_address": "192.168.1.100",
"client_version": "1.0.0"
}

Response (200 OK):

{
"session_id": "uuid",
"license_key": "PROD-2025-ABCD-1234",
"expires_at": "2026-01-08T12:06:00Z",
"is_active": true,
"seats_remaining": 4
}

Session Heartbeat

Maintain an active session with heartbeat.

Endpoint: PATCH /api/v1/licenses/sessions/{session_id}/heartbeat/ Authentication: Required

Response (200 OK):

{
"session_id": "uuid",
"expires_at": "2026-01-08T12:09:00Z",
"is_active": true
}

Release License Seat

Release a license seat when done.

Endpoint: DELETE /api/v1/licenses/sessions/{session_id}/ Authentication: Required

Response (200 OK):

{
"message": "Session released successfully",
"seats_remaining": 5
}

Error Handling

Standard Error Format

{
"error": "Error type",
"detail": "Detailed error message"
}

Validation Error Format

{
"errors": {
"field_name": ["Error message 1", "Error message 2"]
}
}

HTTP Status Codes

CodeDescription
200Success
201Created
400Bad Request - Invalid input
401Unauthorized - Invalid or missing token
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
409Conflict - Resource already exists
429Too Many Requests - Rate limit exceeded
500Internal Server Error
503Service Unavailable

Rate Limits

Endpoint CategoryLimit
Authentication5 requests/minute
License Operations100 requests/minute
Heartbeat20 requests/minute
License Validation60 requests/minute (per IP)

Session Lifecycle

1. ACQUIRE → POST /api/v1/licenses/acquire/
└── Get session_id and start using the service

2. HEARTBEAT → PATCH /api/v1/licenses/sessions/{id}/heartbeat/
└── Send every 3-5 minutes to keep session alive
└── Session expires after 6 minutes without heartbeat

3. RELEASE → DELETE /api/v1/licenses/sessions/{id}/
└── Release seat when done to free up for other users

Generated from: openapi-schema-generated.yaml Schema Version: OpenAPI 3.0.3