Saltar al contenido
Beta

Guías SDK de TypeScript

SDK de TypeScript

Usa el cliente oficial de TypeScript para leer tus datos de Totem, paginar listas y gestionar errores de la API desde tu servidor.

El SDK oficial de TypeScript, @totemstudioai/sdk, cubre todos los endpoints de la API de solo lectura en Beta. Se ejecuta en tu servidor con Node.js 22.12 o posterior. Un administrador del equipo crea su clave en Ajustes → Desarrolladores; el acceso a la API pública está incluido desde Pro.

Instala el SDK de TypeScript

Instala el paquete de la versión publicada en el repositorio oficial de GitHub. Contiene el paquete ya compilado, así que no necesita compilar nada y funciona con los scripts de instalación desactivados. Descárgalo con su suma de comprobación, compruébalo y después instala el archivo que comprobaste:

cURL
curl -fLO https://github.com/kiketordera/totem-studio-typescript/releases/download/v0.1.0-beta.2/totemstudioai-sdk-0.1.0-beta.2.tgz
curl -fLO https://github.com/kiketordera/totem-studio-typescript/releases/download/v0.1.0-beta.2/totemstudioai-sdk-0.1.0-beta.2.tgz.sha256
shasum -a 256 -c totemstudioai-sdk-0.1.0-beta.2.tgz.sha256
npm install ./totemstudioai-sdk-0.1.0-beta.2.tgz

La suma de comprobación demuestra que la descarga está completa y sin cambios; viene de la misma página de la versión que el paquete, así que no demuestra quién lo generó. npm registra la dependencia como una ruta file: a ese paquete, así que deja el paquete en la ruta desde la que lo instalaste. También puedes instalar la etiqueta de Git con npm install github:kiketordera/totem-studio-typescript#v0.1.0-beta.2, que compila el paquete durante la instalación y por eso necesita los scripts de instalación activados.

En ambos casos el paquete se importa como @totemstudioai/sdk. Todavía no está publicado en el registro de npm, así que un paquete con ese nombre en npm no es de Totem: no le des nunca tu clave e instala el SDK solo de una de las dos formas anteriores. Guarda la clave en el almacén de secretos de tu servidor y proporciónala como TOTEM_API_KEY. No incluyas nunca este cliente ni su clave en un navegador ni en una aplicación móvil.

Haz una petición tipada

Los ejemplos de esta página son módulos ES y usan await en el nivel superior. En un proyecto CommonJS, colócalos dentro de una función async.

TypeScript
import { TotemClient } from '@totemstudioai/sdk'

const apiKey = process.env.TOTEM_API_KEY
if (!apiKey) throw new Error('Set TOTEM_API_KEY on your server')

const client = new TotemClient({ apiKey })
const integration = await client.me.get()
const teams = await client.teams.list()
console.log(integration.id, teams.data.map(team => team.id))

Si la clave lee varios equipos, elige uno con la opción team del cliente. También puedes indicar team en cada petición de las rutas que leen la colección de un equipo:

TypeScript
const team = process.env.TOTEM_TEAM_ID
if (!team) throw new Error('Set TOTEM_TEAM_ID on your server')

const client = new TotemClient({ apiKey, team })
const page = await client.leads.list({ limit: 100 })
const matching = await client.leads.search({ email: 'alex.rivera@example.com' })
console.log(page.data.length, matching.data.length)

Una ruta que lee un registro por su identificador, como client.leads.get(id), toma el equipo del identificador y no admite la opción team: compara el team del registro con el que esperas. El cliente añade Authorization y Totem-Team, codifica los filtros y devuelve objetos de respuesta tipados. Los nombres de los campos son los mismos que en el JSON de la API. Los campos con un conjunto fijo de valores están tipados de forma que un valor añadido más adelante siga compilando, porque los enums pueden crecer.

Lee todas las páginas con el SDK

Usa items para recorrer una lista sin gestionar sus cursores de página:

