REST API Reference¶
Complete reference for the PyLocket REST API. All endpoints are prefixed with /v1/.
Base URL: https://api.pylocket.com/v1/
Authentication¶
All authenticated endpoints require a Bearer token in the Authorization header:
Obtain tokens via the login endpoint or use an API key.
Auth Endpoints¶
POST /v1/auth/register¶
Register a new developer account.
Request Body:
Response (201):
{
"id": "dev_abc123",
"email": "dev@example.com",
"company_name": "My Company",
"created_at": "2026-03-01T00:00:00Z"
}
POST /v1/auth/login¶
Authenticate and receive JWT tokens.
Request Body:
Response (200) — without 2FA:
{
"access_token": "eyJhbGc...",
"refresh_token": "eyJhbGc...",
"token_type": "bearer",
"expires_in": 3600
}
Response (200) — with 2FA:
POST /v1/auth/login/verify-2fa¶
Complete login with a TOTP code.
Request Body:
Response (200):
{
"access_token": "eyJhbGc...",
"refresh_token": "eyJhbGc...",
"token_type": "bearer",
"expires_in": 3600
}
POST /v1/auth/refresh¶
Refresh an expired access token.
Request Body:
Response (200):
GET /v1/auth/me¶
Get the authenticated developer's profile.
Response (200):
{
"id": "dev_abc123",
"email": "dev@example.com",
"company_name": "My Company",
"two_factor_enabled": true,
"created_at": "2026-03-01T00:00:00Z"
}
POST /v1/auth/api-keys/rotate¶
Generate a new API key. Invalidates the previous key.
Response (200):
POST /v1/auth/2fa/setup¶
Start 2FA setup. Returns a provisioning URI for authenticator apps.
Response (200):
{
"provisioning_uri": "otpauth://totp/PyLocket:dev@example.com?secret=...",
"backup_codes": ["abc123", "def456", "ghi789", "jkl012"]
}
POST /v1/auth/2fa/confirm¶
Confirm 2FA setup with a TOTP code.
Request Body:
Response (200):
POST /v1/auth/2fa/disable¶
Disable 2FA.
Request Body:
GET /v1/auth/2fa/status¶
Check 2FA status.
Response (200):
App Endpoints¶
GET /v1/apps¶
List all apps for the authenticated developer.
Response (200):
[
{
"id": "app_abc123",
"name": "MyApp",
"platforms": ["win-x64", "linux-x64"],
"protection_level": "maximum",
"created_at": "2026-03-01T00:00:00Z"
}
]
POST /v1/apps¶
Create a new application.
Request Body:
Response (201):
{
"id": "app_abc123",
"name": "MyApp",
"platforms": ["win-x64", "linux-x64", "mac-arm64"],
"protection_level": "maximum",
"created_at": "2026-03-01T00:00:00Z"
}
GET /v1/apps/{app_id}¶
Get details for a specific app.
PUT /v1/apps/{app_id}¶
Update an application.
Request Body:
DELETE /v1/apps/{app_id}¶
Delete an application and all associated builds and licenses.
Warning: This action is irreversible.
Build Endpoints¶
POST /v1/apps/{app_id}/builds¶
Create a new protection build by uploading an artifact.
Request: multipart/form-data
| Field | Type | Description |
|---|---|---|
artifact |
File | The artifact to protect |
platform |
String | Target platform |
python_version |
String | Python version |
Response (201):
{
"id": "build_abc789",
"app_id": "app_abc123",
"status": "QUEUED",
"platform": "win-x64",
"python_version": "3.12",
"protection_level": "maximum",
"created_at": "2026-03-01T00:00:00Z"
}
GET /v1/apps/{app_id}/builds¶
List all builds for an app.
Query Parameters:
| Parameter | Description |
|---|---|
status |
Filter by status |
limit |
Max results (default: 20) |
offset |
Pagination offset |
GET /v1/apps/{app_id}/builds/{build_id}¶
Get build details including status.
Response (200):
{
"id": "build_abc789",
"app_id": "app_abc123",
"status": "READY",
"platform": "win-x64",
"python_version": "3.12",
"protection_level": "maximum",
"scan_status": "CLEAN",
"artifact_size_bytes": 2457600,
"protected_size_bytes": 3145728,
"created_at": "2026-03-01T00:00:00Z",
"completed_at": "2026-03-01T00:02:30Z"
}
GET /v1/apps/{app_id}/builds/{build_id}/download¶
Get a signed download URL for the protected artifact.
Response (200):
The download URL is valid for 7 days.
License Endpoints¶
POST /v1/licenses/activate¶
Activate an end-user license. Called by the protected application at runtime. Request and response details are handled automatically by the PyLocket runtime.
Error Responses:
| Status | Meaning |
|---|---|
401 |
Invalid or revoked license key |
403 |
Device limit exceeded |
429 |
Velocity limit exceeded (too many activations) |
POST /v1/licenses/refresh¶
Refresh a runtime token. Called periodically by the protected application. Request and response details are handled automatically by the PyLocket runtime.
GET /v1/licenses¶
List licenses for the authenticated developer.
Query Parameters:
| Parameter | Description |
|---|---|
app_id |
Filter by app |
status |
Filter by status: active, revoked, expired, demo |
limit |
Max results (default: 20) |
offset |
Pagination offset |
POST /v1/licenses/{license_id}/revoke¶
Revoke a license immediately.
Public Endpoints¶
GET /v1/public/pricing¶
Get public pricing information. No authentication required.
Response (200):
{
"base_fee_annual_usd": 9.00,
"license_fee_usd": 4.00,
"free_download_limit": 10,
"storage_fee_per_gb_month_usd": 0.03
}
Error Response Format¶
All errors follow a consistent format:
{
"detail": "Human-readable error message",
"error_code": "INVALID_LICENSE_KEY",
"status_code": 401
}
Rate Limiting¶
All API endpoints are rate-limited. Rate limits vary by endpoint group (authentication, app management, build operations, license activation, and general API access).
Rate limit headers are included in all responses:
When the rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header.
Pagination¶
List endpoints support pagination:
| Parameter | Description | Default |
|---|---|---|
limit |
Max items per page | 20 |
offset |
Number of items to skip | 0 |
Response includes pagination metadata: