Skip to content

TypeScript SDK

The teiwah package is a typed server-side client for the Teiwah API. It supports Node.js 20+, Bun 1+, and Deno with npm package support.

Terminal window
npm install teiwah

Copy the session API key from the Teiwah dashboard and pass it to the client:

import { Teiwah } from "teiwah";
const teiwah = new Teiwah({
apiKey: process.env.TEIWAH_API_KEY!,
});

The SDK exports the InboundMessage webhook payload type. Pass its chatId back unchanged when replying:

import { Teiwah, type InboundMessage } from "teiwah";
const teiwah = new Teiwah({
apiKey: process.env.TEIWAH_API_KEY!,
});
export async function handleMessage(message: InboundMessage) {
switch (true) {
case "text" in message:
return teiwah.sendText({
chatId: message.chatId,
text: `Received: ${message.text}`,
});
case "media" in message:
// Handle image, audio, video, document, or PTT media.
return;
default:
// Handle an unsupported message shape.
}
}

In group messages, chatId identifies the group and participant identifies the individual sender. contact is sender metadata, not a reply target.

Use the helper that matches the outbound message type:

await teiwah.sendText({
chatId,
text: "Hello from Teiwah",
});
await teiwah.sendImage({
chatId,
url: "https://example.com/photo.jpg",
caption: "Photo",
});
await teiwah.sendPtt({
chatId,
base64: voiceNoteBase64,
});

Available methods:

  • sendText
  • sendImage
  • sendPtt
  • sendAudio
  • sendVideo
  • sendDocument
  • sendMessage for a dynamic text or media request
  • showTyping
  • markMessageRead
  • downloadMedia

Media helpers accept exactly one of url or base64. The decoded base64 size limit is 16 MB. mimeType and filename are optional overrides when Teiwah cannot infer them.

Inbound PTT voice notes always contain media.base64 for immediate processing. If Teiwah cannot download and decrypt a PTT message, it skips that webhook rather than delivering a payload without the bytes. Other inbound media is downloaded through media.url.

Use the native inbound message ID:

await teiwah.sendText({
chatId: message.chatId,
text: "Got it",
quoteMessageId: message.id,
});

API failures are thrown as typed errors. The SDK does not retry requests automatically because a failed send can have an ambiguous delivery result and an automatic retry could create a duplicate message.

See the errors and limits reference for API status codes.