Skip to content

The User Profile Management endpoints cover account identity, beta-gate free-tier setup, audit activity, and the per-user encrypted vault. Use these endpoints to inspect or update profiles, audit recent API calls, manage free-tier provisioning during the beta, or store arbitrary key-value secrets scoped to a realm.

Retrieve a user profile by ID. Admins can view any user; regular users can only view their own profile. This endpoint works even for banned users (read-only access).

NameInTypeRequiredDescription
idpathstringYesUser ID to retrieve
{
"statusCode": 200,
"message": "User retrieved successfully",
"data": {
"id": "507f1f77bcf86cd799439011",
"username": "john_doe",
"alias": "John Doe",
"email": "john.doe@example.com",
"is_admin": false,
"is_banned": false,
"metadata": {},
"created_at": "2024-12-01T10:00:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
}
}
const user = await client.api.users.get({ id: "507f1f77bcf86cd799439011" });

Update a user profile. Regular users can update their own alias and password (with current_password verification). Admins can update any user and set is_admin/is_banned flags.

NameInTypeRequiredDescription
idpathstringYesUser ID to update
FieldTypeRequiredDescription
aliasstringNoNew display name/alias (1–100 chars).
public_keystringNoED25519 public key (exactly 64 hexadecimal characters). Used for cryptographic identity and verification.
metadataobjectNoCustom metadata object for storing additional user information. Can include nested objects.
passwordstringNoNew password. Must be at least 12 characters, 3 of 4 character classes. Requires current_password for verification.
current_passwordstringNoCurrent password. Required when setting a new password for verification (8–128 chars).
is_adminbooleanNoAdmin status (admin-only field). Grants full system access.
is_bannedbooleanNoBan status (admin-only field). Admin users cannot be banned.
{
"statusCode": 200,
"message": "User updated successfully",
"data": {
"id": "507f1f77bcf86cd799439011",
"username": "john_doe",
"alias": "John Smith",
"email": "john.doe@example.com",
"public_key": "a1b2c3d4e5f6789012345678901234567890abcdefabcdefabcdefabcdef1234",
"is_admin": false,
"is_banned": false,
"metadata": {},
"created_at": "2024-12-01T10:00:00.000Z",
"updated_at": "2025-01-15T14:45:00.000Z"
}
}
const updated = await client.api.users.update({
id: "507f1f77bcf86cd799439011",
data: { alias: "John Smith" }
});

Return the account’s free-tier / beta-gate status, including whether the gate is enabled, whether this account is unlocked, whether it already owns a free server, and (advisory, point-in-time) why a claim is currently blocked. This endpoint never attempts a claim.

This endpoint takes no parameters.

{
"statusCode": 200,
"message": "Free-tier status retrieved",
"data": {
"gate_enabled": true,
"unlocked": false,
"has_free_server": false,
"can_claim": false,
"claim_blocked_reason": "invite_required"
}
}
const status = await client.api.users.getFreeTierStatus();

Redeem a single-use invite code to unlock free-tier server claiming during the beta, then immediately provision a free server. Idempotent if already unlocked. No-op (no code consumed) when the beta gate is disabled.

This endpoint takes no parameters.

FieldTypeRequiredDescription
codestringYesThe invite code (case/format-insensitive). 1–64 characters.
{
"statusCode": 200,
"message": "Invite code redeemed. Your free server is being prepared.",
"data": {
"unlocked": true,
"required": true,
"claim_blocked_reason": "none",
"server": { "id": "507f1f77bcf86cd799439099" },
"project": { "id": "507f1f77bcf86cd799439098" },
"container": null
}
}
const result = await client.api.users.redeemInviteCode({
data: { code: "HOODY-7Q4K-9F2M-3B8T-XR5W-2HKD-1" }
});

Manually claim a free-tier server and create the default project and container. Idempotent — safe to call if already provisioned.

This endpoint takes no parameters.

FieldTypeRequiredDescription
regionstringNoOptional preferred region override. Lowercase letters, digits, and hyphens; max 50 chars.
{
"statusCode": 200,
"data": {
"server": { "id": "507f1f77bcf86cd799439099" },
"project": { "id": "507f1f77bcf86cd799439098" },
"container": null
}
}
const result = await client.api.users.retrySetup({
data: { region: "us-east-1" }
});

Retrieve activity logs for the authenticated user with optional filtering by date range, HTTP method, status code, or realm.

NameInTypeRequiredDescription
pagequeryintegerNoPage number. Default: 1.
limitqueryintegerNoResults per page. Default: 50.
start_datequerystringNoFilter logs after this date.
end_datequerystringNoFilter logs before this date.
errors_onlyquerystringNoShow only errors (status ≥ 400). Literal values: true, false.
min_statusqueryintegerNoMinimum status code.
max_statusqueryintegerNoMaximum status code.
methodquerystringNoFilter by HTTP method. Literal values: GET, POST, PUT, PATCH, DELETE.
realm_idquerystringNoFilter by realm ID.
{
"statusCode": 200,
"message": "Activity logs retrieved successfully",
"data": [
{
"id": "1a9c3592695c087a8f35ceae",
"user_id": "507f1f77bcf86cd799439011",
"realm_id": "507f1f77bcf86cd799439011",
"method": "GET",
"path": "/api/v1/projects",
"status_code": 200,
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"created_at": "2025-11-18T20:00:00Z"
}
],
"metadata": {
"total": 100,
"page": 1,
"limit": 50,
"pages": 2
}
}
const logs = await client.api.activity.listIterator({
page: 1,
limit: 50,
errors_only: "true"
});

Retrieve storage usage statistics for activity logs, including total size, record count, oldest/newest record timestamps, and retention period.