TypeScript
for await (const lead of client.items('leads.list', { query: { limit: 100 } })) {
  console.log(lead.id, lead.version)
}

Usa pages si necesitas el objeto completo de cada página. Se detiene cuando has_more es false; no programa futuras consultas. timeoutMs se aplica a cada página; pasa signal: AbortSignal.timeout(ms) para limitar el recorrido completo.

Lee el feed de cambios con pages o con client.sync.changes({ cursor, limit: 100 }), nunca con items: aplica cada página antes de guardar su next_cursor, también en una página vacía con has_more: false. Un cursor undefined o null empieza desde el principio. Guarda un cursor por equipo y vuelve a consultar cada 1 a 5 minutos. Usa isFeedRemoval(item) para distinguir una eliminación del estado actual de un registro, y aplica un elemento solo si su version es mayor que la que tienes. Sincroniza una copia explica las eliminaciones, las versiones y la resincronización completa; el SDK no guarda los datos ni los cursores por ti.

Errores y metadatos del SDK

TypeScript
import { TotemApiError, TotemError } from '@totemstudioai/sdk'

try {
  const response = await client.requestWithResponse('me.get')
  console.log(response.requestId, response.data.id)
} catch (error) {
  if (error instanceof TotemApiError) {
    console.error(error.status, error.code, error.action, error.param, error.requestId)
  } else if (error instanceof TotemError) {
    console.error(error.name)
  }
  throw error
}

Todos los errores que lanza el SDK por una petición que ha enviado extienden TotemError:

  • TotemApiError para un error con el que respondió la API. Incluye el estado HTTP, el code de error de la API, la action recomendada, el param que ha fallado, title, el identificador de la petición y retryAfterMs cuando se proporciona.
  • TotemProtocolError para una respuesta que el contrato no permite, como una respuesta correcta cuyo cuerpo no es JSON, una página de lista sin data o un cursor ausente o repetido durante pages() o items().
  • TotemConnectionError para un fallo de red que los reintentos no resuelven, y TotemTimeoutError para el plazo de la petición.

Las opciones o los argumentos no válidos, como un apiKey o un team vacíos, lanzan un TypeError normal antes de enviar ninguna petición, y el motivo de cancelación de tu propia signal se relanza sin cambios.

Decide según action, la agrupación de códigos de error que hace el SDK: fix_request, check_credentials, resync, wait_capture, drop_team, keep_and_retry, retry_after, backoff o contact_support. El errorCatalogue que exporta el SDK asigna a cada código documentado su acción, y el catálogo de errores explica cada código; trata un código desconocido según su estado HTTP. En el feed de cambios, action === 'resync' (resync_required o sync_cursor_expired) significa una resincronización completa; capture_not_ready significa conservar tus datos y tu cursor y volver a intentarlo más tarde; team_not_accessible significa volver a leer GET /v1/teams y descartar el equipo solo si ya no aparece. Sin el SDK, decide según el code de la respuesta. Guarda el identificador de la petición para soporte.

El cliente hace un número limitado de reintentos, con esperas aleatorizadas, ante fallos temporales y respeta Retry-After. Si la espera supera maxRetryDelayMs, o el tiempo que queda hasta el plazo de la petición, devuelve el error a tu código al momento en lugar de acortarla. Usa timeoutMs, maxRetries, maxRetryDelayMs y signal para ajustar el plazo de tu proceso. Los errores de autenticación, autorización o petición inválida necesitan una corrección, no un bucle de reintentos.

Verifica tu integración con el SDK

Inyecta una implementación de fetch con new TotemClient({ apiKey, fetch }) para hacer pruebas HTTP deterministas. Prueba por separado cómo tu receptor gestiona las versiones, las eliminaciones y la persistencia del cursor, y después haz peticiones reales con tu propia clave. Pruebas y puesta en producción enumera el comportamiento que debes verificar; una respuesta simulada no demuestra que funcionen una clave o un servidor reales.

Versión de la API 1.0a