openvibe-sdk/exchange

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

From types/exchange.d.ts (server only). Declarations are shown verbatim.

class ExchangeError

OpenVibe.Exchange: the buyer side (chat, models, offers, presets, usage, receipts) and the seller side.

export declare class ExchangeError extends Error {
    constructor(message: string, init?: { status?: number | null; code?: string | null; body?: unknown; retryAfter?: number | null });
    status: number | null;
    code: string | null;
    body: unknown;
    retryAfter: number | null;
    /** No status, 5xx, 429 or 401. */
    readonly retryable: boolean;
}

type ExchangePaths

Where each call goes; a deployment may point another one at these paths.

export type ExchangePaths = {
    chat?: string;
    models?: string;
    receipts?: string;
    presets?: string;
    catalog?: string;
    catalogModels?: string;
    usage?: string;
    platformUsage?: string;
    sell?: string;
    sellerOffers?: string;
    offerReport?: string;
    offerList?: string;
    computePrices?: string;
};

type ExchangeOptions

export type ExchangeOptions = {
    /** The Network developer key (Bearer) the buyer side speaks with. */
    developerKey?: string;
    /** The key used on the Network's origin when the seller side reports an offer; defaults to the developer key. */
    networkKey?: string;
    /** The Exchange's origin; default https://api.openvibe.exchange. */
    baseUrl?: string;
    /** The Network's origin, where the user-owned AI offers live; default https://api.openvibe.network. */
    networkUrl?: string;
    /** Exchange's public site, where the compute price book lives; default https://openvibe.exchange. */
    siteUrl?: string;
    fetchImpl?: typeof fetch;
    /** Per request, default 60000. */
    timeoutMs?: number;
    /** How many times a 429 or a 5xx is retried, default 3. */
    maxRetries?: number;
    /** The first backoff before the jitter, in ms; default 250. */
    retryBaseMs?: number;
    /** The seller subject (usr_...), used by the seller side when a call names no other owner. */
    owner?: string;
    paths?: ExchangePaths;
    /** The User-Agent the calls carry. */
    agent?: string;
};

type ComputePriceKind

export type ComputePriceKind = 'cpu' | 'gpu';

interface ComputePrice

export interface ComputePrice {
    id: string;
    provider: string;
    region?: string | null;
    kind: ComputePriceKind;
    cpu?: number | null;
    ram_mb?: number | null;
    gpu?: string | null;
    gpu_mb?: number | null;
    currency: string;
    hourly: number;
    per_second: number;
    billing_seconds?: number | null;
    promotion?: string | null;
    promotion_expires?: string | null;
    interruptible?: boolean;
    checked_at: string;
    /** Epoch milliseconds. */
    expires_at: number;
    source: string;
    [field: string]: unknown;
}

interface ComputePriceBook

export interface ComputePriceBook {
    checked_at: string;
    prices: ComputePrice[];
    [field: string]: unknown;
}

interface ComputePriceOptions

export interface ComputePriceOptions {
    /** Only this kind: a computer (cpu) or a GPU. */
    kind?: ComputePriceKind;
}

interface ComputePriceClient

export interface ComputePriceClient {
    computePrices(query?: ComputePriceOptions, opts?: { signal?: AbortSignal }): Promise<ComputePriceBook>;
}

type ExchangeChatRequest

export type ExchangeChatRequest = {
    model: string;
    messages: { role: string; content: string | unknown[] | null; [field: string]: unknown }[];
    stream?: boolean;
    stream_options?: { include_usage?: boolean };
    temperature?: number;
    max_tokens?: number;
    max_completion_tokens?: number;
    tools?: unknown[];
    tool_choice?: unknown;
    [field: string]: unknown;
};

type ExchangeUsage

export type ExchangeUsage = {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
};

type ExchangeChatCompletion

export type ExchangeChatCompletion = {
    id: string;
    object: 'chat.completion' | string;
    created: number;
    model: string;
    choices: { index: number; message: { role: string; content: string | null; tool_calls?: unknown[] }; finish_reason: string | null }[];
    usage: ExchangeUsage;
    system_fingerprint?: string | null;
    x_openvibe?: { run_id: string; provider?: string; fallback_used?: boolean; cost_usd?: number; synthetic?: boolean };
};

type ExchangeChatChunk

export type ExchangeChatChunk = {
    id: string;
    object: 'chat.completion.chunk' | string;
    created: number;
    model: string;
    choices: { index: number; delta: { role?: string; content?: string | null; tool_calls?: unknown[] }; finish_reason: string | null }[];
    usage?: ExchangeUsage;
    x_openvibe?: { run_id: string; provider?: string; fallback_used?: boolean; cost_usd?: number; synthetic?: boolean };
};