This endpoint takes no parameters.

{
"statusCode": 200,
"message": "Activity stats retrieved successfully",
"data": {
"total_size_bytes": 1048576,
"total_records": 5000,
"oldest_record": "2025-10-18T20:00:00Z",
"newest_record": "2025-11-18T20:00:00Z",
"retention_days": 30
}
}
const stats = await client.api.activity.getStats();

The user vault stores arbitrary key-value pairs scoped to a realm. Total size limits are enforced globally across all realms, while key listings and per-realm counts are scoped to the current realm.

List all keys in your encrypted vault with metadata (key names, sizes, timestamps). Values are not included — use GET /vault/keys/:key to retrieve individual values.

NameInTypeRequiredDescription
realm_idquerystringNoTarget a specific realm (24-char hex). When omitted and not on a realm subdomain, defaults to global scope (realm_id = ""). Case-insensitive — uppercase is normalized to lowercase.
{
"statusCode": 200,
"message": "Vault keys retrieved successfully",
"data": [
{
"key": "my-encrypted-notes",
"realm_id": "507f1f77bcf86cd799439011",
"metadata": {},
"size_bytes": 2048,
"created_at": "2025-11-14T18:00:00.000Z",
"updated_at": "2025-11-14T18:15:00.000Z"
}
]
}
const keys = await client.api.vault.listIterator({
realm_id: "507f1f77bcf86cd799439011"
});

Retrieve a specific key-value pair from your encrypted vault by key name.

NameInTypeRequiredDescription
realm_idquerystringNoTarget a specific realm (24-char hex). When omitted and not on a realm subdomain, defaults to global scope (realm_id = ""). Case-insensitive — uppercase is normalized to lowercase.
keypathstringYesVault key name (alphanumeric, dots, underscores, hyphens).
{
"statusCode": 200,
"message": "Vault key retrieved successfully",
"data": {
"key": "my-encrypted-notes",
"realm_id": "507f1f77bcf86cd799439011",
"value": "{\"notes\": \"My important notes\", \"encrypted\": true}",
"metadata": {},
"size_bytes": 53,
"created_at": "2025-11-14T18:00:00.000Z",
"updated_at": "2025-11-14T18:15:00.000Z"
}
}
const entry = await client.api.vault.get({
key: "my-encrypted-notes",
realm_id: "507f1f77bcf86cd799439011"
});

Create or update a key-value pair in your personal encrypted vault. Values can be any UTF-8 string (JSON, encrypted data, plain text).

NameInTypeRequiredDescription
realm_idquerystringNoTarget a specific realm (24-char hex). When omitted and not on a realm subdomain, defaults to global scope (realm_id = ""). Case-insensitive — uppercase is normalized to lowercase.
keypathstringYesVault key name (alphanumeric, dots, underscores, hyphens).
FieldTypeRequiredDescription
valuestringYesValue to store. Any UTF-8 string (JSON, encrypted data, plain text). Counts toward vault storage limit.
metadataobjectNoOptional JSON metadata (max 256KB). Useful for content-type, filename, upload date, etc. Counts toward vault storage limit.
{
"statusCode": 200,
"message": "Vault key updated successfully",
"data": {
"key": "my-encrypted-notes",
"realm_id": "507f1f77bcf86cd799439011",
"value": "{\"notes\": \"My important notes\", \"encrypted\": true}",
"metadata": {},
"size_bytes": 53,
"created_at": "2025-11-14T18:00:00.000Z",
"updated_at": "2025-11-14T18:15:00.000Z"
}
}
await client.api.vault.set({
key: "api-keys",
realm_id: "507f1f77bcf86cd799439011",
data: { value: "{\"key\": \"secret\"}" }
});

Permanently delete a key-value pair from your encrypted vault. This action cannot be undone.

NameInTypeRequiredDescription
realm_idquerystringNoTarget a specific realm (24-char hex). When omitted and not on a realm subdomain, defaults to global scope (realm_id = ""). Case-insensitive — uppercase is normalized to lowercase.
keypathstringYesVault key name (alphanumeric, dots, underscores, hyphens).
{
"statusCode": 200,
"message": "Vault key deleted successfully"
}
await client.api.vault.delete({
key: "api-keys",
realm_id: "507f1f77bcf86cd799439011"
});

Retrieve statistics about your vault usage. total_keys and total_size_bytes are scoped to the current realm. limit_mb, remaining_mb, and used_percentage reflect global vault usage across all realms.

NameInTypeRequiredDescription
realm_idquerystringNoTarget a specific realm (24-char hex). When omitted and not on a realm subdomain, defaults to global scope (realm_id = ""). Case-insensitive — uppercase is normalized to lowercase.
{
"statusCode": 200,
"message": "Vault statistics retrieved successfully",
"data": {
"total_keys": 5,
"total_size_bytes": 10240,
"total_size_mb": 0.009766,
"limit_mb": 50,
"used_percentage": 0.02,
"remaining_mb": 49.990234
}
}
const stats = await client.api.vault.getStats({
realm_id: "507f1f77bcf86cd799439011"
});

Permanently delete ALL keys and values from your encrypted vault. This action cannot be undone.

NameInTypeRequiredDescription
realm_idquerystringNoTarget a specific realm (24-char hex). When omitted and not on a realm subdomain, defaults to global scope (realm_id = ""). Case-insensitive — uppercase is normalized to lowercase.
{
"statusCode": 200,
"message": "Vault cleared successfully",
"data": {
"deleted_count": 5
}
}
await client.api.vault.clear({
realm_id: "507f1f77bcf86cd799439011"
});