SDKs: Backend and browser TypeScript SDK usage.
---
# SDK para navegador
> Cliente frontend para eventos públicos y Stripe Checkout.
@wodira/browserFrontend · publishable keys · Stripe Checkout ## Instalación [Sección titulada «Instalación»](#instalación)
```bash
pnpm add @wodira/browser
```
## Uso básico [Sección titulada «Uso básico»](#uso-básico)
```ts
import { createWodiraBrowserClient } from '@wodira/browser';
const wodira = createWodiraBrowserClient({ publishableKey: 'wpk_live_...' });
const session = await wodira.createRegistrationCheckoutSession({
eventId: 'event_...',
categoryId: 'cat_...',
purchaserEmail: 'buyer@example.com',
purchaserName: 'Buyer Name',
teamName: 'Team Name',
termsAccepted: true,
waiversAccepted: { waiver_123: true },
idempotencyKey: crypto.randomUUID(),
successUrl: 'https://organizador.com/gracias',
cancelUrl: 'https://organizador.com/cancelado',
athletes: [
{
fullname: 'Ada Lovelace',
idNumber: '12345678A',
email: 'ada@example.com',
phone: '+34600000000',
gender: 'FEMALE',
birthDate: '1990-01-01',
},
],
});
if (session.sessionUrl) window.location.href = session.sessionUrl;
```
## Métodos [Sección titulada «Métodos»](#métodos) [`searchEvents`Listar eventos públicos](#searchevents)[`getEvent`Leer detalle público de evento](#getevent)[`getPricingCards`Mostrar categorías y precios](#getpricingcards)[`getRegistrationSummary`Previsualizar total del checkout](#getregistrationsummary)[`createRegistrationCheckoutSession`Crear Stripe Checkout Session](#createregistrationcheckoutsession) ### `searchEvents` [Sección titulada «searchEvents»](#searchevents) Lista eventos publicados disponibles para la publishable key. Úsalo en webs de organizadores para mostrar carreras, competiciones o eventos vendibles.
```ts
const events = await wodira.searchEvents({ search: 'Madrid', limit: 20 });
```
* **Endpoint:** [`POST /external/v1/browser/events/search`](/api/endpoints/#buscar-eventos) * **Credencial:** `wpk_live_...` con `Origin` permitido ### `getEvent` [Sección titulada «getEvent»](#getevent) Obtiene el detalle público de un evento, incluyendo categorías, campos públicos, waivers y suplementos activos.
```ts
const event = await wodira.getEvent('event_123');
```
* **Endpoint:** [`GET /external/v1/browser/events/:eventId`](/api/endpoints/#detalle-de-evento) * **Credencial:** `wpk_live_...` con `Origin` permitido ### `getPricingCards` [Sección titulada «getPricingCards»](#getpricingcards) Devuelve cards de precio públicas para pintar categorías, cupos, precio activo y tiers antes de iniciar el formulario.
```ts
const pricing = await wodira.getPricingCards('event_123');
```
* **Endpoint:** [`GET /external/v1/browser/events/:eventId/pricing-cards`](/api/endpoints/#pricing-cards) * **Credencial:** `wpk_live_...` con `Origin` permitido ### `getRegistrationSummary` [Sección titulada «getRegistrationSummary»](#getregistrationsummary) Calcula un resumen del checkout antes de redirigir a Stripe: precio base, suplementos seleccionados, cupón aplicado, total y moneda.
```ts
const summary = await wodira.getRegistrationSummary({
categoryId: 'cat_123',
purchaserEmail: 'buyer@example.com',
selectedSupplementIds: ['supp_123'],
promocode: 'EARLY',
});
```
* **Endpoint:** [`POST /external/v1/browser/checkout/registration/summary`](/api/endpoints/#checkout-summary) * **Uso recomendado:** resumen reactivo en el formulario antes de pagar ### `createRegistrationCheckoutSession` [Sección titulada «createRegistrationCheckoutSession»](#createregistrationcheckoutsession) Crea una Stripe Checkout Session para inscripciones públicas. La web externa debe redirigir a `sessionUrl`; no se redirige a WODira para pagar.
```ts
const session = await wodira.createRegistrationCheckoutSession({
eventId: 'event_123',
categoryId: 'cat_123',
purchaserEmail: 'buyer@example.com',
purchaserName: 'Buyer Name',
termsAccepted: true,
waiversAccepted: { waiver_123: true },
idempotencyKey: crypto.randomUUID(),
successUrl: 'https://organizador.com/gracias',
cancelUrl: 'https://organizador.com/cancelado',
athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }],
});
window.location.href = session.sessionUrl;
```
* **Endpoint:** [`POST /external/v1/browser/checkout/registration/session`](/api/endpoints/#checkout-session) * **Seguridad:** `successUrl` y `cancelUrl` deben pertenecer a un origin permitido * **Alternativa UI:** [``](/ui-components/checkout-flow/) si prefieres Web Components completos
---
# Browser SDK
> Frontend client for public events and Stripe Checkout.
## Install [Section titled “Install”](#install)
```bash
pnpm add @wodira/browser
```
## Quickstart [Section titled “Quickstart”](#quickstart)
```ts
import { createWodiraBrowserClient } from '@wodira/browser';
const wodira = createWodiraBrowserClient({ publishableKey: 'wpk_live_...' });
const session = await wodira.createRegistrationCheckoutSession({
eventId: 'event_...',
categoryId: 'cat_...',
purchaserEmail: 'buyer@example.com',
purchaserName: 'Buyer Name',
teamName: 'Team Name',
termsAccepted: true,
waiversAccepted: { waiver_123: true },
idempotencyKey: crypto.randomUUID(),
successUrl: 'https://organizer.com/success',
cancelUrl: 'https://organizer.com/cancel',
athletes: [
{
fullname: 'Ada Lovelace',
idNumber: '12345678A',
email: 'ada@example.com',
phone: '+34600000000',
gender: 'FEMALE',
birthDate: '1990-01-01',
},
],
});
if (session.sessionUrl) window.location.href = session.sessionUrl;
```
## Methods [Section titled “Methods”](#methods) [`searchEvents`List public events](#searchevents)[`getEvent`Read public event details](#getevent)[`getPricingCards`Render categories and prices](#getpricingcards)[`getRegistrationSummary`Preview checkout total](#getregistrationsummary)[`createRegistrationCheckoutSession`Create Stripe Checkout Session](#createregistrationcheckoutsession) ### `searchEvents` [Section titled “searchEvents”](#searchevents) Lists published events available to the publishable key. Use it on organizer websites to render races, competitions, or sellable events.
```ts
const events = await wodira.searchEvents({ search: 'Madrid', limit: 20 });
```
* **Endpoint:** [`POST /external/v1/browser/events/search`](/en/api/endpoints/#search-events) * **Credential:** `wpk_live_...` with an allowed `Origin` ### `getEvent` [Section titled “getEvent”](#getevent) Reads public event details, including categories, public fields, waivers, and active supplements.
```ts
const event = await wodira.getEvent('event_123');
```
* **Endpoint:** [`GET /external/v1/browser/events/:eventId`](/en/api/endpoints/#event-details) * **Credential:** `wpk_live_...` with an allowed `Origin` ### `getPricingCards` [Section titled “getPricingCards”](#getpricingcards) Returns public pricing cards for rendering categories, quotas, active prices, and tiers before showing the form.
```ts
const pricing = await wodira.getPricingCards('event_123');
```
* **Endpoint:** [`GET /external/v1/browser/events/:eventId/pricing-cards`](/en/api/endpoints/#pricing-cards) * **Credential:** `wpk_live_...` with an allowed `Origin` ### `getRegistrationSummary` [Section titled “getRegistrationSummary”](#getregistrationsummary) Calculates a checkout summary before redirecting to Stripe: base price, selected supplements, applied coupon, total, and currency.
```ts
const summary = await wodira.getRegistrationSummary({
categoryId: 'cat_123',
purchaserEmail: 'buyer@example.com',
selectedSupplementIds: ['supp_123'],
promocode: 'EARLY',
});
```
* **Endpoint:** [`POST /external/v1/browser/checkout/registration/summary`](/en/api/endpoints/#checkout-summary) * **Recommended use:** reactive summary in the registration form before payment ### `createRegistrationCheckoutSession` [Section titled “createRegistrationCheckoutSession”](#createregistrationcheckoutsession) Creates a Stripe Checkout Session for public registrations. The external website should redirect to `sessionUrl`; users do not go to WODira to pay.
```ts
const session = await wodira.createRegistrationCheckoutSession({
eventId: 'event_123',
categoryId: 'cat_123',
purchaserEmail: 'buyer@example.com',
purchaserName: 'Buyer Name',
termsAccepted: true,
waiversAccepted: { waiver_123: true },
idempotencyKey: crypto.randomUUID(),
successUrl: 'https://organizer.com/success',
cancelUrl: 'https://organizer.com/cancel',
athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }],
});
window.location.href = session.sessionUrl;
```
* **Endpoint:** [`POST /external/v1/browser/checkout/registration/session`](/en/api/endpoints/#checkout-session) * **Security:** `successUrl` and `cancelUrl` must belong to an allowed origin * **UI alternative:** [``](/en/ui-components/checkout-flow/) if you prefer complete Web Components
---
# Backend SDK
> Server-to-server client for the Organizer API.
## Install [Section titled “Install”](#install)
```bash
pnpm add @wodira/sdk
```
## Quickstart [Section titled “Quickstart”](#quickstart)
```ts
import { createWodiraClient } from '@wodira/sdk';
const wodira = createWodiraClient({
apiKey: process.env.WODIRA_API_KEY!,
});
const events = await wodira.searchEvents({ status: 'PUBLISHED', limit: 20 });
const pricing = await wodira.getPricingCards(events.data[0].id);
```
## Methods [Section titled “Methods”](#methods) [`searchEvents`Search organizer events](#searchevents)[`getEvent`Read full event details](#getevent)[`getPricingCards`Read categories, quotas, and prices](#getpricingcards)[`createRegistration`Create server-to-server registration](#createregistration)[`searchRegistrations`Search registrations/tickets](#searchregistrations)[`updateRegistration`Update a registration](#updateregistration)[`deleteRegistration`Cancel/delete a registration](#deleteregistration) ### `searchEvents` [Section titled “searchEvents”](#searchevents) Searches events for the authenticated organizer. Use it to sync catalogs, show internal listings, or find an `eventId` before reading pricing or registrations.
```ts
const events = await wodira.searchEvents({
search: 'Madrid',
status: 'PUBLISHED',
limit: 20,
offset: 0,
});
```
* **Endpoint:** [`POST /external/v1/organizer/events/search`](/en/api/endpoints/#search-events) * **Required scope:** `events:read` ### `getEvent` [Section titled “getEvent”](#getevent) Reads full event details, including categories, form fields, waivers, sponsors, and active supplements.
```ts
const event = await wodira.getEvent('event_123');
```
* **Endpoint:** [`GET /external/v1/organizer/events/:eventId`](/en/api/endpoints/#event-details) * **Required scope:** `events:read` ### `getPricingCards` [Section titled “getPricingCards”](#getpricingcards) Returns sellable event categories with quota, registered count, base price, active price, and tiers. Use it before creating a registration.
```ts
const pricing = await wodira.getPricingCards('event_123');
const firstCategory = pricing.cards[0];
```
* **Endpoint:** [`GET /external/v1/organizer/events/:eventId/pricing-cards`](/en/api/endpoints/#pricing-cards) * **Required scope:** `pricing:read` ### `createRegistration` [Section titled “createRegistration”](#createregistration) Creates a registration from a trusted backend using a secret key. Do not use this method in the browser; for public checkout use [`createRegistrationCheckoutSession`](/en/sdks/browser-sdk/#createregistrationcheckoutsession) from `@wodira/browser`.
```ts
const order = await wodira.createRegistration({
eventId: 'event_123',
categoryId: 'cat_123',
purchaserEmail: 'buyer@example.com',
purchaserName: 'Buyer Name',
termsAccepted: true,
athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }],
});
```
* **Endpoint:** [`POST /external/v1/organizer/registrations`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:write` ### `searchRegistrations` [Section titled “searchRegistrations”](#searchregistrations) Searches registrations/tickets for reconciliation, support, or syncing with external systems.
```ts
const registrations = await wodira.searchRegistrations({
eventId: 'event_123',
search: 'ada@example.com',
limit: 50,
});
```
* **Endpoint:** [`POST /external/v1/organizer/registrations/search`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:read` ### `updateRegistration` [Section titled “updateRegistration”](#updateregistration) Updates an existing registration from a backend when the integrator owns support or edit flows.
```ts
const ticket = await wodira.updateRegistration('ticket_123', {
purchaserName: 'Ada L.',
});
```
* **Endpoint:** [`PATCH /external/v1/organizer/registrations/:ticketId`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:write` ### `deleteRegistration` [Section titled “deleteRegistration”](#deleteregistration) Cancels or deletes a registration from a backend according to WODira operational rules.
```ts
await wodira.deleteRegistration('ticket_123');
```
* **Endpoint:** [`DELETE /external/v1/organizer/registrations/:ticketId`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:write`
---
# SDK overview
> Differences between the backend SDK and browser SDK.
WODira offers two TypeScript SDKs with the same mental model as Stripe: a secure server library and a browser-ready client. [`@wodira/sdk`Secret keys, scopes, and server-to-server operations.](/en/sdks/backend-sdk/)[`@wodira/browser`Publishable keys, Origin allowlist, and Stripe Checkout.](/en/sdks/browser-sdk/) | Package | Runtime | Credential | Reference | | ----------------- | ---------------- | -------------- | ------------------------------------------------ | | `@wodira/sdk` | Backend/server | `wd_live_...` | [Backend methods](/en/sdks/backend-sdk/#methods) | | `@wodira/browser` | Browser/frontend | `wpk_live_...` | [Browser methods](/en/sdks/browser-sdk/#methods) | ## Quick method map [Section titled “Quick method map”](#quick-method-map) | I need to… | Recommended method | | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | List public events on a website | [`@wodira/browser.searchEvents`](/en/sdks/browser-sdk/#searchevents) | | Read public event details | [`@wodira/browser.getEvent`](/en/sdks/browser-sdk/#getevent) | | Render categories and prices | [`@wodira/browser.getPricingCards`](/en/sdks/browser-sdk/#getpricingcards) | | Preview the checkout total before payment | [`@wodira/browser.getRegistrationSummary`](/en/sdks/browser-sdk/#getregistrationsummary) | | Create a Stripe Checkout Session | [`@wodira/browser.createRegistrationCheckoutSession`](/en/sdks/browser-sdk/#createregistrationcheckoutsession) | | Sync events from a backend | [`@wodira/sdk.searchEvents`](/en/sdks/backend-sdk/#searchevents) | | Create or manage registrations from a backend | [`@wodira/sdk.createRegistration`](/en/sdks/backend-sdk/#createregistration) | | Search/update/cancel tickets from a backend | [`@wodira/sdk.searchRegistrations`](/en/sdks/backend-sdk/#searchregistrations) | The backend SDK throws if it detects browser execution. The browser SDK does not accept secret keys.
---
# SDK para backend
> Cliente server-to-server para Organizer API.
@wodira/sdkServer-to-server · secret keys · scopes ## Instalación [Sección titulada «Instalación»](#instalación)
```bash
pnpm add @wodira/sdk
```
## Uso básico [Sección titulada «Uso básico»](#uso-básico)
```ts
import { createWodiraClient } from '@wodira/sdk';
const wodira = createWodiraClient({
apiKey: process.env.WODIRA_API_KEY!,
});
const events = await wodira.searchEvents({ status: 'PUBLISHED', limit: 20 });
const pricing = await wodira.getPricingCards(events.data[0].id);
```
## Métodos [Sección titulada «Métodos»](#métodos) [`searchEvents`Buscar eventos del organizador](#searchevents)[`getEvent`Leer detalle completo de evento](#getevent)[`getPricingCards`Consultar categorías, cupos y precios](#getpricingcards)[`createRegistration`Crear inscripción server-to-server](#createregistration)[`searchRegistrations`Buscar inscripciones/tickets](#searchregistrations)[`updateRegistration`Actualizar una inscripción](#updateregistration)[`deleteRegistration`Cancelar/eliminar inscripción](#deleteregistration) ### `searchEvents` [Sección titulada «searchEvents»](#searchevents) Busca eventos del organizador autenticado. Úsalo para sincronizar catálogos, mostrar listados internos o localizar el `eventId` antes de consultar pricing o inscripciones.
```ts
const events = await wodira.searchEvents({
search: 'Madrid',
status: 'PUBLISHED',
limit: 20,
offset: 0,
});
```
* **Endpoint:** [`POST /external/v1/organizer/events/search`](/api/endpoints/#buscar-eventos) * **Scope requerido:** `events:read` ### `getEvent` [Sección titulada «getEvent»](#getevent) Obtiene el detalle de un evento concreto, incluyendo categorías, campos de formulario, waivers, sponsors y suplementos activos.
```ts
const event = await wodira.getEvent('event_123');
```
* **Endpoint:** [`GET /external/v1/organizer/events/:eventId`](/api/endpoints/#detalle-de-evento) * **Scope requerido:** `events:read` ### `getPricingCards` [Sección titulada «getPricingCards»](#getpricingcards) Devuelve las categorías vendibles de un evento con cupo, inscritos, precio base, precio activo y tiers. Es el método recomendado antes de crear una inscripción.
```ts
const pricing = await wodira.getPricingCards('event_123');
const firstCategory = pricing.cards[0];
```
* **Endpoint:** [`GET /external/v1/organizer/events/:eventId/pricing-cards`](/api/endpoints/#pricing-cards) * **Scope requerido:** `pricing:read` ### `createRegistration` [Sección titulada «createRegistration»](#createregistration) Crea una inscripción desde un backend de confianza usando secret key. No uses este método desde navegador; para checkout público usa [`createRegistrationCheckoutSession`](/sdks/browser-sdk/#createregistrationcheckoutsession) en `@wodira/browser`.
```ts
const order = await wodira.createRegistration({
eventId: 'event_123',
categoryId: 'cat_123',
purchaserEmail: 'buyer@example.com',
purchaserName: 'Buyer Name',
termsAccepted: true,
athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }],
});
```
* **Endpoint:** [`POST /external/v1/organizer/registrations`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:write` ### `searchRegistrations` [Sección titulada «searchRegistrations»](#searchregistrations) Busca inscripciones/tickets para conciliación, soporte o sincronización con sistemas propios.
```ts
const registrations = await wodira.searchRegistrations({
eventId: 'event_123',
search: 'ada@example.com',
limit: 50,
});
```
* **Endpoint:** [`POST /external/v1/organizer/registrations/search`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:read` ### `updateRegistration` [Sección titulada «updateRegistration»](#updateregistration) Actualiza datos de una inscripción existente desde backend cuando el integrador mantiene flujos de soporte o edición propios.
```ts
const ticket = await wodira.updateRegistration('ticket_123', {
purchaserName: 'Ada L.',
});
```
* **Endpoint:** [`PATCH /external/v1/organizer/registrations/:ticketId`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:write` ### `deleteRegistration` [Sección titulada «deleteRegistration»](#deleteregistration) Cancela o elimina una inscripción desde backend según las reglas operativas de WODira.
```ts
await wodira.deleteRegistration('ticket_123');
```
* **Endpoint:** [`DELETE /external/v1/organizer/registrations/:ticketId`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:write` ## Seguridad [Sección titulada «Seguridad»](#seguridad) Guarda `wd_live_...` en variables de entorno o secret manager. Nunca la envíes al navegador.
---
# Overview de SDKs
> Diferencias entre el SDK backend y el SDK browser.
WODira ofrece dos SDKs TypeScript con el mismo modelo mental que Stripe: una librería segura para servidor y otra preparada para navegador. [`@wodira/sdk`Secret keys, scopes y operaciones server-to-server.](/sdks/backend-sdk/)[`@wodira/browser`Publishable keys, Origin allowlist y Stripe Checkout.](/sdks/browser-sdk/) | Paquete | Runtime | Credencial | Referencia | | ----------------- | ---------------- | -------------- | ------------------------------------- | | `@wodira/sdk` | Backend/server | `wd_live_...` | [Métodos backend](/sdks/backend-sdk/) | | `@wodira/browser` | Browser/frontend | `wpk_live_...` | [Métodos browser](/sdks/browser-sdk/) | ## Mapa rápido de métodos [Sección titulada «Mapa rápido de métodos»](#mapa-rápido-de-métodos) | Necesito… | Método recomendado | | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | | Listar eventos públicos en una web | [`@wodira/browser.searchEvents`](/sdks/browser-sdk/#searchevents) | | Leer detalle público de un evento | [`@wodira/browser.getEvent`](/sdks/browser-sdk/#getevent) | | Mostrar categorías y precios | [`@wodira/browser.getPricingCards`](/sdks/browser-sdk/#getpricingcards) | | Previsualizar el total antes de pagar | [`@wodira/browser.getRegistrationSummary`](/sdks/browser-sdk/#getregistrationsummary) | | Crear una Stripe Checkout Session | [`@wodira/browser.createRegistrationCheckoutSession`](/sdks/browser-sdk/#createregistrationcheckoutsession) | | Sincronizar eventos desde backend | [`@wodira/sdk.searchEvents`](/sdks/backend-sdk/#searchevents) | | Crear o gestionar inscripciones desde backend | [`@wodira/sdk.createRegistration`](/sdks/backend-sdk/#createregistration) | | Buscar/actualizar/cancelar tickets desde backend | [`@wodira/sdk.searchRegistrations`](/sdks/backend-sdk/#searchregistrations) | El SDK backend lanza error si detecta ejecución en navegador. El SDK browser no acepta secret keys.