Licenses API
Manage floating concurrent licenses for CODITECT.
Overview
CODITECT uses a floating concurrent license model:
- Licenses allow a maximum number of simultaneous users
- Users acquire a "seat" when starting CODITECT
- Seats are released when the user exits or after inactivity
Endpoints
List Licenses
GET /v1/licenses
Get all licenses for your organization.
curl https://api.coditect.ai/v1/licenses \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"data": [
{
"id": "lic_abc123",
"key": "CODI-XXXX-XXXX-XXXX",
"product": "coditect-pro",
"max_seats": 10,
"active_seats": 3,
"status": "active",
"expires_at": "2027-01-09T00:00:00Z",
"created_at": "2026-01-09T00:00:00Z"
}
]
}
Get License
GET /v1/licenses/{license_id}
Get details for a specific license.
curl https://api.coditect.ai/v1/licenses/lic_abc123 \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"data": {
"id": "lic_abc123",
"key": "CODI-XXXX-XXXX-XXXX",
"product": "coditect-pro",
"max_seats": 10,
"active_seats": 3,
"available_seats": 7,
"status": "active",
"expires_at": "2027-01-09T00:00:00Z",
"features": {
"ai_assistance": true,
"cloud_workstations": true,
"team_collaboration": true,
"priority_support": true
},
"sessions": [
{
"id": "sess_xyz789",
"user_id": "usr_abc123",
"hardware_id": "hw_def456",
"started_at": "2026-01-09T10:00:00Z",
"last_heartbeat": "2026-01-09T10:25:00Z"
}
]
}
}
Acquire License Seat
POST /v1/licenses/acquire
Acquire a seat to start using CODITECT.
curl -X POST https://api.coditect.ai/v1/licenses/acquire \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"license_key": "CODI-XXXX-XXXX-XXXX",
"hardware_id": "hw_def456"
}'
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
license_key | string | Yes | License key |
hardware_id | string | Yes | Unique hardware identifier |
metadata | object | No | Additional session metadata |
Response:
{
"data": {
"session_id": "sess_xyz789",
"license_token": "eyJhbGciOiJSUzI1NiIs...",
"expires_at": "2026-01-09T11:00:00Z",
"heartbeat_interval": 300,
"features": {
"ai_assistance": true,
"cloud_workstations": true
}
}
}
Send Heartbeat
POST /v1/licenses/heartbeat
Keep your session alive. Must be called within the heartbeat interval.
curl -X POST https://api.coditect.ai/v1/licenses/heartbeat \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"session_id": "sess_xyz789"
}'
Response:
{
"data": {
"session_id": "sess_xyz789",
"status": "active",
"next_heartbeat_due": "2026-01-09T10:35:00Z"
}
}
Release License Seat
POST /v1/licenses/release
Release your seat when done using CODITECT.
curl -X POST https://api.coditect.ai/v1/licenses/release \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"session_id": "sess_xyz789"
}'
Response:
{
"data": {
"session_id": "sess_xyz789",
"status": "released",
"released_at": "2026-01-09T10:30:00Z"
}
}
License Validation
Licenses can be validated locally using the signed token:
import jwt
from cryptography.hazmat.primitives import serialization
# CODITECT public key (retrieve from /v1/licenses/public-key)
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----"""
def validate_license_token(token: str) -> dict:
"""Validate license token offline."""
return jwt.decode(
token,
public_key,
algorithms=["RS256"],
audience="coditect-client"
)
Error Responses
No Seats Available
{
"error": {
"code": "no_seats_available",
"message": "All seats are currently in use (10/10)",
"details": {
"max_seats": 10,
"active_seats": 10
}
}
}
License Expired
{
"error": {
"code": "license_expired",
"message": "This license expired on 2026-01-01",
"details": {
"expired_at": "2026-01-01T00:00:00Z"
}
}
}
Invalid Hardware ID
{
"error": {
"code": "invalid_hardware_id",
"message": "The hardware ID format is invalid",
"details": {
"expected_format": "hw_[a-z0-9]{32}"
}
}
}
Session Timeout
{
"error": {
"code": "session_timeout",
"message": "Session expired due to missed heartbeat",
"details": {
"last_heartbeat": "2026-01-09T10:00:00Z",
"timeout_at": "2026-01-09T10:06:00Z"
}
}
}
SDK Examples
Python
from coditect import Client
client = Client(api_key="cdt_live_abc123...")
# Acquire a seat
session = client.licenses.acquire(
license_key="CODI-XXXX-XXXX-XXXX",
hardware_id=client.get_hardware_id()
)
# Start heartbeat in background
client.licenses.start_heartbeat(session.session_id)
# ... use CODITECT ...
# Release when done
client.licenses.release(session.session_id)
JavaScript
import { CoditectClient } from '@coditect/sdk';
const client = new CoditectClient({
apiKey: 'cdt_live_abc123...'
});
// Acquire seat
const session = await client.licenses.acquire({
licenseKey: 'CODI-XXXX-XXXX-XXXX',
hardwareId: await client.getHardwareId()
});
// Heartbeat is automatic with SDK
// ...use CODITECT...
// Release on exit
await client.licenses.release(session.sessionId);
Webhooks
Subscribe to license events:
| Event | Description |
|---|---|
license.seat.acquired | Seat was acquired |
license.seat.released | Seat was released |
license.seat.timeout | Seat timed out |
license.seats.exhausted | All seats in use |
license.expiring | License expiring soon |
license.expired | License has expired |
See Webhooks for setup instructions.