RODEO

Quickstart

First scene in 5 minutes.

Install

npm install @rodeo/sdk

Initialize

import { Rodeo } from "@rodeo/sdk";

const rodeo = new Rodeo({
  apiKey: "your-api-key",
  endpoint: "http://localhost:3000",
});

Register a channel

const sms = await rodeo.channels.create({
  name: "sms-main",
  type: "direct",
  tone: {
    register: "casual",
    voice: "peer",
    awareness: "cold",
    deniability: "none",
  },
  provider: "twilio",
  provider_config: { from: "+15551234567" },
});

Create an audience

const audience = await rodeo.audiences.create({
  type: "individual",
  context: {
    name: "Jordan",
    role: "mobile butcher",
    region: "TX-Hill-Country",
  },
  bounds: {
    maxBeatsPerDay: 3,
    maxBeatsPerWeek: 8,
    cooldownMinutes: 60,
  },
});

Declare an intention

const intention = await rodeo.intentions.create({
  type: "recruit",
  description: "Recruit mobile butcher for processing network",
  success_condition: { contractSigned: true },
  alignment: {
    audienceBenefit: "Guaranteed weekly volume, premium pricing",
    mutuality: "Stable income for butcher, capacity for network",
  },
});

Build and declare

const scene = await rodeo.scenes
  .build()
  .intention(intention.id)
  .audience(audience.id)
  .arc("approach")
  .constraints({ maxBeats: 4, maxDuration: "2h", budget: 50 })
  .beat({
    sequence: 1,
    channel_id: sms.id,
    content: { body: "Hey Jordan — steady work if you're interested." },
    tone: { warmth: "warm", urgency: "none", ask: "implicit" },
    timing: { mode: "absolute", at: "2025-01-15T08:00:00-06:00" },
  })
  .beat({
    sequence: 2,
    channel_id: sms.id,
    content: { body: "No pressure — happy to chat whenever." },
    tone: { warmth: "warm", urgency: "gentle", ask: "soft" },
    timing: { mode: "relative", after: "30m", anchor: "beat:1" },
  })
  .create();

await rodeo.scenes.declare(scene.scene.id);

Report a sensor reading

await rodeo.sensors.report({
  sensorId: "sms-delivery",
  beatId: scene.beats[0].id,
  sceneId: scene.scene.id,
  type: "delivery",
  metric: "delivered",
  value: true,
});

Query the ledger

const entries = await rodeo.ledger.query({
  intentionType: "recruit",
  outcome: "succeeded",
});