npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sceneinfrastructure/storefront-api

v0.7.0

Published

Typed SDK and oRPC contract for the Mesh public Storefront API

Readme

@sceneinfrastructure/storefront-api

Typed SDK and oRPC contract for Mesh public Storefront API integrations.

pnpm add @sceneinfrastructure/storefront-api @sceneinfrastructure/public-types @orpc/client @orpc/contract @orpc/openapi-client zod
import { createStorefrontApiClient } from '@sceneinfrastructure/storefront-api/client'

const storefront = createStorefrontApiClient({
  baseUrl: process.env.MESH_PUBLIC_API_BASE_URL!,
  apiKey: process.env.MESH_SCENE_API_KEY!,
})

const { events } = await storefront.listEvents({
  sceneId: process.env.MESH_SCENE_ID!,
})

listEvents can also narrow the scene event feed server-side:

const { events } = await storefront.listEvents({
  sceneId: process.env.MESH_SCENE_ID!,
  status: 'scheduled',
  eventIds: ['evt_example'],
  eventType: 'RSVP',
  collaboratorGroupIds: ['scg_partner_team'],
})

eventIds and collaboratorGroupIds match any ID in the provided list, and all provided filters are combined. Collaborator group filtering is scoped to the requested sceneId.

The optional @sceneinfrastructure/storefront-api/react-query subpath uses @orpc/tanstack-query. Install it only if you want oRPC's TanStack Query helpers; otherwise wrap the typed client with your own useQuery calls.

What the public read endpoints expose

The public read endpoints only return events that are state = 'published', visibility = 'public', and not archived. Drafts, publishing rows, archived rows, and private rows are filtered out at the read layer.

Each event also carries:

  • acceptingRegistration: boolean — when false, every tier is reported as isActive: false.
  • display: { headline, dateLabel, shortDateLabel, venueLabel, imageAlt, accentLabel, numberLabel } — storefront-ready labels for cards, event detail headers, and checkout summaries.
  • location: { name, address, formattedAddress, kind, url } | null — derived from the V2 event.location JSON when present, with a fallback to V1 event.address.

Each tier carries:

  • display: { group, sortOrder, subtitle, visible, defaultSelected } — admin-defined ticket group label and ordering, a storefront subtitle, visibility, and a default selection hint so storefronts don't need to infer groups or first-choice tiers from labels.
  • price.formatted and allInclusivePrice.formatted — canonical USD display labels alongside numeric USD and integer USDC values.
  • quantity: { label, remainingNumber, ... } — storefront-ready inventory labels and safe numeric remaining quantities when available.
  • relationships: { requiredParentTierId } — when non-null, the tier is an add-on that must be purchased with an eligible primary ticket. Checkout accepts the exact referenced parent tier, except for Mesh's internal "any primary" add-on group where any primary event ticket can satisfy the relationship.
  • restrictions: { maxQuantityPerOrder, requiresAccessCode } — same surface as before.
  • schedule: { startTime, endTime, timezone } and validityWindow: { validFrom, validUntil, isActive } — public sale and ticket-validity windows for storefront presentation.

POST /v1/cart-url accepts multi-item carts and returns a checkout URL that encodes every item as repeated saleKeyId/quantity query parameters. The endpoint:

  • Aggregates duplicate saleKeyId lines server-side before validation, so splitting an order into multiple identical line items cannot bypass availability or add-on parent-quantity checks.
  • Sorts primary tiers before add-ons in the emitted URL so the hosted storefront's preselect always sees the parent before its children regardless of input ordering.

