Skip to content

Toborlife Marketplace: End-to-End Flow

Summary

The Toborlife marketplace lets organizations sell robot datasets they hold on Toboverse and lets other organizations license and import them, with Toborlife in the middle of every deal. It runs at a Toboverse subdomain (proposed: market.toboverse.ai) and is built on the existing RDS database and S3 video bucket rather than copying data into a new system.

Three roles use it:

  • Buyer: an organization that searches, previews, licenses and imports datasets. It may be an existing Toborlife customer or a new sign-up.
  • Seller: an organization that lists a chosen set of its episodes for sale. It may already store data on Toboverse or be a new organization uploading for the first time.
  • Admin (Toborlife): holds buyer payments until delivery is accepted and takes a commission.

This document walks through each flow in order and names the component, table and bucket involved at every step.

Features

The first version ships the necessary features; the optional ones can follow.

Necessary

Feature What it does
Organization accounts Buyers and sellers sign in with AWS Cognito and act for an organization
Listings from a set A seller lists a set or group with title, description, visibility, license options and price
Search and filters Robot model, task, frame rate, sensors, hours, format, price
Previews before purchase Short sample videos and synced multi-sensor playback
Standard licenses and contracts Click-to-accept templates; e-signature for custom deals
Held payment and payout Toborlife holds the buyer's money until the acceptance window closes, then pays the seller minus commission
Delivery in standard formats LeRobot or HDF5 by download, S3 copy or SDK
Audit trail Every order step written to audit_logs

Optional

Feature What it does
Automated QA before going live Unprocessed, trashed or not-ready episodes block a listing
Data requests A buyer posts requirements, budget and deadline; sellers reply with quotes
Requirement-based ranking Listings ranked by the robot type, tasks and formats a buyer says they need
Free sample datasets Small public samples published on Hugging Face to attract buyers
Quality score on listings Average aggregate_score shown on each listing
Import into the buyer's org Existing customers receive purchases as episodes in their own workspace
Consent and provenance records Proof of who collected the data and under what consent

End-to-end flow

Every listing passes automated QA before buyers can see it, and every payment is held by Toborlife until the buyer accepts the delivery.

flowchart TD
    subgraph Seller
        S1["Sign in or register<br/>AWS Cognito"] --> S2["Seller setup<br/>Agreement, payout details"]
        S2 --> S3["Create listing<br/>Pick a set, set price"]
        S5["Fix and resubmit<br/>Reasons from QA"]
        S10["Receive payout<br/>Price minus commission"]
    end
    subgraph Toborlife["Toborlife platform and admin"]
        T4["Publisher and previews<br/>Facets, QA, sample clips"] --> T5{"QA passes?"}
        T6["Listing live<br/>Indexed in OpenSearch"]
        T8["Hold payment, export<br/>Grant access, package"]
    end
    subgraph Buyer
        B1["Sign in or register<br/>AWS Cognito"] --> B7["Search and preview<br/>OpenSearch, CloudFront"]
        B7 --> B8["Sign license and pay<br/>Contract, held payment"]
        B9["Download or import<br/>Signed URL, S3 copy, SDK"]
    end
    S3 --> T4
    T5 -- no --> S5
    S5 --> S3
    T5 -- yes --> T6
    T6 --> B7
    B8 --> T8
    T8 --> B9
    B9 -- "7-day window" --> S10

Read each lane top down: the seller's work on the left, Toborlife's checks and holds in the middle, the buyer's steps on the right. A rejected listing loops back to the seller; after the acceptance window, the payout goes to the seller.

Flow 1: Sign in

Every buyer, seller and admin enters through the same AWS Cognito login; a role is a permission on an account, not a separate account.

  1. The user opens the marketplace subdomain.
  2. The app redirects to AWS Cognito.
  3. An existing Toborlife customer signs in with their current Cognito account. The platform matches them to users and to an active organization_members row (removed_at IS NULL).
  4. A new user registers in Cognito and a users row is added. They either create an organization, becoming its first Owner, or join one by accepting an invite through accept_member_invite(token, user_id).
  5. Cognito returns a signed token carrying the user's identity; the user picks which of their orgs to act for.
  6. On every request the API opens a transaction as tobor_app, runs SET LOCAL app.current_org and app.current_user, and resolves permissions from roles, role_permissions and user_permissions. RLS then limits every tenant read and write to that org.

One organization can hold both buyer and seller roles at the same time.

Flow 2: Seller onboarding

An organization can list data once it has accepted the seller agreement and added payout details.

  1. In the seller studio, an Owner (or a member whose role carries the new marketplace.sell permission) selects "Start selling". The API calls a marketplace function that creates the org's marketplace.seller_accounts row.
  2. The seller adds payout bank details with the marketplace payment provider; the reference is stored in marketplace.seller_accounts. The existing billing tables are not touched.
  3. The seller accepts the seller agreement: they own the data and hold consent from anyone recorded in it. The acceptance and agreement version are written to audit_logs.
  4. Members who should list data get marketplace.sell through role_permissions or user_permissions; role changes are recorded in role_change_logs. The org can now publish listings.

Flow 3: Publishing a listing

