evento-sdk
v0.1.2
Published
Display your Evento events and sell tickets on your own website or app.
Maintainers
Readme
evento-sdk
Display your Evento events and sell tickets on your own website or app.
evento-sdk is a small JavaScript / TypeScript library that pulls your published
Evento events and ticket prices into your own design, then hands checkout to
Evento's hosted widget — so your audience can browse and buy without leaving your page.
- Your design, your layout. Fetch events and ticket types as data and render them however you want.
- Sell in one click.
getWidgetUrl()returns the Evento checkout for an event; embed it and buyers complete their purchase securely on Evento. - No API key. It only reads your public event data, so it's safe to ship in a browser or mobile app.
- Tiny and dependency-free. Native
fetch, ESM + CJS, full TypeScript types. - Runs anywhere. Browsers, Node 18+, React, Next.js, and React Native.
Install
npm install evento-sdk
# pnpm add evento-sdk · yarn add evento-sdk · bun add evento-sdkQuick start
import { createEventoClient } from "evento-sdk";
// Defaults to the hosted Evento API.
const evento = createEventoClient();
// 1. Load your organizer's events.
const { data: events } = await evento.listOrganizerEvents("YOUR_ORGANIZER_ID");
// 2. Show them your way.
for (const event of events) {
const from = evento.getFromPrice(event); // { amount, currency } | null
const tickets = evento.getTickets(event); // ticket types
console.log(event.title, from, tickets.length);
}
// 3. Sell: embed Evento's checkout for an event.
const widgetUrl = evento.getWidgetUrl(events[0].id, {
primaryColor: "#7b5db8",
continueButtonText: "Get Tickets",
});Display your events
// An organizer's published events (paginated)
const { data, meta } = await evento.listOrganizerEvents(organizerId, {
page: 1,
per_page: 25,
});
// A single event, including its ticket categories and prices
const event = await evento.getEvent(eventId);
// Ticket types and the "from" price
const tickets = evento.getTickets(event); // Product[]
const from = evento.getFromPrice(event); // { amount, currency } | null
// Iterate every page
for await (const event of evento.paginateEvents()) {
console.log(event.title);
}Tickets are embedded in each event (product_categories[].products[]), so there's
no separate tickets call.
Checkout with the Evento widget
The SDK doesn't touch payments — it returns the URL of Evento's hosted checkout widget for an event. Embed that URL and the buyer checks out on Evento's secure page.
const url = evento.getWidgetUrl(event.id, {
primaryColor: "#7b5db8",
primaryTextColor: "#000000",
continueButtonText: "Get Tickets",
locale: "en",
iframeId: `widget-${event.id}`,
});Vanilla / any framework
<iframe
id="evento-widget"
src="https://theeventoapp.com/widget/EVENT_ID?primaryColor=%237b5db8&iframeId=evento-widget"
style="width: 100%; border: 0"
sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation allow-downloads"
></iframe>The widget posts its height so the iframe can resize automatically:
import { isWidgetResizeMessage } from "evento-sdk";
const iframe = document.getElementById("evento-widget") as HTMLIFrameElement;
const iframeId = "evento-widget";
window.addEventListener("message", (message) => {
if (isWidgetResizeMessage(message.data, iframeId)) {
iframe.style.height = `${message.data.height}px`;
}
});React / Next.js
import { useEffect, useState } from "react";
import { createEventoClient, isWidgetResizeMessage, type Event } from "evento-sdk";
const evento = createEventoClient();
export function Events({ organizerId }: { organizerId: string }) {
const [events, setEvents] = useState<Event[]>([]);
useEffect(() => {
evento.listOrganizerEvents(organizerId).then((res) => setEvents(res.data));
}, [organizerId]);
return (
<div>
{events.map((event) => (
<article key={event.id}>
<h3>{event.title}</h3>
<p>from {evento.getFromPrice(event)?.amount}</p>
<Widget eventId={event.id} />
</article>
))}
</div>
);
}
function Widget({ eventId }: { eventId: string }) {
const iframeId = `evento-widget-${eventId}`;
useEffect(() => {
const onMessage = (message: MessageEvent) => {
if (isWidgetResizeMessage(message.data, iframeId)) {
const el = document.getElementById(iframeId) as HTMLIFrameElement | null;
if (el) el.style.height = `${message.data.height}px`;
}
};
window.addEventListener("message", onMessage);
return () => window.removeEventListener("message", onMessage);
}, [iframeId]);
return (
<iframe id={iframeId} src={evento.getWidgetUrl(eventId, { iframeId })} style={{ width: "100%", border: 0 }} />
);
}React Native
import { Linking } from "react-native";
import { WebView } from "react-native-webview";
import { createEventoClient } from "evento-sdk";
const evento = createEventoClient();
// Embed the checkout:
<WebView source={{ uri: evento.getWidgetUrl(event.id) }} />;
// Or open it in the system browser:
Linking.openURL(evento.getWidgetUrl(event.id));API
createEventoClient(options?)
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| apiBaseUrl | string | https://theeventoapp.com/api | API base URL, including /api. |
| widgetBaseUrl | string | derived from apiBaseUrl | Origin serving the checkout widget. |
| fetch | FetchLike | global fetch | Custom fetch (tests, proxies, instrumentation). |
| headers | Record<string, string> | {} | Extra headers on every request. |
| timeoutMs | number | — | Abort requests after this many milliseconds. |
Methods
| Method | Returns | Description |
| --- | --- | --- |
| listEvents(params?) | PaginatedResponse<Event> | Published, upcoming events across Evento. |
| getEvent(eventId, { promoCode? }) | Event | One event, including ticket categories. |
| listOrganizerEvents(organizerId, params?) | PaginatedResponse<Event> | An organizer's published events. |
| getOrganizer(organizerId) | Organizer | An organizer's public profile. |
| getOrganizerByUsername(username) | Organizer | An organizer's public profile. |
| getEventByOrganizerUsernameAndSlug(username, slug) | Event | One event by username + slug. |
| getTickets(event) | Product[] | Flatten an event's ticket types. |
| getFromPrice(event) | Money \| null | Lowest available ticket price. |
| getWidgetUrl(eventId, options?) | string | Checkout widget URL to embed. |
| paginateEvents(params?) | AsyncGenerator<Event> | Iterate every event across all pages. |
| request(path, options?) | unknown | Call any public endpoint directly. |
Pagination and sorting params: page, per_page (max 50), query, sort_by,
sort_direction.
Errors
Failed requests throw EventoApiError with status, message, errors, and body.
import { EventoApiError } from "evento-sdk";
try {
await evento.getEvent(eventId);
} catch (error) {
if (error instanceof EventoApiError && error.isNotFound) {
// event is not published or does not exist
}
}Good to know
- Only published events are returned. Events still in draft aren't visible.
- Responses are
{ data }, and list calls are{ data, meta }. - No API key is needed, and you should never put an Evento account API key in a browser or mobile app. This SDK doesn't use one.
- Want a different layout, or a section for costumes, sponsors, and photos next to your events? The SDK gives you the data — style it however you like.
Status
0.1.0 — initial release. See CHANGELOG.md.
Development
See CONTRIBUTING.md. In short: npm test and npm run build.
License
MIT — see LICENSE. Security policy: SECURITY.md.
