BackstageClient.cases
BackstageClient.cases in @ticketlayer/backstage.
@ticketlayer/backstage / BackstageClient / cases
cases: {
clearPresence: (caseId: string, requestOptions?: RequestOptions) => Promise<{
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[]>;
create: (request: {
accountId?: string;
category?: string;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
contact?: {
email?: string | null;
name?: string | null;
phone?: string | null;
};
customerId?: string;
links?: {
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation?: "follow_up" | "about" | "merged" | "related";
}[];
note?: {
body: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
};
priority?: "low" | "normal" | "high" | "urgent";
salesChannelId?: string;
subject: string;
tags?: string[];
}, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;
get: (caseId: string, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;
link: (caseId: string, request: {
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation?: "follow_up" | "about" | "merged" | "related";
}, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;
list: (options?: {
accountId?: string;
category?: string;
channel?: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
cursor?: string;
customerId?: string;
limit?: string;
linkedId?: string;
linkedType?: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
priority?: "low" | "normal" | "high" | "urgent";
search?: string;
state?: string;
stateCategory?: "cancelled" | "open" | "waiting" | "done";
tag?: string;
}, requestOptions?: RequestOptions) => Promise<{
cases: {
assignedAt: string | null;
assigneeUserId: string | null;
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}[];
nextCursor: string | null;
}>;
listActions: (caseId: string, requestOptions?: RequestOptions) => Promise<{
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[]>;
listActivities: (caseId: string, options?: {
cursor?: string;
limit?: string;
tier?: string;
}, requestOptions?: RequestOptions) => Promise<{
activities: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
}[];
nextCursor: string | null;
}>;
listProposals: (caseId: string, requestOptions?: RequestOptions) => Promise<{
caseId: string | null;
confirmedAt: string | null;
conversationId: string;
createdAt: string;
effect: {
[key: string]: unknown;
};
executedAt: string | null;
executionError: string | null;
id: string;
inputs: {
[key: string]: unknown;
};
kind: "refund" | "exchange" | "name_change" | "transfer" | "resend";
level: string;
message: string;
orderId: string;
policyVersion: string;
reasonCode: string;
refundRequestId: string | null;
thresholdsSource: {
[key: string]: unknown;
};
verdict: "confirm" | "deny" | "staff_approval" | "allow";
}[]>;
logActivity: (caseId: string, request:
| {
attachmentAssetIds?: string[];
body: string;
kind: "note";
occurredAt?: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
}
| {
attachmentAssetIds?: string[];
direction: "inbound" | "outbound";
durationSeconds?: number;
kind: "call";
notes?: string;
occurredAt?: string;
outcome?: | "resolved"
| "follow_up"
| "voicemail"
| "no_answer"
| "wrong_number"
| "other";
phoneNumber?: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
}
| {
asked: string;
attachmentAssetIds?: string[];
done: string;
kind: "visit";
notes?: string;
occurredAt?: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
}, requestOptions?: RequestOptions) => Promise<{
activity: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
};
caseReopened: boolean;
}>;
renderMacro: (caseId: string, macroId: string, request: {
orderId?: string;
}, requestOptions?: RequestOptions) => Promise<{
action: | {
action: string;
available: boolean;
label: string | null;
orderIds?: string[];
requiresFields: string[];
}
| null;
body: string;
caseId: string;
knowledgeArticleId: string | null;
macroId: string;
missingVariables: string[];
resultingState: | "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| null;
transition: | {
action: string;
available: boolean;
label: string | null;
orderIds?: string[];
requiresFields: string[];
}
| null;
}>;
setPresence: (caseId: string, request: {
mode: "viewing" | "replying";
}, requestOptions?: RequestOptions) => Promise<{
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[]>;
takeAction: (caseId: string, action: string, request: {
expectedVersion?: number;
fields?: {
activityIds?: string[];
assigneeId?: string;
body?: string;
orderId?: string;
queueKey?: string | null;
reason?: string;
resolutionReason?: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate";
subject?: string;
targetCaseId?: string;
};
note?: {
body: string;
tier?: "internal" | "restricted" | "self";
};
}, requestOptions?: RequestOptions) => Promise<{
activity: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
};
case: {
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
};
result: {
[key: string]: unknown;
};
}>;
unlink: (caseId: string, linkId: string, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;
update: (caseId: string, request: {
category?: string | null;
contact?: {
email?: string | null;
name?: string | null;
phone?: string | null;
} & Record<string, never>;
customerId?: string | null;
expectedVersion?: number;
priority?: "low" | "normal" | "high" | "urgent";
subject?: string;
tags?: string[];
}, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;
};Defined in: client.ts:10961
Cases methods
clearPresence()#
clearPresence: (caseId: string, requestOptions?: RequestOptions) => Promise<{
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[]>;Leave a case You are no longer viewing or replying to the case. Answers who still is.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[]>
Operation Id#
deleteCasePresence
create()#
create: (request: {
accountId?: string;
category?: string;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
contact?: {
email?: string | null;
name?: string | null;
phone?: string | null;
};
customerId?: string;
links?: {
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation?: "follow_up" | "about" | "merged" | "related";
}[];
note?: {
body: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
};
priority?: "low" | "normal" | "high" | "urgent";
salesChannelId?: string;
subject: string;
tags?: string[];
}, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;Open a case
Open a case: one conversation with one customer about one thing. Name the customer (one you can read) or a contact (an email address or phone number, which never becomes a customer here), and link what it is about. The case belongs to the account that owns what it is about (the linked order's event); with nothing linked, to accountId, else your own account when you write cases on one, else the organisation when you write them on every account. Objects of two accounts on one case are refused (409 CASE_LINK_ACCOUNT_MISMATCH). Needs cases.write for that account.
Parameters#
| Parameter | Type | Description |
|---|---|---|
request | { accountId?: string; category?: string; channel: | "email" | "phone" | "sms" | "in_person" | "chat" | "concierge" | "manage" | "box_office" | "api"; contact?: { email?: string | null; name?: string | null; phone?: string | null; }; customerId?: string; links?: { objectId: string; objectType: | "order" | "case" | "event" | "pass" | "occurrence" | "payment" | "refund_request"; relation?: "follow_up" | "about" | "merged" | "related"; }[]; note?: { body: string; sensitive?: boolean; tier?: "internal" | "restricted" | "self"; }; priority?: "low" | "normal" | "high" | "urgent"; salesChannelId?: string; subject: string; tags?: string[]; } | - |
request.accountId? | string | Description The account the case belongs to when nothing linked names one. Ignored in favour of the linked objects' owner, and refused when it disagrees with it. Example acc_xyz789 |
request.category? | string | Example accessibility |
request.channel? | | "email" | "phone" | "sms" | "in_person" | "chat" | "concierge" | "manage" | "box_office" | "api" | Description The channel the case came in on Example phone @enum {string} |
request.contact? | { email?: string | null; name?: string | null; phone?: string | null; } | - |
request.contact.email? | string | null | Format: email |
request.contact.name? | string | null | - |
request.contact.phone? | string | null | - |
request.customerId? | string | Example cus_abc123 |
request.links? | { objectId: string; objectType: | "order" | "case" | "event" | "pass" | "occurrence" | "payment" | "refund_request"; relation?: "follow_up" | "about" | "merged" | "related"; }[] | - |
request.note? | { body: string; sensitive?: boolean; tier?: "internal" | "restricted" | "self"; } | Description A first note on the case, as an activity of kind note. |
request.note.body? | string | - |
request.note.sensitive? | boolean | - |
request.note.tier? | "internal" | "restricted" | "self" | Description internal (the default), restricted (needs cases.write_restricted) or self (the customer may see it). |
request.priority? | "low" | "normal" | "high" | "urgent" | Example normal @enum {string} |
request.salesChannelId? | string | Example sch_boxoffice |
request.subject? | string | Example Wheelchair space for Saturday |
request.tags? | string[] | Example [ "vip" ] |
requestOptions? | RequestOptions | - |
Returns#
Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>
Operation Id#
createCase
get()#
get: (caseId: string, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;Get a case
A case with its links and the actions you may take on it now (availableActions). A staff person may always read a case assigned to them or to a queue they belong to, at the tiers their permissions allow. 404 CASE_NOT_FOUND for a case another account owns that is not one of those.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>
Operation Id#
getCase
link()#
link: (caseId: string, request: {
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation?: "follow_up" | "about" | "merged" | "related";
}, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;Link a case
Link what the case is about: an order, pass, event, occurrence, payment or refund request (relation about), or another case (merged, related or follow_up). An object another account owns is refused (409 CASE_LINK_ACCOUNT_MISMATCH); a case the organisation owns becomes the account's when the first owned object is linked.
Parameters#
| Parameter | Type | Description |
|---|---|---|
caseId | string | - |
request | { objectId: string; objectType: | "order" | "case" | "event" | "pass" | "occurrence" | "payment" | "refund_request"; relation?: "follow_up" | "about" | "merged" | "related"; } | - |
request.objectId | string | Example ord_abc123xyz789 |
request.objectType? | | "order" | "case" | "event" | "pass" | "occurrence" | "payment" | "refund_request" | Example order @enum {string} |
request.relation? | "follow_up" | "about" | "merged" | "related" | Description about (the default) for an order, pass, event, occurrence, payment or refund request; merged, related (the default) or follow_up for another case. |
requestOptions? | RequestOptions | - |
Returns#
Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>
Operation Id#
linkCase
list()#
list: (options?: {
accountId?: string;
category?: string;
channel?: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
cursor?: string;
customerId?: string;
limit?: string;
linkedId?: string;
linkedType?: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
priority?: "low" | "normal" | "high" | "urgent";
search?: string;
state?: string;
stateCategory?: "cancelled" | "open" | "waiting" | "done";
tag?: string;
}, requestOptions?: RequestOptions) => Promise<{
cases: {
assignedAt: string | null;
assigneeUserId: string | null;
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}[];
nextCursor: string | null;
}>;List cases
The cases you can read, most recently changed first: those of the accounts your cases.read reaches, and the organisation's own at :all, and, for any staff person, those assigned to you or filed under a queue you belong to, whatever your roles otherwise reach. Never another account's otherwise. Filter by state, stateCategory, priority, category, tag, customer, owning account or channel; page with cursor.
Parameters#
| Parameter | Type |
|---|---|
options? | { accountId?: string; category?: string; channel?: | "email" | "phone" | "sms" | "in_person" | "chat" | "concierge" | "manage" | "box_office" | "api"; cursor?: string; customerId?: string; limit?: string; linkedId?: string; linkedType?: | "order" | "case" | "event" | "pass" | "occurrence" | "payment" | "refund_request"; priority?: "low" | "normal" | "high" | "urgent"; search?: string; state?: string; stateCategory?: "cancelled" | "open" | "waiting" | "done"; tag?: string; } |
options.accountId? | string |
options.category? | string |
options.channel? | | "email" | "phone" | "sms" | "in_person" | "chat" | "concierge" | "manage" | "box_office" | "api" |
options.cursor? | string |
options.customerId? | string |
options.limit? | string |
options.linkedId? | string |
options.linkedType? | | "order" | "case" | "event" | "pass" | "occurrence" | "payment" | "refund_request" |
options.priority? | "low" | "normal" | "high" | "urgent" |
options.search? | string |
options.state? | string |
options.stateCategory? | "cancelled" | "open" | "waiting" | "done" |
options.tag? | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
cases: {
assignedAt: string | null;
assigneeUserId: string | null;
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}[];
nextCursor: string | null;
}>
Operation Id#
listCases
listActions()#
listActions: (caseId: string, requestOptions?: RequestOptions) => Promise<{
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[]>;List the actions you may take on a case The state changes the case's state admits; on a case with linked orders, refund and resend for the orders your own permissions reach (refundrequests.create, orders.read); and reply when the case has an email address on file and the plan has email on cases. Empty when you read the case but may not write it.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[]>
Operation Id#
listCaseActions
listActivities()#
listActivities: (caseId: string, options?: {
cursor?: string;
limit?: string;
tier?: string;
}, requestOptions?: RequestOptions) => Promise<{
activities: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
}[];
nextCursor: string | null;
}>;List a case's activities
Everything that happened on the case, newest first: notes, calls, visits, actions taken. restricted activities only with cases.read_restricted for the case's account: they are omitted otherwise, with nothing saying they exist. The person working the case (assigned to them or their queue) reads its self and internal activities.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
options? | { cursor?: string; limit?: string; tier?: string; } |
options.cursor? | string |
options.limit? | string |
options.tier? | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
activities: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
}[];
nextCursor: string | null;
}>
Operation Id#
listCaseActivities
listProposals()#
listProposals: (caseId: string, requestOptions?: RequestOptions) => Promise<{
caseId: string | null;
confirmedAt: string | null;
conversationId: string;
createdAt: string;
effect: {
[key: string]: unknown;
};
executedAt: string | null;
executionError: string | null;
id: string;
inputs: {
[key: string]: unknown;
};
kind: "refund" | "exchange" | "name_change" | "transfer" | "resend";
level: string;
message: string;
orderId: string;
policyVersion: string;
reasonCode: string;
refundRequestId: string | null;
thresholdsSource: {
[key: string]: unknown;
};
verdict: "confirm" | "deny" | "staff_approval" | "allow";
}[]>;List the AI's proposals on a case Every proposal the Concierge AI made in the conversation this case is for, oldest first, with the policy engine's verdict (allow, confirm, staff_approval, deny), its reason, the policy version, where each AI action limit came from, the computed effect, everything it was decided on, and when it was confirmed and executed. A staff_approval refund or exchange is decided through its refund request (POST /refund-requests/{requestId}/approve or /reject), linked to the case.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
caseId: string | null;
confirmedAt: string | null;
conversationId: string;
createdAt: string;
effect: {
[key: string]: unknown;
};
executedAt: string | null;
executionError: string | null;
id: string;
inputs: {
[key: string]: unknown;
};
kind: "refund" | "exchange" | "name_change" | "transfer" | "resend";
level: string;
message: string;
orderId: string;
policyVersion: string;
reasonCode: string;
refundRequestId: string | null;
thresholdsSource: {
[key: string]: unknown;
};
verdict: "confirm" | "deny" | "staff_approval" | "allow";
}[]>
Operation Id#
listCaseProposals
logActivity()#
logActivity: (caseId: string, request:
| {
attachmentAssetIds?: string[];
body: string;
kind: "note";
occurredAt?: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
}
| {
attachmentAssetIds?: string[];
direction: "inbound" | "outbound";
durationSeconds?: number;
kind: "call";
notes?: string;
occurredAt?: string;
outcome?: | "resolved"
| "follow_up"
| "voicemail"
| "no_answer"
| "wrong_number"
| "other";
phoneNumber?: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
}
| {
asked: string;
attachmentAssetIds?: string[];
done: string;
kind: "visit";
notes?: string;
occurredAt?: string;
sensitive?: boolean;
tier?: "internal" | "restricted" | "self";
}, requestOptions?: RequestOptions) => Promise<{
activity: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
};
caseReopened: boolean;
}>;Log an activity on a case
Add a note, a logged call or an in-person visit to a case. The customer getting in touch (an inbound call, a visit) reopens a resolved case inside its reopen window, and is refused on a closed case or one past the window (409 CASE_CLOSED, CASE_REOPEN_WINDOW_PASSED): open a new case linked as a follow-up. A note is accepted in any state. A restricted activity needs cases.write_restricted.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
request | | { attachmentAssetIds?: string[]; body: string; kind: "note"; occurredAt?: string; sensitive?: boolean; tier?: "internal" | "restricted" | "self"; } | { attachmentAssetIds?: string[]; direction: "inbound" | "outbound"; durationSeconds?: number; kind: "call"; notes?: string; occurredAt?: string; outcome?: | "resolved" | "follow_up" | "voicemail" | "no_answer" | "wrong_number" | "other"; phoneNumber?: string; sensitive?: boolean; tier?: "internal" | "restricted" | "self"; } | { asked: string; attachmentAssetIds?: string[]; done: string; kind: "visit"; notes?: string; occurredAt?: string; sensitive?: boolean; tier?: "internal" | "restricted" | "self"; } |
requestOptions? | RequestOptions |
Returns#
Promise<{
activity: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
};
caseReopened: boolean;
}>
Operation Id#
logCaseActivity
renderMacro()#
renderMacro: (caseId: string, macroId: string, request: {
orderId?: string;
}, requestOptions?: RequestOptions) => Promise<{
action: | {
action: string;
available: boolean;
label: string | null;
orderIds?: string[];
requiresFields: string[];
}
| null;
body: string;
caseId: string;
knowledgeArticleId: string | null;
macroId: string;
missingVariables: string[];
resultingState: | "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| null;
transition: | {
action: string;
available: boolean;
label: string | null;
orderIds?: string[];
requiresFields: string[];
}
| null;
}>;Render a macro for a case Fill a macro's variables from the case ({{customer.firstName}}, {{order.number}}, {{agent.firstName}}, {{brand.displayName}}, ...) and say what it would do: the case action it names and the state it leaves the case in, each with whether you may take it now. Sends nothing; take the action with POST /cases/{caseId}/actions/{action}. Variables you may not read (the customer without customers.read, the order without orders.read) render empty and are listed in missingVariables. The macro must be the organisation's or the case's account's (404 MACRO_NOT_FOUND otherwise).
Parameters#
| Parameter | Type | Description |
|---|---|---|
caseId | string | - |
macroId | string | - |
request | { orderId?: string; } | - |
request.orderId? | string | Description The linked order {{order.number}} names, when the case links more than one |
requestOptions? | RequestOptions | - |
Returns#
Promise<{
action: | {
action: string;
available: boolean;
label: string | null;
orderIds?: string[];
requiresFields: string[];
}
| null;
body: string;
caseId: string;
knowledgeArticleId: string | null;
macroId: string;
missingVariables: string[];
resultingState: | "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| null;
transition: | {
action: string;
available: boolean;
label: string | null;
orderIds?: string[];
requiresFields: string[];
}
| null;
}>
Operation Id#
renderCaseMacro
setPresence()#
setPresence: (caseId: string, request: {
mode: "viewing" | "replying";
}, requestOptions?: RequestOptions) => Promise<{
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[]>;Say you are viewing or replying to a case
Collision detection: record that you are viewing (cases.read) or replying to (cases.write) the case for the next minute, and see who else is. Send it again every 20 seconds or so while the case is open; the case read lists everyone present in presence. A person only: 403 CASE_PRESENCE_REQUIRES_PERSON for an API key or app.
Parameters#
| Parameter | Type | Description |
|---|---|---|
caseId | string | - |
request | { mode: "viewing" | "replying"; } | - |
request.mode | "viewing" | "replying" | Description viewing needs cases.read, replying cases.write Example replying @enum {string} |
requestOptions? | RequestOptions | - |
Returns#
Promise<{
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[]>
Operation Id#
putCasePresence
takeAction()#
takeAction: (caseId: string, action: string, request: {
expectedVersion?: number;
fields?: {
activityIds?: string[];
assigneeId?: string;
body?: string;
orderId?: string;
queueKey?: string | null;
reason?: string;
resolutionReason?: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate";
subject?: string;
targetCaseId?: string;
};
note?: {
body: string;
tier?: "internal" | "restricted" | "self";
};
}, requestOptions?: RequestOptions) => Promise<{
activity: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
};
case: {
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
};
result: {
[key: string]: unknown;
};
}>;Take an action on a case
The generic action endpoint, in the shape every registered object will share (POST /{objects}/{id}/actions/{action}). State changes: open, wait_on_customer, wait_on_internal, resolve (needs fields.resolutionReason), reopen (inside the reopen window), close, mark_spam. On a linked order: refund raises a refund request as staff (needs refundrequests.create for the order's account) and links it to the case; resend resends the order's confirmation email with its tickets (needs orders.read). The inbox (TKT-604): assign (fields.assigneeId, a person who could work the case), claim (yourself; 409 CASE_ALREADY_ASSIGNED when someone else holds it), unassign, set_queue (fields.queueKey), merge (fields.targetCaseId: this case is the duplicate; its activities and links move to the target and it is resolved as duplicate), split (fields.activityIds: those move to a new case). assign, claim and set_queue are the Platform inbox (403 PLAN_ENTITLEMENT_REQUIRED on other plans). By email: reply sends fields.body to the customer's email on file (the case's customer, else its contact; 409 CASE_EMAIL_NO_RECIPIENT when there is none), branded for the case's sales channel, from the platform address with the organisation's name, threaded so the answer comes back to the case, and records an email_out activity (needs a plan with email on cases, support.email). Every action is recorded on the case as an action activity, with the note if one is sent. 404 CASE_ACTION_UNKNOWN for an action that does not exist, 409 for one the case does not admit now.
Parameters#
| Parameter | Type | Description |
|---|---|---|
caseId | string | - |
action | string | - |
request | { expectedVersion?: number; fields?: { activityIds?: string[]; assigneeId?: string; body?: string; orderId?: string; queueKey?: string | null; reason?: string; resolutionReason?: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate"; subject?: string; targetCaseId?: string; }; note?: { body: string; tier?: "internal" | "restricted" | "self"; }; } | - |
request.expectedVersion? | number | Description The version the action is based on; 412 VERSION_MISMATCH when the case has moved on. |
request.fields? | { activityIds?: string[]; assigneeId?: string; body?: string; orderId?: string; queueKey?: string | null; reason?: string; resolutionReason?: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate"; subject?: string; targetCaseId?: string; } | - |
request.fields.activityIds? | string[] | Description split: the activities that move to the new case |
request.fields.assigneeId? | string | Description assign: the user to hand the case to; they must hold cases.write for its account |
request.fields.body? | string | Description reply: the text sent to the customer, as plain text (it is escaped, never rendered as HTML). It goes to the email on file, never to an address in the request |
request.fields.orderId? | string | Description refund and resend: which linked order, when the case links more than one |
request.fields.queueKey? | string | null | Description set_queue: the queue to file the case under, or null for none |
request.fields.reason? | string | Description refund: the reason recorded on the refund request |
request.fields.resolutionReason? | "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | Description Needed by resolve |
request.fields.subject? | string | Description split: the new case's subject |
request.fields.targetCaseId? | string | Description merge: the case this one is a duplicate of; its activities and links move there |
request.note? | { body: string; tier?: "internal" | "restricted" | "self"; } | Description A note recorded with the action, as an activity of kind note |
request.note.body? | string | - |
request.note.tier? | "internal" | "restricted" | "self" | |
requestOptions? | RequestOptions | - |
Returns#
Promise<{
activity: {
attachmentAssetIds: string[];
authorId: string | null;
authorKind: "user" | "ai" | "system" | "customer" | "party";
body: string | null;
caseId: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api"
| null;
createdAt: string;
customerId: string | null;
direction: "inbound" | "outbound" | null;
id: string;
kind: | "chat"
| "system"
| "email_in"
| "email_out"
| "call"
| "visit"
| "ai_conversation"
| "action"
| "note";
metadata: {
[key: string]: unknown;
};
occurredAt: string;
owningAccountId: string | null;
sensitive: boolean;
tier: "internal" | "restricted" | "self";
};
case: {
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
};
result: {
[key: string]: unknown;
};
}>
Operation Id#
takeCaseAction
unlink()#
unlink: (caseId: string, linkId: string, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;Unlink a case Remove a link from a case. The case keeps the account it belongs to.
Parameters#
| Parameter | Type |
|---|---|
caseId | string |
linkId | string |
requestOptions? | RequestOptions |
Returns#
Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>
Operation Id#
unlinkCase
update()#
update: (caseId: string, request: {
category?: string | null;
contact?: {
email?: string | null;
name?: string | null;
phone?: string | null;
} & Record<string, never>;
customerId?: string | null;
expectedVersion?: number;
priority?: "low" | "normal" | "high" | "urgent";
subject?: string;
tags?: string[];
}, requestOptions?: RequestOptions) => Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>;Update a case Edit a case's subject, priority, category, tags, contact or customer. Setting the customer (a contact matched to one) moves the case's activities onto that customer's timeline. The state changes through actions (POST /cases/{caseId}/actions/{action}), not here. Send expectedVersion to refuse an edit of a case that has moved on (412 VERSION_MISMATCH).
Parameters#
| Parameter | Type | Description |
|---|---|---|
caseId | string | - |
request | { category?: string | null; contact?: { email?: string | null; name?: string | null; phone?: string | null; } & Record<string, never>; customerId?: string | null; expectedVersion?: number; priority?: "low" | "normal" | "high" | "urgent"; subject?: string; tags?: string[]; } | - |
request.category? | string | null | - |
request.contact? | { email?: string | null; name?: string | null; phone?: string | null; } & Record<string, never> | - |
request.customerId? | string | null | Description Set when a contact is matched to a customer; the case's activities move to the customer's timeline with it. |
request.expectedVersion? | number | Description The version the edit is based on; 412 VERSION_MISMATCH when the case has moved on. |
request.priority? | "low" | "normal" | "high" | "urgent" | |
request.subject? | string | - |
request.tags? | string[] | - |
requestOptions? | RequestOptions | - |
Returns#
Promise<{
assignedAt: string | null;
assigneeUserId: string | null;
availableActions: {
action: | "open"
| "refund"
| "close"
| "wait_on_customer"
| "wait_on_internal"
| "resolve"
| "reopen"
| "mark_spam"
| "resend"
| "assign"
| "claim"
| "unassign"
| "set_queue"
| "merge"
| "split"
| "reply";
label: string;
orderIds?: string[];
requiresFields: string[];
}[];
category: string | null;
channel: | "email"
| "phone"
| "sms"
| "in_person"
| "chat"
| "concierge"
| "manage"
| "box_office"
| "api";
closedAt: string | null;
contact: | {
email: string | null;
name: string | null;
phone: string | null;
}
| null;
createdAt: string;
createdBy: string | null;
customerId: string | null;
id: string;
links: {
createdAt: string;
id: string;
objectId: string;
objectType: | "order"
| "case"
| "event"
| "pass"
| "occurrence"
| "payment"
| "refund_request";
relation: "follow_up" | "about" | "merged" | "related";
}[];
number: number;
organisationId: string;
owedReply: {
breached: boolean;
dueAt: string | null;
owed: boolean;
paused: boolean;
since: string | null;
target: "first_response" | "next_response" | null;
};
owningAccountId: string | null;
presence: {
expiresAt: string;
mode: "viewing" | "replying";
since: string;
userId: string;
}[];
priority: "low" | "normal" | "high" | "urgent";
queueKey: string | null;
reopenUntil: string | null;
resolutionReason: "answered" | "refunded" | "exchanged" | "no_action" | "duplicate" | null;
resolvedAt: string | null;
resolverId: string | null;
resolverKind: "user" | "ai" | "workflow" | null;
retainUntil: string | null;
salesChannelId: string | null;
sla: {
breachedAt: string | null;
dueAt: string | null;
firstRespondedAt: string | null;
firstResponseDueAt: string | null;
nextResponseDueAt: string | null;
pausedAt: string | null;
pausedSeconds: number;
status: "none" | "running" | "paused" | "breached";
target: "first_response" | "next_response" | null;
};
state: | "new"
| "open"
| "waiting_on_customer"
| "waiting_on_internal"
| "resolved"
| "closed"
| "spam";
stateCategory: "cancelled" | "open" | "waiting" | "done";
subject: string;
tags: string[];
updatedAt: string;
version: number;
}>
Operation Id#
updateCase