It enforces these rules server-side:

  • 409 Conflict when an add-on tier is included without an eligible primary ticket in the same cart (requiredParentTierId not satisfied by the exact parent tier or Mesh's internal "any primary" add-on group).
  • 409 Conflict when an add-on tier's quantity exceeds the eligible primary ticket quantity in the same cart.
  • 409 Conflict when a tier is sold out or requested quantity exceeds remaining availability (after duplicate-line aggregation).
  • 422 Validation Failed when the cart includes more than one distinct primary ticket tier. The current hosted storefront state model supports only one primary tier (with optional add-ons). Pass a single primary tier per cart URL.
  • 422 Validation Failed when the sum of primary ticket quantities exceeds event.ticketOrderLimit (treated as "no limit" when non-positive). Add-on quantities ride along with their parent and are not counted against the per-event order limit (they are independently capped at the parent quantity).

Reserved and RSVP order workflow

Reserved orders are a server-side checkout alternative for partners that collect or attest payment outside Mesh, such as Blackbird Pay. Use them from a trusted backend only; the scene API key and Idempotency-Key must not be sent from browser code.

The flow is:

  1. POST /v1/events/{eventId}/orders with Idempotency-Key to reserve inventory and receive an order in payment_pending status.
  2. Complete the external payment with the provider.
  3. POST /v1/orders/{orderId}/confirm with the external payment attestation.
  4. GET /v1/orders/{orderId} to poll or reconcile the canonical order status and issued ticket.

Create-order requests include purchaser contact, payment handoff details, an optional reservation TTL, and either the legacy single-item shape (slotId/quantity) or a multi-item items array. Each items entry uses the public slot identifier returned by Mesh plus its quantity. Multi-item reserved orders reserve, price, and fulfill every line item atomically; add-on tiers must include an eligible primary ticket in the same order and cannot exceed the eligible primary quantity. Create, confirm, and get responses include items so partners can reconcile the exact session/add-on allocation. They also include cart.breakdown, with subtotal, itemized fees (processingFee, protocolFee, vendorFee, referrerFee, total), itemized taxes (salesTax, total), and final total in USD minor units. Confirm requests currently support the blackbird_pay external provider and require amount, currency, external payment ID, paid timestamp, and paid status. Confirmed orders return the ticket details when fulfillment succeeds; orders may also remain fulfillment_pending, fail, expire, or be fetched later for reconciliation.

For RSVP events with no payment component, use the same create-order endpoint with type: "rsvp" and omit payment. Mesh validates that the event is an RSVP event and that the selected slots price to zero, then immediately starts ticket fulfillment. The create response is the canonical order shape with type: "rsvp" and a status such as fulfillment_pending or confirmed; poll GET /v1/orders/{orderId} when fulfillment is pending.

Always send a stable Idempotency-Key for create-order retries. Reusing the same key for the same logical order is safe; generating a new key for every retry can create duplicate reservations.

Named request/response types

@sceneinfrastructure/storefront-api exports named TypeScript aliases for every endpoint so consumers don't need to derive output types from the client or z.infer on schemas:

import type {
  ListEventsOutput,
  ListEventTiersOutput,
  ListEventPricesOutput,
  CreateCartUrlInput,
  CreateCartUrlOutput,
  CreateOrderInput,
  CreateOrderOutput,
  ConfirmOrderInput,
  ConfirmOrderOutput,
  GetOrderOutput,
  StorefrontApiEvent,
  StorefrontApiEventDisplay,
  StorefrontApiEventLocation,
  StorefrontApiEventType,
  StorefrontApiPrice,
  StorefrontApiTier,
  StorefrontApiTierDisplay,
  StorefrontApiTierRelationships,
  StorefrontApiTierRestriction,
  StorefrontApiOrderItem,
  StorefrontApiOrderSlot,
  StorefrontApiOrderStatus,
  StorefrontApiOrderTicket,
} from '@sceneinfrastructure/storefront-api'

The schemas (listEventsOutputSchema, publicApiTierSchema, etc.) and typed client (@sceneinfrastructure/storefront-api/client) remain available unchanged.

Agent skill

If you are using an AI coding agent, install the Mesh Storefront skill for API/SDK setup guidance, Next.js server-only usage patterns, required env vars, and OpenAPI fallback examples:

npx skills add https://api.sceneconstruction.xyz

The installer discovers the skill from https://api.sceneconstruction.xyz/.well-known/agent-skills/index.json.