# API v1

All API paths use `/api/v1`. Send JSON with UTF-8 over HTTPS. Client calls include `X-Client-Version`, `X-Core-Version`, `X-Platform`, and `X-Architecture` when available; activation stores bounded client and OS version strings. Never send hardware serials, process lists, sensor values, access codes in telemetry, or credentials in query strings.

## Client endpoints

| Method | Path | Authorization | Purpose |
|---|---|---|---|
| POST | `/auth/activate` | none; activation rate limit | Atomically consume a one-time code and create a device session |
| POST | `/auth/refresh` | refresh token in JSON body | Rotate access and refresh credentials |
| POST | `/auth/revoke` | Bearer access token | Revoke this session |
| GET | `/core/versions?channel=stable` | none | List signed, published Core releases |
| POST | `/core/versions/{id}/download` | none; rate limited | Create a short-lived installer ticket |
| GET | `/catalog/plugins` | none | Public stable plugin metadata only |
| GET | `/plugins` | Bearer access token | List packages available to this product/channel |
| POST | `/plugins/{pluginId}/download` | Bearer access token | Authorize a private plugin download |
| GET | `/downloads/{ticket}` | one-time opaque ticket | Consume once and stream the artifact |

Activation request:

```json
{
  "code": "ABCDE-FG234-HJKLM-NP567-QRSTU",
  "deviceId": "4f3db80e-3297-4c25-9e02-685b65b2c497",
  "clientVersion": "1.0.0",
  "osVersion": "Windows 11",
  "apiVersion": "v1",
  "platform": "windows",
  "architecture": "x64"
}
```

Successful activation returns `accessToken`, `refreshToken`, `accessExpiresAt`, `refreshExpiresAt`, and `deviceId`. Invalid, expired, used, disabled and revoked codes return the same unauthorized response. Refresh tokens are single-use because refresh rotates the stored HMAC in the same conditional update.

Download authorization returns a relative `downloadUrl`, expiration time, filename, SHA-256, signature and signing key id. Treat the ticket as a bearer credential. The ticket is short-lived and consumed once. The SDK verifies both digest and publisher signature before saving to the final path.

## Admin endpoints

Admin operations are separate from Core bearer auth. `POST /admin/api/login` requires username, strong password and TOTP. The server sets an eight-hour Secure, HttpOnly, SameSite=Strict cookie and returns a CSRF token. State-changing calls must include the matching `X-CSRF-Token` and same-origin `Origin` header.

| Method | Path | Permission |
|---|---|---|
| POST | `/admin/api/login`, `/logout` | admin login / active admin session |
| POST | `/admin/api/access-codes` | `codes.generate` |
| GET | `/admin/api/access-codes`, `/access-codes/{id}` | `codes.read` |
| POST | `/admin/api/access-codes/{id}/disable`, `/revoke` | `codes.revoke` |
| GET | `/admin/api/devices` | `devices.read` |
| POST | `/admin/api/devices/{id}/revoke` | `devices.revoke` |
| GET | `/admin/api/sessions` | `sessions.read` |
| POST | `/admin/api/sessions/{id}/revoke` | `sessions.revoke` |
| POST | `/admin/api/plugins/upload`, `/plugins/{slug}/unpublish` | `plugins.publish` |
| POST | `/admin/api/core/upload`, `/core/versions/{id}/unpublish` | `core.publish` |
| GET | `/admin/api/audit` | `audit.read` |

Code generation accepts a count from 1 to 500, one expiration option, product id, channel and bounded metadata. Plain codes are returned only in that response; later searches never reveal them. Artifact uploads are multipart form data and require a valid publisher signature.

## Plugin publishing

Send multipart fields `id`, `name`, `version`, `apiVersion`, `author`, `description`, `category`, `minCoreVersion`, `channel`, `productId`, `visibility` (`private` or `public`), `permissions` (JSON string array), `dependencies` (JSON array of `{ "id": "other-plugin", "versionRequirement": ">=1.0.0" }`), `resourceEstimate` (JSON object), `signingKeyId`, `signature`, plus the package file as `package`. Supported packages are `.zip` and `.kretplugin`, maximum 1 GiB. Known permissions are `read.sensors`, `hardware.access`, `network.client`, `notifications`, and `settings.read`.

Core uploads use `version`, `buildNumber`, `releaseDate` (RFC 3339), `minWindowsVersion`, `channel`, `changelog`, `signingKeyId`, `signature`, and installer file `package` (`.exe`, `.msi` or `.msix`). Release uploads publish immediately after signature verification.

## Errors and throttles

- `400` malformed request/metadata, `401` invalid client/admin authentication, `403` insufficient administrator permission, `404` unknown or unavailable artifact/ticket, `429` rate limited.
- Activation: 8 requests per IP per minute; refresh: 20 per IP per minute; admin login: 5 per IP per five minutes; general API: 120 per IP per minute. Adjust limits behind trusted proxy infrastructure and add distributed rate limiting before multi-region scale.
- Error responses never echo codes, tokens or hashes. Audit events contain action and bounded metadata, never plaintext credentials.
