---
title: "openvibe-sdk/elements · OpenVibe.Services"
canonical: "https://openvibe.services/docs/sdk/elements"
updated: null
---

# openvibe-sdk/elements · OpenVibe.Services

HTML: [openvibe-sdk/elements · OpenVibe.Services](https://openvibe.services/docs/sdk/elements)

# `openvibe-sdk/elements`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

From `types/elements.d.ts` (both). Declarations are shown verbatim.

## type ElementSharing

~~~~
export type ElementSharing = 'private' | 'link' | 'gallery';
~~~~

## type ElementRole

~~~~
export type ElementRole = 'everyone' | 'follower' | 'subscriber' | 'vip' | 'operator' | 'owner';
~~~~

## type ElementShape

~~~~
export type ElementShape = 'round' | 'pill' | 'square';
~~~~

## type ActionKind

~~~~
export type ActionKind =
    | 'robot.drive_pulse' | 'robot.head_preset' | 'robot.headlight' | 'robot.say' | 'robot.macro'
    | 'chat.message' | 'chat.pin' | 'chat.poll'
    | 'screen.alert' | 'screen.animation' | 'screen.confetti' | 'screen.sound' | 'screen.tts'
    | 'screen.counter' | 'screen.state' | 'screen.visibility' | 'screen.scene'
    | 'stream.clip' | 'stream.moment' | 'stream.title' | 'stream.category'
    | 'ai.ask' | 'actor.task' | 'webhook.call' | 'money.tip_goal';
~~~~

## type ProductId

~~~~
export type ProductId = 'bot' | 'chat' | 'live' | 'ai' | 'actor' | 'billing';
~~~~

## type TriggerKind

~~~~
export type TriggerKind =
    | 'press' | 'hold' | 'double_press' | 'key' | 'gamepad' | 'chat_command' | 'chat_text'
    | 'follow' | 'tip' | 'ai_moment' | 'rundown_topic' | 'timer' | 'schedule'
    | 'robot_telemetry' | 'robot_event' | 'stream_start' | 'stream_end' | 'viewer_count' | 'element_event';
~~~~

## type ElementValue

~~~~
export type ElementValue = boolean | number | string | Array<number | string>;
~~~~

## type ElementValues

~~~~
export type ElementValues = Record<string, ElementValue>;
~~~~

## interface ElementsError

~~~~
export interface ElementsError {
    /** Where the problem is, e.g. "/recipe/actions/0/product". */
    path: string;
    /** A plain sentence an editor can show after "Can't do that: ". */
    message: string;
}
~~~~

## interface ElementValidation

~~~~
export interface ElementValidation {
    valid: boolean;
    errors: ElementsError[];
}
~~~~

## interface UiTrigger

One trigger declaration, or the fired occurrence shaped like it.

~~~~
export interface UiTrigger {
    kind: TriggerKind;
    [key: string]: unknown;
}
~~~~

## interface UiAction

One action from the catalog, with the product that authorises it.

~~~~
export interface UiAction {
    kind: ActionKind;
    product: ProductId;
    [key: string]: unknown;
}
~~~~

## interface ElementConditions

~~~~
export interface ElementConditions {
    role?: ElementRole;
    /** Channel points only; stage 1 never charges money or Vibes. */
    cost?: { points: number };
    cooldown?: { per_person_seconds?: number; overall_seconds?: number };
    daily_cap?: { per_person?: number; overall?: number };
    live_only?: boolean;
    robot_turn_only?: boolean;
    chance?: { one_in: number };
}
~~~~

## interface ElementLook

~~~~
export interface ElementLook {
    component: string;
    label: string;
    icon?: string;
    props?: Record<string, boolean | number | string>;
    style?: {
        tint?: string;
        shape?: ElementShape;
        opacity?: number;
        show_label?: boolean;
    };
}
~~~~

## interface ElementRecipe

~~~~
export interface ElementRecipe {
    triggers: UiTrigger[];
    conditions?: ElementConditions;
    actions: UiAction[];
}
~~~~

## interface ElementModReference

~~~~
export interface ElementModReference {
    id: string;
    version: string;
    sha256: string;
    capabilities?: ActionKind[];
}
~~~~

## interface UiElement

~~~~
export interface UiElement {
    id?: string;
    revision?: number;
    name: string;
    description?: string;
    author: { name: string; subject?: SubjectRef };
    sharing: ElementSharing;
    look: ElementLook;
    recipe: ElementRecipe;
    capabilities: ActionKind[];
    initial_state?: ElementValues;
    mod?: ElementModReference;
    created_at?: string;
    updated_at?: string;
}
~~~~

## interface ElementState

~~~~
export interface ElementState {
    values?: ElementValues;
    revision?: number;
}
~~~~

## interface ElementLimits

~~~~
export interface ElementLimits {
    /** Milliseconds until this scope is ready; 0 when it is ready now. */
    cooldown(query: { scope: 'person' | 'overall'; elementId: string; actorId: string; at: number }): number | Promise<number>;
    /** How many times this scope already fired in the UTC day. */
    dailyCount(query: { scope: 'person' | 'overall'; elementId: string; actorId: string; day: string }): number | Promise<number>;
    /** Record an accepted fire so the cooldown and daily counters move. */
    hit(query: { elementId: string; actorId: string; at: number; day: string }): void | Promise<void>;
}
~~~~

## interface ElementSpend

~~~~
export interface ElementSpend {
    points: number;
    elementId: string;
    actorId: string;
    subject: SubjectRef | null;
    at: number;
}
~~~~

## interface ElementSpendResult

~~~~
export interface ElementSpendResult {
    ok: boolean;
    reason?: string;
    message?: string;
}
~~~~

## interface ElementSendInfo

~~~~
export interface ElementSendInfo {
    element: { id?: string; name?: string; capabilities: ActionKind[] };
    actor: { subject?: SubjectRef; role?: ElementRole; name?: string };
    trigger: UiTrigger;
    /** The product that authorises this action; the host dispatches on it. */
    product: ProductId;
}
~~~~

## interface ElementSendResult

~~~~
export interface ElementSendResult {
    ok: boolean;
    result?: unknown;
    reason?: string;
    message?: string;
}
~~~~

## interface ElementsHostContext

The host's side of run(). It is supplied by the product that owns the press.

~~~~
export interface ElementsHostContext {
    now?: number;
    random?: () => number;
    isLive?: boolean;
    robotInTurn?: boolean;
    element: { id?: string; name?: string; capabilities: ActionKind[] };
    actor?: { subject?: SubjectRef; role?: ElementRole; name?: string };
    limits?: ElementLimits;
    spend?: (query: ElementSpend) => ElementSpendResult | Promise<ElementSpendResult>;
    refund?: (query: ElementSpend) => void | Promise<void>;
    send: (action: UiAction, info: ElementSendInfo) => ElementSendResult | Promise<ElementSendResult>;
}
~~~~

## type ElementsRefusalCode

~~~~
export type ElementsRefusalCode =
    | 'invalid' | 'trigger' | 'capability' | 'role' | 'not_live' | 'robot_turn' | 'chance'
    | 'cooldown' | 'daily_cap' | 'points' | 'limits' | 'action';
~~~~

## interface ElementsRunSuccess

~~~~
export interface ElementsRunSuccess {
    ok: true;
    pointsSpent: number;
    actions: Array<{ action: UiAction; result: unknown }>;
}
~~~~

## interface ElementsRunRefusal

~~~~
export interface ElementsRunRefusal {
    ok: false;
    code: ElementsRefusalCode;
    message: string;
    retryAfterMs?: number;
    scope?: 'person' | 'overall';
    refusedAction?: ActionKind;
    refunded?: boolean;
    pointsSpent?: number;
    actions?: Array<{ action: UiAction; result: unknown }>;
}
~~~~

## type ElementsRunResult

~~~~
export type ElementsRunResult = ElementsRunSuccess | ElementsRunRefusal;
~~~~

## interface ElementsReduceResult

~~~~
export interface ElementsReduceResult {
    values: ElementValues;
    revision: number;
    changed: boolean;
    errors: ElementsError[];
}
~~~~

## function validate

~~~~
export declare function validate(element: unknown): ElementValidation;
~~~~

## function run

~~~~
export declare function run(recipe: ElementRecipe, trigger: UiTrigger, ctx: ElementsHostContext): Promise<ElementsRunResult>;
~~~~

## function reduce

~~~~
export declare function reduce(state: ElementState | null, actions: UiAction[], options?: { maxKeys?: number }): ElementsReduceResult;
~~~~

## function isValidValue

~~~~
export declare function isValidValue(value: unknown): boolean;
~~~~

## const PRODUCTS

~~~~
export declare const PRODUCTS: Record<ActionKind, ProductId>;
~~~~

## const ACTION\_KINDS

~~~~
export declare const ACTION_KINDS: ActionKind[];
~~~~

## const ACTION\_SET

~~~~
export declare const ACTION_SET: Set<ActionKind>;
~~~~

## const TRIGGER\_KINDS

~~~~
export declare const TRIGGER_KINDS: TriggerKind[];
~~~~

## const TRIGGER\_SET

~~~~
export declare const TRIGGER_SET: Set<TriggerKind>;
~~~~

## const ROBOT\_ACTIONS

~~~~
export declare const ROBOT_ACTIONS: ActionKind[];
~~~~

## const ROLES

~~~~
export declare const ROLES: ElementRole[];
~~~~

## const ROLE\_RANK

~~~~
export declare const ROLE_RANK: Record<ElementRole, number>;
~~~~
