Skip to content
FurniOps
NewConnect AI agents over MCP

One catalogue from every vendor. Live in every system you run.

FurniOps reads your vendors' APIs, feeds, files and websites, builds one master record for every product with the source of each field, and tells your systems within seconds when a price or stock level changes.

curl api.furniops.com/v1/products
app.furniops.com
The FurniOps dashboard's Home: changes, webhook deliveries, catalogue freshness and API calls today, a 30-day chart of API calls and a setup guide
  • Any source

    Vendor APIs, price files and storefront feeds, read politely.

  • One master record

    Every field keeps its source, when it was seen and how sure we are.

  • Changes in seconds

    Signed webhooks, a live stream and an ordered change feed.

  • Agents propose

    AI suggests fixes, proved on recorded data. It never writes master data.

For developers

Your catalogue in a few lines. SDK, HTTP, CLI or MCP.

Read every product once, then follow each change as it happens. The same calls work from the TypeScript SDK, plain HTTP, the CLI, or an AI agent over MCP.

  • Typed from the OpenAPI spec: every route is a method
  • Zero dependencies: fetch and Web Crypto, in Node, Deno, Bun and Workers
  • Retries, idempotency keys, typed errors and auto-pagination
  • A change stream that reconnects, and webhook verification
Language
sync.ts
import { FurniOps } from "@furniops/sdk";

const apiKey = process.env["FURNIOPS_API_KEY"] ?? "";
const furniops = new FurniOps({ apiKey });

// Everything that changed since your last sync, page by page.
const lastSync = "2026-10-05T00:00:00Z";
const changed = furniops.products.list({ updated_since: lastSync });
for await (const product of changed) {
  console.log(product.id, product.data.title);
}

// Then follow the change feed live: it reconnects and resumes itself.
const stream = furniops.changes.stream({ types: "offer.changed" });
for await (const { type, event } of stream) {
  console.log(type, event.subject, event.time);
}
Terminal
# Everything that changed since your last sync
curl -G https://api.furniops.com/v1/products \
  -d updated_since=2026-10-05T00:00:00Z \
  -H "Authorization: Bearer $FURNIOPS_API_KEY"

# Then the change feed: wait up to 25 s for the next event
curl -G https://api.furniops.com/v1/changes \
  -d types=offer.changed -d wait=25 -d cursor=$CURSOR \
  -H "Authorization: Bearer $FURNIOPS_API_KEY"
Terminal
# Sign in once, in the browser
furniops login

# Forward events to your handler as signed deliveries, no tunnel needed
furniops listen --forward-to localhost:3000/webhooks \
  --events offer.changed

# In another terminal: emit a sample event in test mode
furniops trigger offer.changed
Terminal
# Claude Code: sign in to FurniOps when it asks
claude mcp add --transport http furniops https://mcp.furniops.com/mcp

# Claude, ChatGPT or Cursor: add the same URL as a custom connector
# Each tool is a public API route, with its permissions and limits

How it works

From every source to every system. Every field sourced.

FurniOps keeps what each source says, builds one master record from it field by field, and sends every change on through the channels your systems already listen to.

  1. 01

    Sources

    Each source is checked about as often as it changes, faster for what you are selling now.

    • Vendor APIsA connector per vendor's API
    • Price filesCSV or Excel, uploaded or emailed
    • Storefront feedsShopify stores, read incrementally
    • Website probesThe best way into any vendor's site
  2. 02

    Master record

    Normalised, matched across vendors, and every field keeps its source.

    Bellamy 3-Seat Sofaprod_…

    title
    Bellamy 3-Seat SofaMarlow Living API · mapped
    cost
    $949.00Ashby & Cole price file · mapped
    colour
    OatmealNorthgate Home feed · AI · 0.86
    quantity
    12 at DALMarlow Living API · mapped
  3. 03

    Delivery

    A price or stock change reaches your systems within seconds.

    • WebhooksSigned, retried for about three days
    • Change feedOrdered and replayable for 30 days
    • Live streamServer-sent events that resume
    • API and SDKRead any record, any time
    • MCPThe same routes for AI agents

See it move

Every change, the moment it lands. Signed and replayable.

Sample data from a fictional retailer and its vendors: the events your systems receive, one webhook delivery up close, and how often each source is checked.

Change feedsample events

  1. 10:00:30offer.changedSloane Marble Coffee Tableincoming 24, due Oct 21
  2. 10:00:25variant.updatedAvery 6-Drawer Dresserdimensions, from Ashby & Cole price file
  3. 10:00:14offer.changedLinden King Platform Bedavailability low_stock → in_stock
  4. 10:00:12product.updatedCove Swivel Accent Chairdescription, from Marlow Living API
  5. 10:00:05offer.changedHarlow Round Dining Tablequantity 12 → 3
  6. 10:00:02offer.changedBellamy 3-Seat Sofacost $899.00 → $949.00

Webhook deliveryPOST /hooks/furniops

Delivered
  1. 10:00:02503Service Unavailable1.2 s
  2. 10:00:03503Service Unavailable0.9 s
  3. 10:00:08204No Content38 ms