A listing points to a live set, so buyers always see the episodes the set holds now; each order records the exact episodes it delivered.

  1. Data in. Existing customers already have episodes organised into sets and groups. New orgs upload through upload_parts into the s3 bucket, then link episodes into a set (episode_sets).
  2. Listing. The seller picks a set (or a group) and adds a title, description, visibility (public, private or invite-only), license options and prices. The API calls marketplace.publish_listing(), which writes listings, a listing_versions row holding the set id (or group id) with status processing, listing_prices and an outbox_events row.
  3. Jobs started. The API starts the publisher and preview builder, each with app.current_org set to the seller org.
  4. Publisher worker. It reads the set's live episodes from episode_sets (for a group, through set_groups first) and joins episodes, episode_metadata, episode_tasks, robots and robot_models. QA fails the listing if any episode is trashed (deleted_at set), has a status other than processed, or has not cleared readiness_state. Facets record robot models, frame rate, degrees of freedom, sensors, tasks, hours, episode count and the average aggregate_score.
  5. Preview builder. It picks representative episodes, reads each one's mp4 from the s3 bucket, cuts short samples with FFmpeg plus Rerun files, writes them to previews and records them in listing_previews.
  6. Go live. If QA passes, the status becomes live and another outbox event is written. If it fails, the listing returns to the seller with the reasons.
  7. Search sync. The worker reads the outbox events and updates OpenSearch, so the listing becomes searchable.

When episodes are added to or removed from the set, the publisher reruns QA and refreshes facets and previews before the change reaches buyers. Past buyers keep exactly what their order delivered.

Flow 4: Discovery and preview

Buyers see listings ranked by their stated requirements and can watch samples, but never touch the videos bucket before paying.

  1. (Optional) On a first visit, the buyer answers a few questions: robot type, tasks, formats, budget. These are saved to their profile and used to rank listings.
  2. The buyer portal asks the API for listings. Search and filters go to OpenSearch, which returns matching listing IDs; listing details come from the marketplace schema on the read replica, never from seller tables.
  3. Visibility rules apply: private listings show only to invited organizations.
  4. Opening a listing streams previews from the previews bucket through CloudFront, or opens a multi-sensor sample in the embedded Rerun viewer.
  5. (Optional) If nothing fits, the buyer posts a data request (marketplace.data_requests) with requirements, budget and deadline. Sellers are emailed through SES and reply with offers in marketplace.quotes. An accepted quote enters Flow 5 as an order.

Flow 5: Purchase to payout

The order workflow (Step Functions) runs each purchase from checkout to payout; the buyer's money is held until the acceptance window closes.

sequenceDiagram
    participant B as Buyer (portal)
    participant A as Marketplace API
    participant W as Order workflow (Step Functions)
    participant X as External (payment, Dropbox Sign)
    participant D as Database (RDS primary)
    participant P as Export packager (S3)
    B->>A: Checkout
    A->>D: Create order
    A->>W: Start workflow
    W->>X: Create contract
    X-->>B: Accept or e-sign
    X-->>W: Signed (webhook)
    W->>P: PDF to contracts
    W->>X: Charge, hold funds
    X-->>W: Payment succeeded
    W->>D: Grant access
    W->>P: Start export job
    P-->>W: Export ready
    W->>B: Download link
    Note over B,P: Acceptance window, about 7 days, payout waits
    W->>X: Release payout
    W->>D: Order complete

Access is written only after the signed-contract and payment webhooks arrive; the payout is released after the acceptance window, not at checkout.

  1. Checkout. The buyer picks a listing version and license, such as commercial non-exclusive. The API confirms the listing is still live.
  2. Order created. The API writes marketplace.orders (status pending_contract) on the primary, recording the listing version, license template version, price and Toborlife fee. It also copies the set's current episode ids into marketplace.order_episodes, so the order fixes exactly what this buyer gets, then starts the workflow.
  3. Contract. Standard licenses are click-to-accept, generated from the license template. Custom or high-value deals go through a Dropbox Sign request signed by both parties. The signed PDF goes to the contracts bucket under Object Lock; its SHA-256 fingerprint goes to marketplace.contracts.
  4. Payment. The marketplace payment provider charges the buyer and Toborlife holds the funds. The result is recorded in marketplace.payments; the order becomes paid.
  5. Access granted. The workflow writes marketplace.entitlements, linking the buyer org to the order and its episodes. This is written to the primary, so access is live immediately. No resource_access_grants row is created: that table only grants access inside a single org.
  6. Export. The workflow starts the export packager with app.current_org set to the seller org. It reads the episode ids in marketplace.order_episodes, fetches each episode's mp4 and parquet from videos, converts to the chosen format (LeRobot, HDF5), and adds a manifest and the license. The package is written to exports and kept for the license term. An existing Toborlife customer can also import it into its own org as new episodes, running with app.current_org set to the buyer org.
  7. Delivery. The buyer is emailed through SES and notified in the portal. Downloads use short-lived presigned URLs from IAM/STS; each download and SDK pull is logged.
  8. Acceptance window. The workflow waits about seven days.
  9. Payout. After the window, Toborlife pays the seller's share through the marketplace payment provider (price minus commission). The payout is recorded in marketplace.payouts and the order becomes complete.

Every step writes to audit_logs, so admin can replay any order's history.

Flow 6: Admin operations

The admin console uses the same API with admin-only permissions.

  • Set commission and featured listings.
  • Remove listings or suspend accounts that break the rules.
  • Watch dashboards for sales, failed jobs and payment problems; CloudWatch alerts the team when a worker fails, a job keeps retrying or payments start failing.