Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
69ea8af
docs: add private spaces SDK design spec (ORB-1919)
JanKulhavy Jul 27, 2026
900ded3
docs: add private spaces implementation plan (ORB-1919)
JanKulhavy Jul 27, 2026
31a2291
feat(private-spaces): add PrivateSpaces endpoint with list() (ORB-1919)
JanKulhavy Jul 27, 2026
57a6917
feat(private-spaces): add get() with usage columns (ORB-1919)
JanKulhavy Jul 27, 2026
a075f6f
feat(private-spaces): add update() with confirmed option (ORB-1919)
JanKulhavy Jul 27, 2026
84d1572
feat(organizations): add privateSpaces column to Organization type (O…
JanKulhavy Jul 27, 2026
aea5e34
feat(private-spaces): export public types and document endpoint (ORB-…
JanKulhavy Jul 27, 2026
5f01c44
feat(private-spaces): add tool definitions (ORB-1919)
JanKulhavy Jul 27, 2026
45bc711
test(private-spaces): add integration tests (ORB-1919)
JanKulhavy Jul 27, 2026
bd8afd4
chore(private-spaces): formatting and verification follow-ups (ORB-1919)
JanKulhavy Jul 27, 2026
dd66ec8
test(private-spaces): skip restore when original limit was never obse…
JanKulhavy Jul 27, 2026
6fe92c5
docs(private-spaces): correct nullable schema note in spec (ORB-1919)
JanKulhavy Jul 27, 2026
598df55
fix(private-spaces): align transferLimit and consumedCenticredits typ…
JanKulhavy Jul 27, 2026
d67d809
feat: make JSONSchema type optional for enhanced flexibility
JanKulhavy Jul 27, 2026
b70f4f0
fix(private-spaces): resolve round-1 Copilot PR review comments
JanKulhavy Jul 27, 2026
e459b05
fix(private-spaces): checker findings — self-review round 1
JanKulhavy Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const make = new Make('your-api-key', 'eu2.make.com', {
- **Keys** - API keys and secrets
- **On-Prem Agents** - On-prem bridge agents running on customer infrastructure
- **Organizations** - Top-level account and billing management
- **Private Spaces** - Per-user private workspaces within an organization (list, get, update)
- **Scenarios** - Scenario management
- **Teams** - Team management and collaboration
- **Public Templates** - Public template discovery and blueprint export (read-only)
Expand Down Expand Up @@ -209,6 +210,7 @@ All tools are organized into the following categories:
- `keys`
- `on-prem-agent`
- `organizations`
- `private-spaces`
- `scenarios`
- `teams`
- `public-templates`
Expand Down
14 changes: 14 additions & 0 deletions src/endpoints/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ export type Organization = {
/** Webhook log retention period in days */
webhookLogRetentionDays?: number;
};
/**
* Private spaces the requesting user is a member of within this organization.
* Only returned when requested via `cols`; available on public cloud only.
*/
privateSpaces?: {
/** Unique identifier of the private space */
id: number;
/** Name of the private space */
name: string;
/** Whether the requesting user owns the space */
isOwner: boolean;
/** Whether org admins can see into the space (mirrors the organization's "add admins as observers" setting) */
hasAdminVisibility: boolean;
}[];
/** The name of the subscription for the organization */
serviceName: string;
/** Teams in the organization */
Expand Down
106 changes: 106 additions & 0 deletions src/endpoints/private-spaces.tools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import type { Make } from '../make.js';
import type { MakeTool } from '../tools.js';

export const tools: MakeTool[] = [
{
name: 'private-spaces_list',
title: 'List private spaces',
description:
"List the private spaces of an organization. Requires the organization's private-spaces feature to be enabled (error IM903 otherwise) and the 'personal team manage' permission. Private spaces cannot be created or deleted through the API — they are provisioned automatically by organization settings.",
category: 'private-spaces',
scope: 'private-spaces:read',
scopeId: 'organizationId',
identifier: 'organizationId',
annotations: {
readOnlyHint: true,
destructiveHint: false,
openWorldHint: false,
},
inputSchema: {
type: 'object',
properties: {
organizationId: { type: 'number', description: 'The organization ID to list private spaces for' },
externalId: { type: 'string', description: 'Filter private spaces by their external ID' },
},
required: ['organizationId'],
},
examples: [{ organizationId: 5 }, { organizationId: 5, externalId: 'ext-1' }],
execute: async (make: Make, args: { organizationId: number; externalId?: string }) => {
const { organizationId, ...options } = args;
return await make.privateSpaces.list(organizationId, { ...options, cols: ['*'] });
},
},
{
name: 'private-spaces_get',
title: 'Get private space',
description:
'Get details of a specific private space, including usage totals (operations, transfer, centicredits). Callers who are not members of the space receive a 404 even when the space exists.',
category: 'private-spaces',
scope: 'private-spaces:read',
scopeId: 'privateSpaceId',
identifier: 'privateSpaceId',
resourceId: 'privateSpaceId',
annotations: {
readOnlyHint: true,
destructiveHint: false,
openWorldHint: false,
},
inputSchema: {
type: 'object',
properties: {
privateSpaceId: { type: 'number', description: 'The private space ID to retrieve' },
},
required: ['privateSpaceId'],
},
examples: [{ privateSpaceId: 101 }],
execute: async (make: Make, args: { privateSpaceId: number }) => {
return await make.privateSpaces.get(args.privateSpaceId, { cols: ['*'] });
},
},
{
name: 'private-spaces_update',
title: 'Update private space',
description:
"Update a private space's operations limit. Set operationsLimit to null to remove the limit (unlimited); the transfer limit is derived automatically. When the new limit is below the space's current consumption the call fails with IM004 unless 'confirmed' is true — confirming pauses the space.",
category: 'private-spaces',
scope: 'private-spaces:write',
scopeId: 'privateSpaceId',
identifier: 'privateSpaceId',
resourceId: 'privateSpaceId',
annotations: {
readOnlyHint: false,
destructiveHint: true,
idempotentHint: true,
openWorldHint: false,
},
Comment thread
JanKulhavy marked this conversation as resolved.
inputSchema: {
type: 'object',
properties: {
privateSpaceId: { type: 'number', description: 'The private space ID to update' },
operationsLimit: {
oneOf: [{ type: 'number' }, { type: 'null' }],
description:
'Maximum operations limit (minimum 0). Pass null to remove the limit; omit to leave unchanged.',
},
confirmed: {
type: 'boolean',
description:
"Confirmation of the update. Required when the new limit is below the space's current consumption; confirming pauses the space.",
},
},
required: ['privateSpaceId'],
},
examples: [
{ privateSpaceId: 101, operationsLimit: 10000 },
{ privateSpaceId: 101, operationsLimit: 50, confirmed: true },
{ privateSpaceId: 101, operationsLimit: null },
],
execute: async (
make: Make,
args: { privateSpaceId: number; operationsLimit?: number | null; confirmed?: boolean },
) => {
const { privateSpaceId, confirmed, ...body } = args;
return await make.privateSpaces.update(privateSpaceId, body, { confirmed });
},
},
];
230 changes: 230 additions & 0 deletions src/endpoints/private-spaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
import type { FetchFunction, Pagination, PickColumns } from '../types.js';

/**
* Represents a private space in Make.
* A private space is a per-user personal workspace inside an organization where
* scenarios and related entities (including connections) stay visible only to the
* owner. Private spaces cannot be created or deleted through the API — they are
* provisioned automatically based on the organization's private-spaces settings.
*/
export type PrivateSpace = {
/** Unique identifier of the private space */
id: number;
/** Name of the private space */
name: string;
/** ID of the organization this private space belongs to */
organizationId: number;
/** Whether Make global AI agents are enabled for the space */
globalAgentsEnabled?: boolean;
/** Type of the underlying team; always `personal` for private spaces */
type?: 'personal';
/** Name of the space owner */
privateSpaceOwnerName?: string;
/** Email of the space owner */
privateSpaceOwnerEmail?: string;
/** User ID of the space owner */
privateSpaceOwnerId?: number;
/** Maximum operations limit; null means unlimited */
operationsLimit?: number | null;
/**
* Maximum data transfer limit in bytes; derived from the operations limit.
* Serialized as a string by `list()`/`get()` but as a number by `update()`.
*/
transferLimit?: string | number | null;
/** Number of operations consumed in the current period */
consumedOperations?: number | null;
/** Amount of data transfer consumed in the current period, in bytes */
consumedTransfer?: string | null;
/** Whether the space is paused due to exceeded limits */
isPaused?: boolean | null;
/** Number of centicredits consumed in the current period, serialized as a string */
consumedCenticredits?: string | null;
/** Total operations since the last reset; only selectable via `cols` on `get()` */
operations?: string;
/** Total data transfer since the last reset, in bytes; only selectable via `cols` on `get()` */
transfer?: string;
/** Total centicredits since the last reset; only selectable via `cols` on `get()` */
centicredits?: string;
/** Whether the space is deleted; returned by `update()` */
deleted?: boolean;
/** External identifier of the space; returned by `update()` */
externalId?: string | null;
};

/**
* Options for listing private spaces.
* @template C Keys of the PrivateSpace type to include in the response
*/
export type ListPrivateSpacesOptions<C extends keyof PrivateSpace = never> = {
/** Specific columns/fields to include in the response */
cols?: C[] | ['*'];
/** Pagination options (the API supports sorting by `name` only) */
pg?: Partial<Pagination<PrivateSpace>>;
/** Filter spaces by their external ID */
externalId?: string;
};

/**
* Options for retrieving a private space.
* @template C Keys of the PrivateSpace type to include in the response
*/
export type GetPrivateSpaceOptions<C extends keyof PrivateSpace = never> = {
/**
* Specific columns/fields to include in the response. In addition to the list
* columns, `get()` supports the usage totals `operations`, `transfer` and
* `centicredits` (computed from analytics storage; the API responds with 503
* when that storage is unavailable).
*/
cols?: C[] | ['*'];
};

/**
* Body for updating a private space.
*/
export type UpdatePrivateSpaceBody = {
/**
* Maximum operations limit (minimum 0). Set to `null` to remove the limit
* (unlimited); omit to leave unchanged. The transfer limit is derived from
* this value by the API.
*/
operationsLimit?: number | null;
};

/**
* Options for updating a private space.
*/
export type UpdatePrivateSpaceOptions = {
/**
* Confirmation of the update. Required (the API fails with IM004 otherwise)
* when the new operations limit is below the space's current consumption;
* confirming pauses the space.
*/
confirmed?: boolean;
};

/**
* Response format for listing private spaces.
*/
type ListPrivateSpacesResponse<C extends keyof PrivateSpace = never> = {
/** List of private spaces matching the query */
privateSpaces: PickColumns<PrivateSpace, C>[];
/** Pagination information */
pg: Pagination<PrivateSpace>;
};

/**
* Response format for getting a private space.
*/
type GetPrivateSpaceResponse<C extends keyof PrivateSpace = never> = {
/** The requested private space */
privateSpace: PickColumns<PrivateSpace, C>;
};

/**
* Response format for updating a private space.
*/
type UpdatePrivateSpaceResponse = {
/** The updated private space */
privateSpace: PrivateSpace;
};

/**
* Class providing methods for working with Make private spaces.
* Requires the organization's private-spaces feature to be enabled; the API
* responds with error IM903 when it is not.
*/
export class PrivateSpaces {
readonly #fetch: FetchFunction;

/**
* Create a new PrivateSpaces instance.
* @param fetch Function for making API requests
*/
constructor(fetch: FetchFunction) {
this.#fetch = fetch;
}

/**
* List private spaces of an organization.
* Requires the `personal team manage` organization permission.
* @param organizationId The organization ID to list private spaces for
* @param options Optional parameters for filtering and pagination
* @returns Promise with the list of private spaces
*
* @example
* ```typescript
* const spaces = await make.privateSpaces.list(123);
* ```
*/
async list<C extends keyof PrivateSpace = never>(
organizationId: number,
options?: ListPrivateSpacesOptions<C>,
): Promise<PickColumns<PrivateSpace, C>[]> {
return (
await this.#fetch<ListPrivateSpacesResponse<C>>('/private-spaces', {
query: {
organizationId,
externalId: options?.externalId,
cols: options?.cols,
pg: options?.pg,
},
})
).privateSpaces;
}

/**
* Get details of a specific private space.
* Requires the `personal team own view` organization permission; callers who are
* not members of the space receive a 404 even when the space exists.
* @param privateSpaceId The private space ID to get
* @param options Optional parameters for filtering returned fields
* @returns Promise with the private space information
*
* @example
* ```typescript
* const space = await make.privateSpaces.get(101);
* ```
*/
async get<C extends keyof PrivateSpace = never>(
privateSpaceId: number,
options?: GetPrivateSpaceOptions<C>,
): Promise<PickColumns<PrivateSpace, C>> {
return (
await this.#fetch<GetPrivateSpaceResponse<C>>(`/private-spaces/${privateSpaceId}`, {
query: {
cols: options?.cols,
},
})
).privateSpace;
}

/**
* Update a private space.
* Requires the `personal team manage` organization permission.
* @param privateSpaceId The private space ID to update
* @param body The fields to update
* @param options Optional update options
* @returns Promise with the updated private space
*
* @example
* ```typescript
* // Remove the operations limit
* const space = await make.privateSpaces.update(101, { operationsLimit: null });
* ```
*/
async update(
privateSpaceId: number,
body: UpdatePrivateSpaceBody,
options?: UpdatePrivateSpaceOptions,
): Promise<PrivateSpace> {
return (
await this.#fetch<UpdatePrivateSpaceResponse>(`/private-spaces/${privateSpaceId}`, {
method: 'PATCH',
query: {
confirmed: options?.confirmed,
},
body,
})
).privateSpace;
}
}
8 changes: 8 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,12 @@ export type {
ListPublicTemplatesOptions,
GetPublicTemplateOptions,
} from './endpoints/public-templates.js';
export type {
PrivateSpace,
PrivateSpaces,
ListPrivateSpacesOptions,
GetPrivateSpaceOptions,
UpdatePrivateSpaceBody,
UpdatePrivateSpaceOptions,
} from './endpoints/private-spaces.js';
export type { User, Users } from './endpoints/users.js';
Loading