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
- Health Endpoints
- Auth Endpoints
- Subscription Endpoints
- License Endpoints
- License Seat Management
- Error Handling
- Rate Limits
Authentication
This API uses JWT (JSON Web Token) authentication via Firebase.
Authentication Header
Authorization: Bearer <your-jwt-token>
Token Lifetime
| Token Type | Expiration |
|---|---|
| Access Token | 15 minutes |
| Refresh Token | 7 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 error409- 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Verification 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.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
License Endpoints
List Licenses
List all licenses for the authenticated user's organization.
Endpoint: GET /api/v1/licenses/
Authentication: Required
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
is_active | boolean | Filter by active status |
tier | string | Filter 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
| Code | Description |
|---|---|
200 | Success |
201 | Created |
400 | Bad Request - Invalid input |
401 | Unauthorized - Invalid or missing token |
403 | Forbidden - Insufficient permissions |
404 | Not Found - Resource doesn't exist |
409 | Conflict - Resource already exists |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error |
503 | Service Unavailable |
Rate Limits
| Endpoint Category | Limit |
|---|---|
| Authentication | 5 requests/minute |
| License Operations | 100 requests/minute |
| Heartbeat | 20 requests/minute |
| License Validation | 60 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