client.chats manages direct and group chat conversations for the athlete: listing chats, sending and editing messages, and marking messages as seen. Blocking a chat mutes the other athlete in a private conversation.
| Method | What it does |
|---|---|
| ChatService.listChats | List chats (including groups) for the athlete, most recently active first |
| ChatService.listMessages | List messages in a chat |
| ChatService.sendMessage | Send a message |
| ChatService.markSeen | Mark a message as seen (update last seen message ID) |
| ChatService.getChat | One chat by id |
| ChatService.listGroups | Group chats for the athlete, in name order |
| ChatService.blockChat | Block (on = true) or unblock the other athlete in a private chat |
| ChatService.updateMessage | Edit a message's content or answer (the only fields the API updates) |
| ChatService.deleteMessage | Delete a message |
List the athlete's chats and groups, then read one chat's details and its most recent messages.
const client = new IntervalsClient({ apiKey });
const chats = await client.chats.listChats();
console.log(`${chats.length} chats`);
for (const chat of chats) {
console.log(`- ${chat.id} ${chat.type ?? 'unknown type'} ${chat.name ?? ''}`);
}
const groups = await client.chats.listGroups();
console.log(`${groups.length} group chats`);
const first = chats[0];
if (!first || first.id === undefined) {
console.log('No chats found');
} else {
const chat = await client.chats.getChat(first.id);
console.log(`Chat ${chat.id}: ${chat.name ?? chat.type ?? ''}`);
const messages = await client.chats.listMessages(first.id, { limit: 5 });
console.log(`${messages.length} most recent messages`);
for (const message of messages) {
console.log(`- ${message.created ?? ''} ${message.content ?? ''}`);
}
}
Send a message to another athlete, edit its content, then delete it. The API rejects a message to yourself with 422 Cannot send message to self, so the example reads the recipient from INTERVALS_CHAT_TO_ATHLETE_ID; that athlete receives one real message, which is edited and then deleted.
CI never runs this example; running it by hand changes the authenticated account. If the create call itself fails after the server committed it, nothing is cleaned up: search the account for Created by the SDK example (or Uploaded by the SDK example) and delete it by hand.
// maxRetries: 0 — a create that committed before a 5xx would be repeated by a retry, and only the last response's id would be cleaned up.
const client = new IntervalsClient({ apiKey, maxRetries: 0 });
const content = `Created by the SDK example ${Date.now()}`;
const edited = `${content} (edited)`;
const sent = await client.chats.sendMessage({ to_athlete_id: recipient, content, type: 'TEXT' });
// The API's response shape for chat id varies: `chat_id` is not in the vendored Message
// schema, so read it defensively from the raw response, then fall back to the new chat's
// id, then search for the message by its (unique) content if neither is present.
let chatId = (sent.message as { chat_id?: number } | undefined)?.chat_id ?? sent.new_chat?.id;
let msgId = sent.message?.id ?? sent.id;
if (typeof chatId !== 'number' || typeof msgId !== 'number') {
for (const chat of await client.chats.listChats()) {
if (typeof chat.id !== 'number') continue;
// One unreadable chat must not abandon the search: the message still needs deleting.
try {
const hit = (await client.chats.listMessages(chat.id, { limit: 20 })).find((m) => m.content === content);
if (typeof hit?.id === 'number') {
chatId = chat.id;
msgId = hit.id;
break;
}
} catch {
continue;
}
}
}
if (typeof chatId !== 'number' || typeof msgId !== 'number') {
console.log('Could not determine the chat id or message id of the sent message');
console.log(`The message is still there, with content "${content}" — delete it by hand from the Intervals.icu chat`);
} else {
console.log(`Sent message id=${msgId} in chat=${chatId}`);
try {
await client.chats.updateMessage(chatId, msgId, { content: edited });
const messages = await client.chats.listMessages(chatId, { limit: 20 });
console.log(`Edited content: ${messages.find((m) => m.id === msgId)?.content}`);
} finally {
await client.chats.deleteMessage(chatId, msgId);
console.log(`Deleted message ${msgId}`);
}
}
content and answer ( UpdateMessageDTO); the SDK's live tests restore state.to_athlete_id fails with 422 and error: "Cannot send message to self" (on IntervalsAPIError as details); pick a real recipient.