57 endpoints at https://api.vaif.studio, generated from the API's OpenAPI document. The REST API page covers authentication, and All endpoints lists every group.
GET /orgs/{orgId}/managed-domains
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
domains: {
id: string;
name: string;
registrar: string;
expiresAt: string (date-time);
annualAmountCents: number;
}[];
}
GET /orgs/
Response 200 (application/json)
{
slugLocked: boolean;
blueprintDefaultEffort: null | string;
blueprintDefaultTier: null | string;
companyName: null | string;
createdAt: string (date-time);
createdBy: null | string;
dataRegion: string;
enterpriseAccountManager: null | string;
enterpriseProvisionedAt: null | string (date-time);
enterpriseSubdomain: null | string;
enterpriseTier: null | string;
founderAt: null | string (date-time);
founderNumber: null | number;
founderPriceLockUntil: null | string (date-time);
id: string;
managed: boolean;
name: string;
outsideMembersPolicy: string;
outsideMembersPolicyChangedAt: null | string (date-time);
outsideMembersPolicyChangedBy: null | string;
requireMfa: boolean;
requireMfaEnabledAt: null | string (date-time);
requireMfaEnabledBy: null | string;
slug: string;
}[]
POST /orgs/
Request body (application/json)
{
name: string;
companyName?: string;
}
Response 200 (application/json)
{
slugLocked: boolean;
blueprintDefaultEffort: null | string;
blueprintDefaultTier: null | string;
companyName: null | string;
createdAt: string (date-time);
createdBy: null | string;
dataRegion: string;
enterpriseAccountManager: null | string;
enterpriseProvisionedAt: null | string (date-time);
enterpriseSubdomain: null | string;
enterpriseTier: null | string;
founderAt: null | string (date-time);
founderNumber: null | number;
founderPriceLockUntil: null | string (date-time);
id: string;
managed: boolean;
name: string;
outsideMembersPolicy: string;
outsideMembersPolicyChangedAt: null | string (date-time);
outsideMembersPolicyChangedBy: null | string;
requireMfa: boolean;
requireMfaEnabledAt: null | string (date-time);
requireMfaEnabledBy: null | string;
slug: string;
}
POST /orgs/first
Response 200 (application/json)
{
org: any;
created: boolean;
}
PATCH /orgs/{orgId}
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json, required)
{
name: string;
}
Response 200 (application/json)
{
slugLocked: boolean;
id: string;
name: string;
slug: string;
companyName: null | string;
managed: boolean;
enterpriseSubdomain: null | string;
enterpriseTier: null | string;
enterpriseProvisionedAt: null | string (date-time);
enterpriseAccountManager: null | string;
dataRegion: string;
blueprintDefaultTier: null | string;
blueprintDefaultEffort: null | string;
founderAt: null | string (date-time);
founderNumber: null | number;
founderPriceLockUntil: null | string (date-time);
createdBy: null | string;
requireMfa: boolean;
requireMfaEnabledAt: null | string (date-time);
requireMfaEnabledBy: null | string;
outsideMembersPolicy: string;
outsideMembersPolicyChangedAt: null | string (date-time);
outsideMembersPolicyChangedBy: null | string;
createdAt: string (date-time);
}
GET /orgs/{orgId}/membership
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
membership: null | {
id: string;
userId: string;
orgId: string;
role: string;
createdAt: string (date-time);
permissions: ("billing.manage" | "billing.read" | "changes.request" | "team.invite")[];
};
accessPaused?: {
orgName: string;
domains: string[];
message: string;
};
}
DELETE /orgs/{orgId}/members/{userId}
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
userId | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
}
GET /orgs/{orgId}/roles
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
roles: {
key: string;
label: string;
description: string;
ownerOnly: boolean;
assignable: boolean;
}[];
}
PATCH /orgs/{orgId}/members/roles
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json, required)
{
changes: {
userId: string (uuid);
role: "owner" | "admin" | "developer" | "member" | "viewer" | "client" | "billing";
}[];
}
Response 200 (application/json)
{
members: {
userId: string;
role: string;
previousRole: string;
}[];
}
Errors: 400, 401, 403, 404, 409, with the error body.
PATCH /orgs/{orgId}/members/{userId}/role
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
userId | path | string | Yes |
Request body (application/json, required)
{
role: "owner" | "admin" | "developer" | "member" | "viewer" | "client" | "billing";
}
Response 200 (application/json)
{
createdAt: string (date-time);
id: string;
orgId: string;
role: string;
userId: string;
}
POST /orgs/{orgId}/transfer
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json)
{
toEmail: string;
billingHandoff?: boolean;
}
Response 200 (application/json)
{
ok: boolean;
transfer: any;
emailQueued: boolean;
}
POST /orgs/{orgId}/transfers/{id}/resend
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
id | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
emailQueued: boolean;
}
GET /orgs/{orgId}/transfers
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
transfers: {
id: string;
orgId: string;
toEmail: string;
status: string;
billingHandoff: boolean;
expiresAt: string (date-time);
createdAt: string (date-time);
acceptedAt: null | string (date-time);
fromOwnerUserId: string;
emailQueued: false | true | null;
emailQueuedAt: null | string (date-time);
declinedAt: null | string (date-time);
}[];
}
DELETE /orgs/{orgId}/transfers/{id}
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
id | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
}
GET /orgs/transfers/preview
| Parameter | In | Type | Required |
|---|
token | query | string | No |
Response 200 (application/json)
{
ok: boolean;
orgName: string;
fromName: null | string;
toEmail: string;
billingHandoff: boolean;
expiresAt: string (date-time);
plan?: {
name: string;
periodEnd: null | string;
};
}
POST /orgs/transfers/decline
Request body (application/json)
null | {
token?: any;
}
Response 200 (application/json)
{
ok: boolean;
}
POST /orgs/transfers/accept
Request body (application/json)
{
token: string;
}
Response 200 (application/json)
{
ok: boolean;
orgId: string;
org: {
id: string;
slug: string;
name: string;
};
}
GET /orgs/{orgId}/data-region
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
region: "eu-west-1" | "us-central-1";
defaultRegion: "eu-west-1" | "us-central-1";
entitled: boolean;
locked: boolean;
migrationRunbook: string;
supportedRegions: {
key: "eu-west-1" | "us-central-1";
label: string;
gcpRegion: string;
}[];
}
PATCH /orgs/{orgId}/data-region
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json, required)
{
region: string;
}
Response 200 (application/json)
{
region: any;
previousRegion: "eu-west-1" | "us-central-1";
appliesToExistingInstances: boolean;
}
GET /orgs/{orgId}/blueprint-defaults
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
tier: null | "lite" | "max" | "standard";
effort: null | "balanced" | "deep" | "extended" | "quick";
editable: boolean;
allowed: {
tiers: {
id: "lite" | "max" | "standard";
label: string;
}[];
efforts: {
id: "balanced" | "deep" | "extended" | "quick";
label: string;
}[];
};
}
PATCH /orgs/{orgId}/blueprint-defaults
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json, required)
{
tier?: string | null;
effort?: string | null;
}
Response 200 (application/json)
{
tier: null | "lite" | "max" | "standard";
effort: null | "balanced" | "deep" | "extended" | "quick";
}
GET /orgs/{orgId}/leave-requests
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
requests: {
id: string;
userId: string;
email: string;
name: null | string;
role: string;
reason: null | string;
createdAt: string (date-time);
expiresAt: string (date-time);
}[];
}
POST /orgs/{orgId}/leave-requests
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json, required)
{
reason?: string;
}
Response 200 (application/json)
{
ok: boolean;
request: {
id: string;
status: "approved" | "closed" | "declined" | "expired" | "pending" | "withdrawn";
reason: null | string;
createdAt: string (date-time);
expiresAt: string (date-time);
};
notified: number;
}
GET /orgs/{orgId}/leave-requests/mine
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
request: {
id: string;
status: "approved" | "closed" | "declined" | "expired" | "pending" | "withdrawn";
reason: null | string;
createdAt: string (date-time);
expiresAt: string (date-time);
};
}
DELETE /orgs/{orgId}/leave-requests/mine
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
}
POST /orgs/{orgId}/leave-requests/{requestId}/approve
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
requestId | path | string | Yes |
Request body (application/json, required)
{
note?: string;
}
Response 200 (application/json)
{
ok: boolean;
}
POST /orgs/{orgId}/leave-requests/{requestId}/decline
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
requestId | path | string | Yes |
Request body (application/json, required)
{
note?: string;
}
Response 200 (application/json)
{
ok: boolean;
}
GET /orgs/{orgId}/managed-summary
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
limit | query | number | No |
Response 200 (application/json)
{
contracts: {
total: number;
active: number;
onHold: number;
};
nonPayment: {
unpaidInvoices: number;
pausedServices: number;
};
domains: {
total: number;
expiringWithin30Days: number;
};
recentOps: {
at: string;
kind: string;
summary: string;
}[];
}
GET /orgs/{orgId}/change-requests
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
limit | query | number | No |
Response 200 (application/json)
{
requests: {
id: string;
message: string;
status: "declined" | "done" | "in_progress" | "open";
requesterEmail: string;
createdAt: null | string;
updatedAt: null | string;
}[];
}
POST /orgs/{orgId}/change-requests
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json)
{
message: string;
}
Response 200 (application/json)
{
ok: boolean;
request: {
id: string;
message: string;
status: "declined" | "done" | "in_progress" | "open";
requesterEmail: string;
createdAt: null | string;
updatedAt: null | string;
};
}
GET /orgs/{orgId}/members
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
members: {
twoFactor?: boolean;
signIn?: any[];
lastSignInAt?: null | string;
id: string;
userId: string;
orgId: string;
role: string;
createdAt: string (date-time);
user: {
id: string;
email: null | string;
name: null | string;
avatarUrl: null | string;
};
}[];
}
GET /orgs/{orgId}/invites
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
invites: {
id: string;
orgId: string;
email: string;
role: string;
status: string;
expiresAt: string (date-time);
emailQueued: false | true | null;
emailQueuedAt: null | string (date-time);
createdAt: string (date-time);
invitedBy: null | {
id: string;
name: any;
};
}[];
}
DELETE /orgs/{orgId}/invites/{inviteId}
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
inviteId | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
}
POST /orgs/{orgId}/invites/{inviteId}/resend
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
inviteId | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
emailQueued: boolean;
}
POST /orgs/{orgId}/members/invite
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json)
{
email: string;
role: "admin" | "billing" | "client" | "developer" | "member" | "owner" | "viewer";
allowOutside?: boolean;
}
Response 200 (application/json)
{
ok: boolean;
invite: {
id: string;
orgId: string;
email: string;
role: string;
status: string;
expiresAt: string (date-time);
createdAt: string (date-time);
emailQueued: boolean;
emailQueuedAt: null | string (date-time);
};
emailQueued: boolean;
}
GET /orgs/invites/lookup
| Parameter | In | Type | Required |
|---|
token | query | string | No |
Response 200 (application/json)
{
orgName: string;
role: string;
email: string;
invitedBy: null | {
name: null | string;
};
expiresAt: string (date-time);
status: string;
}
POST /orgs/invites/decline
Request body (application/json)
null | {
token?: any;
}
Response 200 (application/json)
{
ok: boolean;
}
POST /orgs/invites/accept
Request body (application/json)
{
token: string;
}
Response 200 (application/json)
{
ok: boolean;
orgId: string;
role: string;
org: {
id: string;
slug: string;
name: string;
};
}
GET /orgs/{orgId}/security
| Parameter | In | Type | Required |
|---|
orgId | path | string (uuid) | Yes |
Response 200 (application/json)
{
requireMfa: boolean;
enabledAt: string | null;
enabledBy: {
id: string;
name: string | null;
} | null;
membersWithoutMfa: number;
members: number;
canWrite: boolean;
}
Errors: 401, 403, 404, with the error body.
PATCH /orgs/{orgId}/security
| Parameter | In | Type | Required |
|---|
orgId | path | string (uuid) | Yes |
Request body (application/json, required)
{
requireMfa: boolean;
preview?: boolean;
}
Response 200 (application/json)
{
requireMfa: boolean;
affectedMembers: number;
preview: boolean;
}
Errors: 401, 403, 404, 409, with the error body.
GET /orgs/{orgId}/profile
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
ok: boolean;
profile: {
id: string;
orgId: string;
legalName: null | string;
displayName: null | string;
billingEmail: null | string;
addressLine1: null | string;
addressLine2: null | string;
city: null | string;
state: null | string;
postalCode: null | string;
country: null | string;
taxIdHint: null | string;
createdAt: string (date-time);
updatedAt: string (date-time);
};
}
PATCH /orgs/{orgId}/profile
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json)
{
legalName?: string;
displayName?: string;
billingEmail?: string;
addressLine1?: string;
addressLine2?: string;
city?: string;
state?: string;
postalCode?: string;
country?: string;
taxIdHint?: string;
}
Response 200 (application/json)
{
ok: boolean;
profile: any;
}
List billing contacts for an organization
| Parameter | In | Type | Required |
|---|
orgId | path | string (uuid) | Yes |
Response 200 (application/json)
{
ok: true;
contacts: {
id: string (uuid);
orgId: string (uuid);
email: string;
label: string | null;
createdAt: string (date-time) | string;
}[];
}
Errors: 401, 403, with the error body.
POST /orgs/{orgId}/billing-contacts
Add a billing contact to an organization
| Parameter | In | Type | Required |
|---|
orgId | path | string (uuid) | Yes |
Request body (application/json, required)
{
email: string (email);
label?: string;
}
Response 200 (application/json)
{
ok: true;
contact: {
id: string (uuid);
orgId: string (uuid);
email: string;
label: string | null;
createdAt: string (date-time) | string;
};
}
Errors: 400, 401, 403, 409, with the error body.
Remove a billing contact from an organization
| Parameter | In | Type | Required |
|---|
orgId | path | string (uuid) | Yes |
contactId | path | string (uuid) | Yes |
Response 200 (application/json)
{
ok: true;
}
Errors: 400, 401, 403, 404, with the error body.
GET /orgs/{orgId}/support/tickets
| Parameter | In | Type | Required |
|---|
status | query | "open" | "waiting_on_vaif" | "waiting_on_customer" | "resolved" | "closed" | No |
priority | query | "p1" | "p2" | "p3" | "p4" | No |
cursor | query | number | No |
orgId | path | string | Yes |
Response 200 (application/json)
{
tickets: {
number: number;
subject: string;
category: string;
priority: "p1" | "p2" | "p3" | "p4";
priorityLabel: string;
status: string;
project: {
id: string;
name: string;
} | null;
openedBy: {
name: string | null;
} | null;
createdAt: string;
updatedAt: string;
resolvedAt: string | null;
closedAt: string | null;
reopenUntil: string | null;
firstResponse: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
resolution: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
}[];
nextCursor: string | null;
}
Errors: 401, 403, 404, with the error body.
POST /orgs/{orgId}/support/tickets
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Request body (application/json, required)
{
subject: string;
category: "production" | "broken" | "question" | "billing" | "access";
priority: "p1" | "p2" | "p3" | "p4";
projectId?: string (uuid) | null;
body: string;
}
Response 201 (application/json)
{
ticket: {
number: number;
subject: string;
category: string;
priority: "p1" | "p2" | "p3" | "p4";
priorityLabel: string;
status: string;
project: {
id: string;
name: string;
} | null;
openedBy: {
name: string | null;
} | null;
createdAt: string;
updatedAt: string;
resolvedAt: string | null;
closedAt: string | null;
reopenUntil: string | null;
firstResponse: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
resolution: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
};
thread: {
kind: "message";
id: string;
authorKind: "customer" | "staff";
authorName: string;
body: string;
internal: boolean;
createdAt: string;
} | {
kind: "event";
id: string;
event: string;
actorKind: string;
actorName: string | null;
before?: any;
after?: any;
reason: string | null;
createdAt: string;
}[];
}
Errors: 400, 401, 403, 404, 429, with the error body.
GET /orgs/{orgId}/support/tickets/{number}
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
number | path | number | Yes |
Response 200 (application/json)
{
ticket: {
number: number;
subject: string;
category: string;
priority: "p1" | "p2" | "p3" | "p4";
priorityLabel: string;
status: string;
project: {
id: string;
name: string;
} | null;
openedBy: {
name: string | null;
} | null;
createdAt: string;
updatedAt: string;
resolvedAt: string | null;
closedAt: string | null;
reopenUntil: string | null;
firstResponse: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
resolution: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
};
thread: {
kind: "message";
id: string;
authorKind: "customer" | "staff";
authorName: string;
body: string;
internal: boolean;
createdAt: string;
} | {
kind: "event";
id: string;
event: string;
actorKind: string;
actorName: string | null;
before?: any;
after?: any;
reason: string | null;
createdAt: string;
}[];
}
Errors: 401, 403, 404, with the error body.
POST /orgs/{orgId}/support/tickets/{number}/messages
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
number | path | number | Yes |
Request body (application/json, required)
{
body: string;
}
Response 201 (application/json)
{
ticket: {
number: number;
subject: string;
category: string;
priority: "p1" | "p2" | "p3" | "p4";
priorityLabel: string;
status: string;
project: {
id: string;
name: string;
} | null;
openedBy: {
name: string | null;
} | null;
createdAt: string;
updatedAt: string;
resolvedAt: string | null;
closedAt: string | null;
reopenUntil: string | null;
firstResponse: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
resolution: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
};
thread: {
kind: "message";
id: string;
authorKind: "customer" | "staff";
authorName: string;
body: string;
internal: boolean;
createdAt: string;
} | {
kind: "event";
id: string;
event: string;
actorKind: string;
actorName: string | null;
before?: any;
after?: any;
reason: string | null;
createdAt: string;
}[];
}
Errors: 401, 403, 404, 409, with the error body.
POST /orgs/{orgId}/support/tickets/{number}/resolve
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
number | path | number | Yes |
Response 200 (application/json)
{
ticket: {
number: number;
subject: string;
category: string;
priority: "p1" | "p2" | "p3" | "p4";
priorityLabel: string;
status: string;
project: {
id: string;
name: string;
} | null;
openedBy: {
name: string | null;
} | null;
createdAt: string;
updatedAt: string;
resolvedAt: string | null;
closedAt: string | null;
reopenUntil: string | null;
firstResponse: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
resolution: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
};
thread: {
kind: "message";
id: string;
authorKind: "customer" | "staff";
authorName: string;
body: string;
internal: boolean;
createdAt: string;
} | {
kind: "event";
id: string;
event: string;
actorKind: string;
actorName: string | null;
before?: any;
after?: any;
reason: string | null;
createdAt: string;
}[];
}
Errors: 401, 403, 404, 409, with the error body.
POST /orgs/{orgId}/support/tickets/{number}/reopen
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
number | path | number | Yes |
Response 200 (application/json)
{
ticket: {
number: number;
subject: string;
category: string;
priority: "p1" | "p2" | "p3" | "p4";
priorityLabel: string;
status: string;
project: {
id: string;
name: string;
} | null;
openedBy: {
name: string | null;
} | null;
createdAt: string;
updatedAt: string;
resolvedAt: string | null;
closedAt: string | null;
reopenUntil: string | null;
firstResponse: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
resolution: {
state: "no_target" | "running" | "at_risk" | "missed" | "paused" | "met";
remainingMinutes: number | null;
targetMinutes: number | null;
usedMinutes: number | null;
dueAt: string | null;
stoppedAt: string | null;
};
};
thread: {
kind: "message";
id: string;
authorKind: "customer" | "staff";
authorName: string;
body: string;
internal: boolean;
createdAt: string;
} | {
kind: "event";
id: string;
event: string;
actorKind: string;
actorName: string | null;
before?: any;
after?: any;
reason: string | null;
createdAt: string;
}[];
}
Errors: 401, 403, 404, 409, with the error body.
GET /orgs/{orgId}/support/sla-report
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
month | query | string | No |
format | query | string | No |
Response 200 (application/json)
{
month: string;
support: {
byPriority: {
priority: "p1" | "p2" | "p3" | "p4";
label: string;
opened: number;
firstResponse: {
met: number;
missed: number;
open: number;
};
resolution: {
met: number;
missed: number;
open: number;
};
}[];
};
uptime: {
source: "status_checks";
target: string;
components: {
id: string;
name: string;
percent: string | null;
measuredDays: number;
daysInMonth: number;
}[];
} | null;
}
Errors: 400, 401, 403, 404, with the error body.
GET /orgs/{orgId}/support/terms
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
supportTier: string;
calendar: "business" | "always";
timezone: string;
businessDays: number[];
businessStart: string | null;
businessEnd: string | null;
pausedUntil: string | null;
priorities: {
id: "p1" | "p2" | "p3" | "p4";
name: string;
label: string;
definition: string;
firstResponseMinutes: number;
resolutionMinutes: number;
}[];
}
Errors: 401, 403, 404, with the error body.
GET /orgs/{orgId}/support/summary
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
open: number;
atRisk: number;
missed: number;
waitingOnYou: number;
resolvedThisMonth: number;
attention: {
number: number;
subject: string;
reason: "missed" | "at_risk" | "waiting_on_you";
clock: "first_response" | "resolution";
dueAt: string | null;
remainingMinutes: number | null;
since: string | null;
}[];
}
Errors: 401, 403, 404, with the error body.
GET /orgs/{orgId}/access-matrix
| Parameter | In | Type | Required |
|---|
q | query | string | No |
orgRole | query | "owner" | "admin" | "developer" | "member" | "viewer" | "billing" | "client" | No |
withoutMfa | query | "true" | "false" | No |
cursor | query | number | No |
limit | query | number | No |
orgId | path | string | Yes |
Response 200 (application/json)
{
projects: {
id: string;
name: string;
}[];
members: {
userId: string;
name: string | null;
email: string;
orgRole: string;
signIn: "sso" | "password" | "both";
twoFactor: boolean;
projectRoles: {
[key: string]: string | null;
};
}[];
nextCursor: string | null;
}
Errors: 401, 403, 404, with the error body.
GET /orgs/{orgId}/identity/summary
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
entitled: {
saml: boolean;
scim: boolean;
};
connections: {
id: string;
protocol: "saml" | "oidc";
displayName: string;
status: "active" | "needs_domain" | "off";
domains: {
domain: string;
verifiedAt: string | null;
}[];
certificateExpiresAt: string | null;
}[];
requireSso: {
on: boolean;
since: string | null;
by: {
userId: string;
name: string;
} | null;
};
breakGlassOwners: {
userId: string;
name: string;
password: boolean;
twoFactor: boolean;
}[];
members: {
total: number;
withoutTwoFactor: number;
password: number;
};
requireSsoImpact: {
coveredPassword: {
domain: string;
count: number;
}[];
uncovered: number;
};
scim: {
status: "active" | "off";
lastSyncAt: string | null;
provisioned: number;
} | null;
}
Errors: 401, 403, 404, with the error body.
GET /orgs/{orgId}/security/posture
| Parameter | In | Type | Required |
|---|
orgId | path | string | Yes |
Response 200 (application/json)
{
checkedAt: string;
groups: {
id: "identity" | "data" | "network" | "projects";
items: {
id: string;
status: "ok" | "attention" | "partial" | "off" | "not_applicable";
title: string;
detail: string;
fix: {
kind: "tenant" | "console";
path: string;
} | null;
}[];
}[];
}
Errors: 401, 403, 404, with the error body.