type ExchangeModel

export type ExchangeModel = { id: string; object: 'model' | string; created?: number; owned_by?: string; [field: string]: unknown };

type ExchangeModelList

export type ExchangeModelList = { object: 'list'; data: ExchangeModel[] };

type ExchangeOffer

export type ExchangeOffer = {
    provider: string;
    provider_name?: string;
    model: string;
    id?: string | null;
    trust: 'community' | 'first-party' | string;
    access?: string;
    free?: boolean;
    price?: { in: number; out: number; cached?: number; per: string; currency: string } | null;
    speed?: { p50_ms: number | null; p95_ms: number | null };
    uptime?: number | null;
    requests_7d?: number;
    requests_today?: number;
    data_policy?: { trains: boolean | null; retention_days: number | null; region: string | null } | null;
    updated_at?: string | null;
    [field: string]: unknown;
};

type ExchangeModelDoc

export type ExchangeModelDoc = {
    slug: string;
    canonical: string;
    name: string;
    family?: string;
    type?: string;
    context?: number | null;
    max_output?: number | null;
    capabilities?: { tools: boolean; json: boolean; vision: boolean; stream: boolean };
    modalities?: string[];
    community?: boolean;
    priced?: boolean;
    offers: ExchangeOffer[];
    [field: string]: unknown;
};

type ExchangeCatalog

export type ExchangeCatalog = {
    generated_at: string;
    window_days: number;
    count: number;
    families?: { name: string; models: number; offers: number }[];
    models: ExchangeModelDoc[];
};

type ExchangePresetPolicy

export type ExchangePresetPolicy = {
    objective?: 'cheapest' | 'fastest' | 'balanced' | 'private';
    floor?: 'fast' | 'balanced' | 'strong' | 'frontier';
    ceiling?: number;
    max_price?: number;
    quantization?: string[];
    region?: string[];
    data_policy?: 'private' | 'anonymized' | 'community';
    community?: boolean;
    adult?: boolean;
    [field: string]: unknown;
};

type ExchangePreset

export type ExchangePreset = {
    name: string;
    description?: string | null;
    policy: ExchangePresetPolicy;
    builtin?: boolean;
    [field: string]: unknown;
};

type ExchangeUsageAggregate

export type ExchangeUsageAggregate = {
    generated_at: string;
    days: number;
    from: string;
    to: string;
    today: { requests: number; tokens_in: number; tokens_out: number; cost_usd: number };
    totals: { requests: number; tokens_in: number; tokens_out: number; cost_usd: number };
    by_day: { day: string; requests: number; tokens_in: number; tokens_out: number; cost_usd: number }[];
    by_model: { provider: string; model: string | null; requests: number; tokens_in: number; tokens_out: number; cost_usd: number }[];
    by_product: { product: string; requests: number; tokens_in: number; tokens_out: number; cost_usd: number; models?: unknown[] }[];
    [field: string]: unknown;
};

type ExchangeReceipt

export type ExchangeReceipt = {
    id: string;
    run_id?: string;
    offer?: { provider: string; model: string | null; deployment?: string | null; access?: string; provider_access?: string | null; local?: boolean; community?: 'machine' | 'endpoint' | null };
    price?: { in: number | null; out: number | null; cached?: number | null; source?: string | null };
    tokens?: { tokens_in: number; tokens_out: number; tokens_cached?: number; tokens_cache_write?: number; tokens_reasoning?: number };
    latency_ms?: number | null;
    why?: string[];
    fallbacks?: { offer: string; provider?: string | null; model?: string | null; why?: string | null; status?: string; reason?: string | null }[];
    paid_by?: { paid_by: string; detail?: string | null; fee_rate?: number | null };
    privacy?: { label: string; [field: string]: unknown } | string;
    preset?: string | null;
    created_at?: string;
    [field: string]: unknown;
};

type ExchangeOfferDocument

The offer document the Network's user-owned AI offers registry validates.

export type ExchangeOfferDocument = {
    offer_id: string;
    machine_id: string;
    owner: string;
    models: string[];
    hours: { start: string; end: string; tz: string };
    concurrency: number;
    price: { in_per_million: number; out_per_million: number };
    audience: 'everyone' | 'followers' | 'group';
    group?: string;
    ready: boolean;
    health: { status: 'up' | 'degraded' | 'down'; checked_at: string };
};

type ExchangeOfferInput