webhook-id
evt_034XqBaL2mRLTZPXyRbaUi
webhook-timestamp
1791108002
webhook-signature
v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
FurniOps-Version
2026-10-04
{
  "id": "evt_034XqBaL2mRLTZPXyRbaUi",
  "type": "offer.changed",
  "spec_version": "1.0",
  "source": "furniops/catalog",
  "subject": "ofr_034XqBaL2mRLTZPXyRbaUg",
  "time": "2026-10-04T10:00:02Z",
  "tenant_id": "org_034XqBaL2mRLTZPXyRbaUj",
  "version": 12,
  "schema_version": 1,
  "correlation_id": "run_034XqBaL2mRLTZPXyRbaUk",
  "causation_id": null,
  "livemode": true,
  "data": {
    "id": "ofr_034XqBaL2mRLTZPXyRbaUg",
    "variant": "var_034XqBaL2mRLTZPXyRbaUf",
    "source": "src_034XqBaL2mRLTZPXyRbaUh",
    "catalogue": "cat_034XqBaL2mRLTZPXyRbaUd",
    "location": "DAL",
    "availability": "in_stock",
    "version": 12,
    "facets": [
      "price"
    ],
    "fields": [
      {
        "path": "cost",
        "old": 89900,
        "new": 94900,
        "provenance": {
          "source": "src_034XqBaL2mRLTZPXyRbaUh",
          "method": "mapped",
          "confidence": 1,
          "observed_at": "2026-10-04T10:00:00Z"
        }
      }
    ]
  }
}

Retried at once, then after 5 s, 5 min, 30 min and on to 14 h: eleven attempts over about three days, in order per object.

Freshnesslearned schedules

Sample sources, how often each is checked, and when next
SourceNext check
Marlow Living APIstock · every 30 minin 0:47
Marlow Living APIcatalogue · every 4 hin 2:14:05
Northgate Home feedcatalogue · every 12 hAnswered 503 three runs in a rowin 9:30
Ashby & Cole price filecatalogue · when a file arriveson arrival

Bellamy 3-Seat Sofa is in shoppers' carts, so every source offering it is checked every 15 minutes until that demand lapses.

Features

Everything between a vendor and your store. Handled for you.

FurniOps does the work no retailer wants to staff: reading every vendor, keeping the data right, and telling your systems the moment it changes.

  • Sources

    Whatever shape a vendor's data comes in

    A vendor is configuration, not code: its API, the price files it uploads or emails, or its Shopify storefront. Several at once, if that is what it takes, and a probe finds the best way into a site you have not read before.

    • Every raw pull is kept, so anything can be re-read and proven
    • Corrupt, incomplete and implausible data is quarantined, never published

    Read today

    • Vendor APIs
    • CSV files
    • Excel files
    • Uploads
    • Email inbox
    • Shopify storefronts
    • Website probes
    How FurniOps works
  • Freshness

    Checked as often as it changes

    Each source's schedule learns how often it really changes, inside a budget that keeps us polite. What you sell now is checked first.

    • Price and stock travel a fast lane of their own
    • An unchanged catalogue costs a hash comparison, not a write
    Freshness
  • Matching and provenance

    One record, every field sourced

    The same sofa from three sources becomes one product with a stable ID, and each field says where it came from, when it was seen and how sure we are.

    • Matched on identifiers, text and pictures
    • Close calls wait for a person; every merge can be undone
    Master records
  • Webhooks

    Signed, retried, replayable

    Standard Webhooks signatures with secrets you can rotate, retries for about three days, and a delivery log you can replay from.

    • Filter each endpoint by event, vendor or category
    • Thin events with what changed, or the whole object
    Your first webhook
  • Identity and SSO

    Sign-in your security team will sign off

    Passkeys first, authenticator apps and recovery codes, and single sign-on with your OpenID Connect provider on the domains you prove.

    • Roles for every member, and restricted keys down to read or write per resource
    • OAuth 2.1 apps of your own, with secrets that rotate
  • AI and MCP

    Agents that propose, never overwrite

    Connect Claude, ChatGPT or Cursor over MCP with the same permissions as the API. Inside FurniOps, agents file categories, repair mappings, onboard sources and explain failures.

    • Proposals are checked against recorded data before they apply
    • Every agent has an autonomy level, a daily budget and an audit trail

    Terminal

    $ claude mcp add --transport http \
        furniops https://mcp.furniops.com/mcp
    MCP server
  • Security

    Isolated by design

    Each organisation's data is fenced in the code and again by row-level security in Postgres, so a request for another organisation's record finds nothing.

    • One audit log for every change, the people and keys included
    • Unusual API key activity is flagged for review
    Webhook security

Developer experience

Built for the developer who ships it. Sandbox, CLI and docs.

A sandbox to break things in, a CLI that brings events to your laptop, and docs that answer the next question before you ask it.

  • fo_test_…
    Sandbox cataloguesample products, never capped
    fo_live_…
    Live catalogueyour vendors' real data

    Test mode

    Every organisation has a sandbox catalogue with sample data. Test keys reach only the sandbox, and the API, feed and webhooks behave exactly as they do live.

    Test mode
  • $ furniops listen --forward-to localhost:3000

    • 10:00:02offer.changed[204]12 ms
    • 10:00:09product.updated[500]3 ms
    • 10:00:11product.updated[204]9 ms

    The CLI

    furniops listen forwards live events to a handler on localhost, signed exactly as real deliveries are, with no tunnel to set up.

    furniops listen
  • The docs

    Concepts, guides, the full API reference and a page for every error, with copyable examples. The whole site is also published as llms.txt for your AI tools.

    Read the docs

Changelog

Shipped lately. Newest first.

New in FurniOps, newest first. Every entry links to the docs that explain it.

All updates
  1. The MCP server

    Connect Claude, ChatGPT, Cursor or any MCP client to your catalogue. Every tool is a public API route, so the same permissions, plan, rate limits and request logs apply.

  2. AI agents that propose, and prove it

    Four agents now watch your catalogue: they file products into categories, repair a mapping when a vendor's file changes, onboard a new source from a probe, and explain what went wrong in a run.

  3. Your own OAuth apps, and 31 days of request logs

    Register OAuth apps for your organisation, and read every API request your keys, apps and members made, kept for 31 days.

Your vendors, one catalogue. Start with the first today.