A small mobile service business, fully described.
Bob runs a plumbing shop out of a Dallas suburb. He has a Google
Business Profile and a Yelp page, but no website worth scraping.
An agent that wants to dispatch a plumber tonight at 2am needs
to know, verifiably, that Bob is open, licensed, in range, and
capable of fielding the call. The UBI listing below is what that
agent reads. The same shape works for a Manhattan dentist, a
Topeka feed store, or a global SaaS. Only the capabilities
block differs.
facet_id: ubi:us:tx:dallas:75002:bobs-plumbing # global stable ID nap: name: "Bob's Plumbing" address: { street, city, state, postal, country, lat, lng } service_area: [{ type: radius_miles, value: 25 }] # for mobile/service biz phone, email, website, social: { instagram, fb, tiktok, ... } hours: regular: { mon: [09:00-17:00], tue: ..., ... } exceptions: [{ date: 2026-12-25, closed: true }] seasonal: { open_from, open_until } status: open_now | closed_now | seasonal | permanently_closed category: naics: 238220 google_place_type: plumber facet_taxonomy: [home_services, plumbing, emergency_24_7] identity: claim_status: unclaimed | claimed_unverified | verified_owner | kyc_verified verification_methods: [postcard, phone_otp, dns_txt, gmb_oauth, stripe_kyc] licenses: [{ jurisdiction, type, number, verified_via, expires }] reputation: facet_score: 4.6 agent_review_count: 142 human_review_count: 1283 # imported from Google/Yelp/BBB if licensed dispute_rate: 0.4% response_time_p50_hours: 2.3 capabilities: # which primitives this listing supports - view_only # always (Bucket 5 to 7) - click_to_call # most (Bucket 4) - book_appointment # subset (Bucket 2) - request_quote # subset (Bucket 3) - purchase_catalog # subset (Bucket 1) provenance: sources: [google_places, yelp_fusion, owner_claim, web_crawl, state_license_registry] last_verified: 2026-04-30T18:22Z signed_by: kid:facet-prod-2026-04
Pseudo-syntax note. The address, social,
hours.regular, hours.seasonal, and licenses blocks above use a
compact key-list shorthand ({ street, city, state, ... }) for
readability. Live UBI documents inflate each shorthand to fully
typed sub-objects per the JSON Schema referenced below. A fully
inflated JSON version of this exact example is available at
ubi-sample-listing.json.
Eight blocks. One document. Globally addressable.
The schema is intentionally narrow. NAP, hours, category, and provenance are the universal Maps/Yelp baseline; identity, reputation, and capabilities are what makes a UBI listing machine-actionable rather than scrape-fodder.
ubi:<country>:<region>:<city>:<postal>:<slug>.
Mobile or no-postal businesses use
ubi:<country>:<region>:mobile:<slug>;
online-only businesses use ubi:online:<domain-slug>.
The ID is stable for the lifetime of the entity. Moves and
renames are recorded as new provenance rows, never
ID changes.
service_area is required for
mobile or dispatch businesses without a fixed customer-
facing address; the address block is optional in that case.
status is a
computed enum derived from the prior three plus the current
timestamp. Agents should trust status rather
than re-derive it client-side.
claim_status progresses
unclaimed → claimed_unverified →
verified_owner → kyc_verified;
each tier unlocks more capabilities (see §03).
verification_methods lists which channels the
owner actually proved control through. licenses
captures regulator-issued credentials with the verifying
authority and expiration.
view_only; a KYC-verified
merchant supports the full set up through
purchase_catalog. Agents that attempt an
unsupported capability get a typed
403 CAPABILITY_NOT_GRANTED with an upgrade
pointer, same pattern as the
tool ladder.
sources records every
channel that contributed a field (Google Places, Yelp
Fusion, owner claim, web crawl, state-licensing registries).
last_verified is the most recent successful
re-check across any source.
signed_by names the Facet signing key
(kid:facet-prod-YYYY-MM rotation cadence) so
downstream consumers can verify the document hasn't been
tampered with in flight. Each source is also a typed
ingestion lane in
Facet's knowledge graph, see §05.
Four tiers. Each unlocks one more thing the agent can do.
Listings progress monotonically through four
claim_status
values. Each tier is a strict superset of the prior tier's
capabilities. No listing ever loses primitives short of an
explicit revoke. Most businesses spend their entire lifetime
in unclaimed;
the ones that show up in agent search results don't.
The schema lives upstream of this page.
This page renders the listing example in marketing-friendly form. The authoritative schema, ER diagram, and JSON Schema validator live in the Facet protocol repo and version independently of the marketing site.
UBI is Facet's proprietary knowledge graph in document form.
Each listing is a flat projection of nodes and edges that live
in Facet's proprietary knowledge-graph layer.
nap,
licenses,
and
category
decompose into nodes;
capabilities,
verification_methods,
and
provenance.sources
become typed edges. Agents that need traversal queries,
"find me a kyc_verified plumber within 25 miles
who hasn't had a dispute in the last 90 days", query the
graph directly. The flat document is just one of many views.
X-Facet-Version-pinned
terminal API. Same wire shape, same auth, same rate
limits. No shadow APIs, no preferred access.
DELETE WHERE (org_id, source) = ... ingestion lanes; idempotent re-projection per source; full ownership of the storage layer.