export type ExchangeOfferInput = {
    /** The model served; models may name several. */
    model?: string;
    models?: string[];
    /** Credits per million tokens: a number for both sides, or {in_per_million, out_per_million}. */
    price: number | { in_per_million?: number; out_per_million?: number; in?: number; out?: number };
    /** The local window the offer is open: {start, end, tz}; start == end is all day. */
    hours: { start: string; end: string; tz?: string };
    /** How many answers may run at once, 1 to 8. */
    concurrency: number;
    /** The OpenAI-compatible server that serves the model. */
    endpoint?: string;
    /** The key the endpoint needs, when it needs one. */
    endpointKey?: string;
    /** The machine the offer belongs to (dev_...). */
    machineId: string;
    /** The owner (usr_...); defaults to the client's owner. */
    owner?: string;
    audience?: 'everyone' | 'followers' | 'group';
    /** The group id, required for the group audience. */
    group?: string;
    ready?: boolean;
    health?: { status: 'up' | 'degraded' | 'down'; checked_at?: string };
    /** The reporter name; the registry keeps one set of offers per source. */
    source?: string;
    /** Whether the endpoint is asked for its model list first; default true. */
    probe?: boolean;
};

type ExchangeOfferResult

export type ExchangeOfferResult = {
    offer: ExchangeOfferDocument;
    report: { source: string; offers: number; marked_down: number; generated_at?: string };
    endpoint: { url: string; models: string[] | null } | null;
};

type ExchangeEndpointOfferInput

A standalone OpenAI-compatible server registered on the Exchange's public seller API. The key names the owner.

export type ExchangeEndpointOfferInput = {
    /** The https base URL, e.g. https://my-server.example/v1; /chat/completions is appended. */
    endpoint: string;
    /** The model served; models may name several. */
    model?: string;
    models?: string[];
    /** Credits per million tokens: a number for both sides, or {in_per_million, out_per_million}; 0 volunteers. */
    price: number | { in_per_million: number; out_per_million: number };
    /** The local window the offer is open: {start, end, tz}; start == end is all day. */
    hours: { start: string; end: string; tz?: string };
    /** How many answers may run at once, 1 to 8. */
    concurrency: number;
    audience?: 'everyone' | 'followers' | 'group';
    /** The group id, required for the group audience. */
    group?: string;
    /** A label for the seller's own dashboard. */
    name?: string;
    /** The key the endpoint needs for the probe, when it needs one. AI sends no key. */
    endpointKey?: string;
    /** Whether the endpoint is asked for its model list first; default true. */
    probe?: boolean;
};

type ExchangeEndpointOffer

export type ExchangeEndpointOffer = {
    id: string;
    offer_id: string;
    name: string | null;
    base_url: string;
    models: string[];
    hours: { start: string; end: string; tz: string };
    concurrency: number;
    price: { in_per_million: number; out_per_million: number };
    audience: 'everyone' | 'followers' | 'group';
    group: string | null;
    created_at?: string;
    updated_at?: string;
    verification?: ExchangeSellerVerification | null;
    reputation?: number;
    free_only?: boolean;
    verified?: boolean;
};

type ExchangeEndpointOfferResult

export type ExchangeEndpointOfferResult = {
    offer: ExchangeEndpointOffer;
    endpoint: { url: string; models: string[] | null };
};

type ExchangeSellerVerification

export type ExchangeSellerVerification = {
    status: 'new' | 'verified' | 'failed' | 'paused' | string;
    canary_passes: number;
    canary_failures: number;
    spot_runs: number;
    spot_failures: number;
    failure_rate?: number;
    last_canary_at?: string | null;
    last_spot_at?: string | null;
    first_verified_at?: string | null;
    failure_reason?: string | null;
};

type ExchangeSellerOffer

export type ExchangeSellerOffer = {
    offer_id: string;
    machine_id: string;
    models: string[];
    hours?: { start: string; end: string; tz: string } | null;
    concurrency?: number | null;
    price?: { in_per_million: number; out_per_million: number };
    audience?: string | null;
    group?: string | null;
    health?: string | null;
    open_now?: boolean | null;
    ready: boolean;
    verification: ExchangeSellerVerification | null;
    verified: boolean;
    reputation: number;
    free_only: boolean;
    uptime_pct?: number | null;
    tokens_per_s?: number | null;
};

type ExchangeEarnings

export type ExchangeEarnings = {
    owner: string;
    generated_at: string;
    offers: ExchangeSellerOffer[];
    totals: {
        requests: number;
        tokens_in: number;
        tokens_out: number;
        pending_credits_micro: number;
        spendable_credits_micro: number;
        self_served_requests: number;
    };
    kudos?: number;
    note?: string;
    [field: string]: unknown;
};

type ExchangeKey

