Server-only admin client for the Hiyve Cloud API. Manages user profiles, organizations, and API keys.
Warning: This package is for server-side (Node.js) use only. Secret keys must never be exposed to the browser. Three layers of enforcement prevent accidental client-side usage.
npm install @hiyve/admin
import { AdminClient } from '@hiyve/admin';
const admin = new AdminClient({
secretKey: process.env.HIYVE_SECRET_KEY,
environment: 'production',
});
// List profiles
const result = await admin.listProfiles('org_abc123', { limit: 20 });
// Get a single profile
const profile = await admin.getProfile('profile_123', 'org_abc123');
// Update a profile
const updated = await admin.updateProfile('profile_123', 'org_abc123', {
name: 'John Smith',
organization: 'Acme Corp',
});
// Deactivate a profile
await admin.deactivateProfile('profile_123', 'org_abc123');
new AdminClient(config: AdminConfig)
| Option | Type | Default | Description |
|---|---|---|---|
secretKey |
string |
— | Secret API key (from your Hiyve dashboard) — required |
environment |
'production' | 'development' |
'production' |
Target environment |
baseUrl |
string |
— | Custom API URL (overrides environment) |
timeout |
number |
30000 |
Request timeout in milliseconds |
listProfiles(brandOrgId?, options?)List user profiles for an organization. Returns a paginated response.
const result = await admin.listProfiles('org_abc123', {
page: 1,
limit: 20,
search: 'john',
metadata: { role: 'admin' },
});
console.log(result.data); // UserProfile[]
console.log(result.total); // total matching profiles
console.log(result.pages); // total pages
| Parameter | Type | Description |
|---|---|---|
brandOrgId |
string? |
Organization ID. If omitted, defaults to the org associated with the API key |
options.page |
number |
Page number (default: 1) |
options.limit |
number |
Items per page (default: 20, max: 100) |
options.search |
string |
Search by name or email |
options.metadata |
Record<string, unknown> |
Filter by metadata fields (e.g. { role: 'admin' }) |
Returns: Promise<PaginatedResponse<UserProfile>>
getProfile(profileId, brandOrgId)Get a single user profile by ID.
const profile = await admin.getProfile('profile_123', 'org_abc123');
console.log(profile.name, profile.email);
Returns: Promise<UserProfile>
updateProfile(profileId, brandOrgId, updates)Update a user profile's fields.
const updated = await admin.updateProfile('profile_123', 'org_abc123', {
name: 'John Smith',
organization: 'Acme Corp',
metadata: { department: 'Engineering' },
});
| Field | Type | Description |
|---|---|---|
name |
string |
Display name |
picture |
string |
Profile picture URL |
phone |
string |
Phone number |
organization |
string |
Organization name |
metadata |
Record<string, unknown> |
Custom key-value data |
Roles cannot be changed via
updateProfile. Anyrolesfield passed in is silently stripped from the request body to prevent accidental privilege escalation (e.g. forwarding an untrusted client request body). UseaddRole/removeRoleinstead.
Returns: Promise<UserProfile>
addRole(profileId, role, brandOrgId?)Add a role to a user profile. Idempotent — if the role is already present, the profile is returned unchanged.
const updated = await admin.addRole('profile_123', 'public-files', 'org_abc123');
console.log(updated.roles); // ['private-files', 'public-files']
| Parameter | Type | Description |
|---|---|---|
profileId |
string |
Profile ID |
role |
string |
Role string to add (e.g. 'public-files') |
brandOrgId |
string? |
Organization ID. If omitted, defaults to the org associated with the API key |
Returns: Promise<UserProfile>
removeRole(profileId, role, brandOrgId?)Remove a role from a user profile. Idempotent — if the role is not present, the profile is returned unchanged. Other roles are preserved.
const updated = await admin.removeRole('profile_123', 'public-files', 'org_abc123');
| Parameter | Type | Description |
|---|---|---|
profileId |
string |
Profile ID |
role |
string |
Role string to remove |
brandOrgId |
string? |
Organization ID. If omitted, defaults to the org associated with the API key |
Returns: Promise<UserProfile>
Concurrency note.
addRole/removeRoleare implemented as read-modify-write and are not atomic. Concurrent calls on the same profile can race — serialize role mutations per profile in your own code.
deactivateProfile(profileId, brandOrgId)Deactivate (soft-delete) a user profile. The profile is not permanently deleted.
const result = await admin.deactivateProfile('profile_123', 'org_abc123');
console.log(result.message); // 'Profile deactivated'
Returns: Promise<{ message: string; profile: UserProfile }>
listAllowedOrigins(orgId)List the CORS allowed origins for an organization.
const result = await admin.listAllowedOrigins('org_abc123');
console.log(result.origins); // ['https://myapp.com', 'https://staging.myapp.com']
Returns: Promise<AllowedOriginsResponse>
setAllowedOrigins(orgId, origins)Replace all allowed origins for an organization.
await admin.setAllowedOrigins('org_abc123', [
'https://myapp.com',
'https://staging.myapp.com',
]);
Returns: Promise<AllowedOriginsResponse>
addAllowedOrigins(orgId, origins)Add origin(s) to the allowed list without removing existing ones.
await admin.addAllowedOrigins('org_abc123', ['https://new-app.com']);
Returns: Promise<AllowedOriginsResponse>
removeAllowedOrigins(orgId, origins)Remove specific origin(s) from the allowed list.
await admin.removeAllowedOrigins('org_abc123', ['https://old-app.com']);
Returns: Promise<AllowedOriginsResponse>
UserProfile| Field | Type | Description |
|---|---|---|
id |
string |
Profile ID |
name |
string |
Display name |
email |
string |
Email address |
picture |
string? |
Profile picture URL |
phone |
string? |
Phone number |
organization |
string? |
Organization name |
metadata |
Record<string, unknown>? |
Custom key-value data |
roles |
string[]? |
Assigned roles |
active |
boolean |
Whether the profile is active |
brandOrgId |
string |
Organization ID |
onboardingCompleted |
boolean? |
Onboarding status |
created |
string? |
Creation timestamp (legacy) |
createdAt |
string? |
Creation timestamp |
updatedAt |
string? |
Last update timestamp |
AllowedOriginsResponse| Field | Type | Description |
|---|---|---|
origins |
string[] |
Allowed origins for the organization |
HiyveAuthUserAuthenticated user attached to req.hiyveUser by createAuthMiddleware.
| Field | Type | Description |
|---|---|---|
id |
string |
User ID |
email |
string |
Email address |
name |
string? |
Display name |
emailVerified |
boolean? |
Whether the email is verified |
metadata |
Record<string, unknown>? |
Custom metadata |
createdAt |
string? |
Account creation timestamp |
| Type | Description |
|---|---|
PaginatedResponse<T> |
Paginated list response with data, total, page, limit, pages |
ListProfilesOptions |
Options for listProfiles() — page, limit, search, metadata |
UpdateProfileData |
Fields for updateProfile() — name, picture, phone, organization, metadata. (Roles are managed via addRole / removeRole.) |
AdminConfig |
Constructor config — secretKey, environment, baseUrl, timeout |
CloudEnvironment |
'production' | 'development' |
HiyveServerConfig |
Server middleware config |
HiyveRequestHandler |
Express-compatible request handler type |
HiyveHandlers |
Object containing all route handlers |
HiyveAuthMiddlewareOptions |
Options for createAuthMiddleware — optional, cacheTtlMs, cacheMaxSize |
| Constant | Value | Description |
|---|---|---|
DEFAULT_BASE_URL |
'https://api.hiyve.dev' |
Production API URL |
DEFAULT_TIMEOUT |
30000 |
Default request timeout (ms) |
ENVIRONMENT_URLS |
{ production, development } |
URL map for each environment |
Express-compatible route handlers for room tokens, cloud tokens, join tokens, AI note generation, health checks, and identity proxy. Mount all routes with a single call or use individual handlers.
import express from 'express';
import { mountHiyveRoutes, loadHiyveConfig } from '@hiyve/admin';
const app = express();
app.use(express.json());
const apiRouter = express.Router();
mountHiyveRoutes(apiRouter, loadHiyveConfig());
app.use('/api', apiRouter);
app.listen(3000);
This registers the following routes on the router:
POST /generate-room-token — Generate a room token for WebRTCPOST /generate-cloud-token — Generate a cloud token for AI servicesPOST /generate-note — Generate AI-powered meeting notesPOST /create-join-token — Generate a server-side join tokenGET /health — Health checkALL /hiyve/identity/* — Proxy to Hiyve Cloud identity endpointsloadHiyveConfig(env?): HiyveServerConfigLoad configuration from environment variables. Reads APIKEY, CLIENT_SECRET, SERVER_REGION, SERVER_REGION_URL, and ENVIRONMENT.
const config = loadHiyveConfig(); // reads from process.env
const config = loadHiyveConfig(customEnv); // or pass a custom env object
mountHiyveRoutes(router, config): routerMount all Hiyve routes on an Express-compatible router. Returns the router for chaining.
createHiyveHandlers(config): HiyveHandlersCreate individual handlers without mounting them. Use this when you need custom routing.
const handlers = createHiyveHandlers(loadHiyveConfig());
app.post('/api/room-token', handlers.roomToken);
app.post('/api/cloud-token', handlers.cloudToken);
app.post('/api/note', handlers.generateNote);
app.post('/api/join-token', handlers.joinToken);
app.get('/api/health', handlers.health);
app.all('/api/hiyve/identity/*', handlers.identityProxy);
| Factory | Description |
|---|---|
createRoomTokenHandler(config) |
Returns handler for room token generation |
createCloudTokenHandler(config) |
Returns handler for cloud token generation |
createNoteHandler(config) |
Returns handler for AI note generation |
createHealthHandler(config) |
Returns handler for health checks |
Note:
joinTokenandidentityProxyhandlers are available viacreateHiyveHandlers()ormountHiyveRoutes()but are not exported as individual factory functions.
HiyveServerConfig| Field | Type | Default | Description |
|---|---|---|---|
apiKey |
string |
— | API key for signaling server and cloud API |
clientSecret |
string |
— | Client secret for signaling server |
region |
string |
'us-west-2' |
Server region |
regionUrl |
string |
Resolved automatically | Region URL suffix |
environment |
string |
'development' |
'production' or 'development' |
cloudApiUrl |
string |
— | Override cloud API URL (auto-derived from environment) |
HiyveHandlers| Property | Route | Description |
|---|---|---|
roomToken |
POST |
Room token generation |
cloudToken |
POST |
Cloud token generation |
generateNote |
POST |
AI note generation |
joinToken |
POST |
Server-side join token creation |
health |
GET |
Health check |
identityProxy |
ALL |
Identity proxy to Hiyve Cloud |
Verify end-user access tokens against Hiyve Cloud. Attach this middleware to routes that require a logged-in user.
import express from 'express';
import { createAuthMiddleware, loadHiyveConfig } from '@hiyve/admin';
const app = express();
const config = loadHiyveConfig();
// Protect routes — verified user available as req.hiyveUser
app.get('/api/me', createAuthMiddleware(config), (req, res) => {
res.json({ user: req.hiyveUser });
});
// Optional auth — req.hiyveUser is null if no token provided
app.get('/api/public', createAuthMiddleware(config, { optional: true }), (req, res) => {
res.json({ user: req.hiyveUser });
});
createAuthMiddleware(config, options?)| Option | Type | Default | Description |
|---|---|---|---|
optional |
boolean |
false |
Allow requests without a token (req.hiyveUser is null) |
cacheTtlMs |
number |
300000 |
Token verification cache TTL (5 minutes) |
cacheMaxSize |
number |
1000 |
Maximum number of cached tokens |
The middleware extracts the Bearer token from the Authorization header, verifies it against Hiyve Cloud, and attaches the authenticated user to req.hiyveUser (see HiyveAuthUser type above).
This package is restricted to server-side (Node.js) environments. If used in a browser context, it will throw an error at both build time and runtime.
If you were previously importing AdminClient from @hiyve/cloud:
- import { AdminClient } from '@hiyve/cloud';
+ import { AdminClient } from '@hiyve/admin';
All types (UserProfile, AdminConfig, etc.) are also exported from @hiyve/admin.
Proprietary - Hiyve SDK
@hiyve/admin - Server-only admin client and middleware for Hiyve
This package provides:
This package must only be used in Node.js environments.
Example: Admin client
Example: Server middleware