Getting started

Your first booking in seven calls.

A walkthrough that takes a brand-new tenant from zero to a confirmed Booking with lifecycle emissions firing — using nothing but curl. The narrative is a tee-time booking system, but the same shape applies to any Seldon Offer.

Early access: The hosted control plane is invite-only today. Join the waitlist to get a sandbox tenant; the steps below run against the production base URL once you have one.

Prerequisites

  • A tenant id and a bearer token (issued when your sandbox is provisioned).
  • A Git repository LatticeKit can read — HTTPS with a deploy token, or SSH with the public key from your tenant's provisioning email.
  • curl and jq on your machine. That's it.

Every example below assumes:

export LK_BASE="https://api.foundation.dev"
export LK_TOKEN="<your-bearer-token>"

1 — Register your config repo with Radiant

Radiant is where every declarative artifact lives — pricing rules, cancellation policies, message templates. Point it at a Git repository your tenant trusts:

curl -sX POST "$LK_BASE/radiant/v1/repositories" \
  -H "Authorization: Bearer $LK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name":          "main-config",
    "remoteUrl":     "https://github.com/your-org/lattice-config.git",
    "defaultBranch": "main"
  }' | jq

You get back a rep_* id. Save it; you will point Assets at it next.

2 — Publish a pricing asset

Commit a pricing YAML to your repo at, say, pricing/tee-time.yaml, then register it as an Asset and publish a Version:

curl -sX POST "$LK_BASE/radiant/v1/assets" \
  -H "Authorization: Bearer $LK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "repositoryId": "rep_01J8K2…",
    "path":         "pricing/tee-time.yaml",
    "schemaKind":   "seldon.pricing.v1"
  }' | jq

And an Alias that always points at the current main:

curl -sX POST "$LK_BASE/radiant/v1/aliases" \
  -H "Authorization: Bearer $LK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "assetId":  "asset_01J9TQ…",
    "name":     "pricing.tee-time.production",
    "channel":  "main"
  }' | jq

3 — Define a physical resource in Trantor

A tee-time needs a slot to be bookable against. Create a ResourceType:

curl -sX POST "$LK_BASE/trantor/v1/resource-types" \
  -H "Authorization: Bearer $LK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name":     "tee_time_slot",
    "kind":     "discrete",
    "metadata": { "dimension": "side" }
  }' | jq

You can add concrete Resources (cart 1, cart 2, …) the same way under /trantor/v1/resources when you need them allocated by name.

4 — Create a Seldon Offer

The Offer is what a customer books. A fixed 4-hour 18-hole round that requires one tee-time slot, with the pricing alias from step 2 pinned:

curl -sX POST "$LK_BASE/seldon/v1/offers" \
  -H "Authorization: Bearer $LK_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name":          "18-hole round",
    "kind":          "appointment",
    "durationShape": { "mode": "fixed", "fixedSec": 14400 },
    "partyCapacity": { "min": 1, "max": 4, "default": 4 },
    "requirements":  [{ "resourceTypeId": "rt_01JAZA…", "count": 1 }],
    "radiantAssetId": "asset_01J9TQ…",
    "cancelDeadlineSec": 86400,
    "isActive":      true
  }' | jq

5 — Resolve an Availability projection

Once a TimeScheme is attached to the Offer (handled by the admin UI for now), Availability becomes queryable. Ask for the next two weeks:

curl -sG "$LK_BASE/seldon/v1/availability" \
  -H "Authorization: Bearer $LK_TOKEN" \
  --data-urlencode "offerId=offer_01JAZB…" \
  --data-urlencode "from=2026-06-12T00:00:00Z" \
  --data-urlencode "to=2026-06-26T00:00:00Z" | jq

You get back a list of open slots with their anchor shapes — that is what the next call references.

6 — Create the Booking

One call. Trantor holds the slot atomically, Terminus checks tier entitlement if a BookingAccessRule applies, the Radiant policy version pins, and the Booking enters confirmed:

curl -sX POST "$LK_BASE/seldon/v1/bookings" \
  -H "Authorization: Bearer $LK_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "offerId":        "offer_01JAZB…",
    "availabilityId": "avlb_01JAZC…",
    "anchor": {
      "slotInstanceId":  "si_01JAZD…",
      "dimensionValues": { "side": "front" }
    },
    "party": {
      "count": 4,
      "members": [{ "displayName": "Greg O.", "role": "organizer" }]
    }
  }' | jq

7 — Watch the lifecycle events fire

From this point on, Seldon's emission pipeline drives the lifecycle. The Booking moves confirmed → checked_in → live → completed automatically as time anchors hit; events fan out to Daneel (which can dispatch through Speaker for a confirmation) and to Palver (which can push them to a live UI). Inspect the Booking at any point:

curl -s "$LK_BASE/seldon/v1/bookings/bk_01JAZE…" \
  -H "Authorization: Bearer $LK_TOKEN" | jq '.lifecycle, .status'

Where to go next

  • Seldon — the full Offer / Availability / Booking model with all five Availability kinds.
  • Terminus — wire identity, tier groups, and consent so your customers stop being walk-up display names.
  • Speaker — route a Daneel-triggered confirmation through the consent gate to email or SMS.
  • Hober + Payments + Mallow — turn this booking into a paid, ledger-recorded sale at check-in.