export type ExchangeKey = { id: string; name: string; prefix: string; monthly_cap_usd: number; allowed_models: string[]; created_at: string; revoked_at: string | null };

type ExchangeSearchOptions

export type ExchangeSearchOptions = { engine?: string; limit?: number; license?: string; commercial?: boolean; format?: string; orientation?: string; size?: 'small' | 'medium' | 'large'; color?: 'black_and_white' | 'black' | 'white' | 'yellow' | 'orange' | 'red' | 'purple' | 'magenta' | 'green' | 'teal' | 'blue'; type?: 'icon' | 'photo' | 'illustration' | 'vector'; after?: string; safe_search?: 'strict'; style?: 'line' | 'solid' | 'any'; set?: string; signal?: AbortSignal };

interface CatalogSearchFilters

export interface CatalogSearchFilters { provider?: string; capability?: string; min_price?: number; max_price?: number; max_speed_ms?: number; sort?: 'relevance' | 'price' | 'speed' | 'quality'; rating_kind?: string; }

interface CatalogModelResult

export interface CatalogModelResult { model: string; name: string; family: string | null; capabilities: Record<string, boolean>; provider: string; price: { in: number; out: number; cached?: number; per?: string; currency?: string } | null; speed: { p50_ms?: number; p95_ms?: number; tokens_per_second?: number } | null; quality: { elo: number; games: number; kind: string } | null; offers: number; task_match: string | null; score: number; }

interface CatalogSearchResponse

export interface CatalogSearchResponse { q: string; count: number; results: CatalogModelResult[]; quality_unavailable: boolean; }

function createCatalogSearchClient

export declare function createCatalogSearchClient(options?: { baseUrl?: string; fetchImpl?: typeof fetch }): { search(q: string, filters?: CatalogSearchFilters, options?: { signal?: AbortSignal }): Promise<CatalogSearchResponse> };

type ExchangeSearchResult

export type ExchangeSearchResult = { results: Array<{ title: string; url: string; snippet: string; engine: string; published: string | null; indexed_on?: string | null; type?: string | null; thumbnail?: string | null; license?: string | null; license_url?: string | null; author?: string | null; author_url?: string | null; source_page?: string | null; attribution?: string | null; width?: number | null; height?: number | null }>; receipt: { engine: string; cost_usd: number; time_ms: number } };

type ExchangeClient

export type ExchangeClient = {
    keys: {
        list(opts?: { signal?: AbortSignal }): Promise<{ keys: ExchangeKey[] }>;
        create(input: { name: string; monthly_cap_usd: number; allowed_models: string[] }, opts?: { signal?: AbortSignal }): Promise<{ key: ExchangeKey; secret: string }>;
        revoke(id: string, opts?: { signal?: AbortSignal }): Promise<{ id: string; revoked: boolean }>;
    };
    keyUsage(opts?: { signal?: AbortSignal }): Promise<{ rows: Array<{ day: string; key_id: string; model: string; requests: number; tokens_in: number; tokens_out: number; cost_usd: number; status: string }> }>;
    deployments: {
        list(opts?: { signal?: AbortSignal }): Promise<{ endpoints: unknown[]; status: unknown }>;
        create(input: { model: string; idle_minutes?: number }, opts?: { signal?: AbortSignal }): Promise<unknown>;
        stop(id: string, opts?: { signal?: AbortSignal }): Promise<unknown>;
    };
    search: ((q: string, opts?: ExchangeSearchOptions) => Promise<ExchangeSearchResult>) & { icons(q: string, opts?: ExchangeSearchOptions): Promise<ExchangeSearchResult> };
    images(q: string, opts?: ExchangeSearchOptions): Promise<ExchangeSearchResult>;
    fetch(url: string, opts?: { signal?: AbortSignal }): Promise<{ url: string; text: string; receipt: ExchangeSearchResult['receipt'] }>;

    arena: {
        start(input: { prompt: string; category?: string; entries: unknown[] }, options?: { signal?: AbortSignal }): Promise<unknown>;
        vote(roundId: string, choice: 'left' | 'right' | 'tie' | 'both_bad', options?: { signal?: AbortSignal }): Promise<unknown>;
    };
    /** One chat completion; stream: true answers an async iterable of chunks. */
    chat(body: ExchangeChatRequest, opts?: { signal?: AbortSignal }): Promise<ExchangeChatCompletion | AsyncIterable<ExchangeChatChunk>>;
    /** The models the Exchange can serve. */
    models(opts?: { signal?: AbortSignal }): Promise<ExchangeModelList>;
    /** The offers that serve one model. */
    offers(model: string, opts?: { signal?: AbortSignal }): Promise<ExchangeOffer[]>;
    /** The whole public catalog. */
    catalog(opts?: { signal?: AbortSignal }): Promise<ExchangeCatalog>;
    /** The reviewed compute tariffs, keyless from the public site; `kind` filters the list. */
    computePrices(query?: ComputePriceOptions, opts?: { signal?: AbortSignal }): Promise<ComputePriceBook>;
    presets: {
        list(opts?: { signal?: AbortSignal }): Promise<ExchangePreset[]>;
        create(input: { name: string; policy: ExchangePresetPolicy }, opts?: { signal?: AbortSignal }): Promise<ExchangePreset>;
        /** The platform has no PATCH: a preset is stored under its name, so a second POST replaces it. */
        update(name: string, input: { policy: ExchangePresetPolicy }, opts?: { signal?: AbortSignal }): Promise<ExchangePreset>;
        remove(name: string, opts?: { signal?: AbortSignal }): Promise<unknown>;
    };
    /** Private key usage by default; days or scope public requests aggregates. */
    usage(query?: { scope?: 'mine' | 'public'; days?: number; from?: string; to?: string; requester?: string }, opts?: { signal?: AbortSignal }): Promise<ExchangeUsageAggregate | { usage: unknown } | { rows: unknown[] }>;
    /** The receipt of one answered request. */
    receipt(id: string, opts?: { signal?: AbortSignal }): Promise<ExchangeReceipt>;
    seller: {
        /** Register a Link machine's offer in the Network's user-owned AI offers, or an endpoint with the Exchange. */
        offer(input: ExchangeOfferInput, opts?: { signal?: AbortSignal }): Promise<ExchangeOfferResult>;
        offer(input: ExchangeEndpointOfferInput, opts?: { signal?: AbortSignal }): Promise<ExchangeEndpointOfferResult>;
        /** The caller's own endpoint offers, with their verification. */
        endpointOffers(opts?: { signal?: AbortSignal }): Promise<{ owner: string; offers: ExchangeEndpointOffer[] }>;
        /** Remove one of the caller's endpoint offers. */
        removeEndpointOffer(id: string, opts?: { signal?: AbortSignal }): Promise<{ id: string; removed: boolean }>;
        /** The model list at an OpenAI-compatible endpoint. */
        probe(input: { endpoint: string; key?: string | null }, opts?: { signal?: AbortSignal }): Promise<{ models: string[] }>;
        /** The seller dashboard: the tokens served, the credits earned, the uptime and the verification. */
        earnings(opts?: { owner?: string } & { signal?: AbortSignal }): Promise<ExchangeEarnings>;
        /** The verification, the reputation and the uptime of every offer. */
        verification(opts?: { owner?: string } & { signal?: AbortSignal }): Promise<{ owner: string | null; generated_at: string | null; offers: ExchangeSellerOffer[] }>;
        /** The offers the Network holds, whole. */
        offers(opts?: { owner?: string; source?: string } & { signal?: AbortSignal }): Promise<{ offers: ExchangeOfferDocument[]; count?: number; generated_at?: string }>;
    };
    webhooks: {
        /** Constant-time check of the RAW body against X-OpenVibe-Signature-V2 (or a legacy sha256= header). */
        verify(rawBody: string | Uint8Array | ArrayBufferView, signatureHeader: string, secret: string, opts?: { toleranceSec?: number; now?: number }): boolean;
    };
    baseUrl(): string;
    networkUrl(): string;
};

function createExchangeClient

export declare function createExchangeClient(options?: ExchangeOptions): ExchangeClient;

function createComputePriceClient

export declare function createComputePriceClient(options?: { baseUrl?: string; fetchImpl?: typeof fetch; timeoutMs?: number; maxRetries?: number; retryBaseMs?: number; agent?: string }): ComputePriceClient;

function verifyWebhook

The same check as exchange.webhooks.verify, for a receiver that only verifies webhooks.

export declare function verifyWebhook(rawBody: string | Uint8Array | ArrayBufferView, signatureHeader: string, secret: string, opts?: { toleranceSec?: number; now?: number }): boolean;

const SIGNATURE_TOLERANCE_SEC

export declare const SIGNATURE_TOLERANCE_SEC: number;

const EXCHANGE_BASE_URL

export declare const EXCHANGE_BASE_URL: string;

const NETWORK_BASE_URL

export declare const NETWORK_BASE_URL: string;

const DEFAULT_PATHS

export declare const DEFAULT_PATHS: Required<ExchangePaths>;

const RETRY_STATUS

export declare const RETRY_STATUS: ReadonlySet<number>;