Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring content
Preparing Ring content
Preparing Ring content
Entities are the organization profiles at the center of Ring’s product loop: discover or create a profile, invite members, post opportunities, optionally activate a store, and keep discovery fresh after every mutation.
Use Founder / Developer tabs in the docs sidebar to filter this page. Sidebar article visibility is controlled by lib/docs/audience-curated-docs.ts (Layer1); this page is curated for both audiences.
Entities are not a business-directory page bolted on later — they are the primary organization record that opportunities, vendor stores, verification procedures, and Tunnel discovery hang off.
| Concern | What Ring ships |
|---|---|
| Industry catalog | Vertical preset via ring-config entities.preset (platform = 26 types; agricultural = alternate catalog) |
| Visibility | public · subscriber · member · confidential (+ isConfidential flag) |
| Verification | Queue statuses none → pending / under_review → verified / rejected via POST /api/entities/{id}/verify |
| Team | addedBy owner, members[], and stored invite roles in memberRoles (OWNER, ADMIN, MEMBER); invite by existing-user email |
| Guests | Visitors can open /entities and /entities/<id> without an account and see public, non-confidential profiles (since 2026-10-17) |
| Groups | Optional parentEntityId links a branch to a group entity, and optional geo holds coordinates |
| Freshness | syncEntityDiscovery() — cache tags, revalidatePath, Tunnel entity:* |
| Data plane | PostgreSQL JSONB through DatabaseService; UI reads SerializedEntity (ISO dates) |
Your settlers and operators need a trusted organization surface: who we are, which industry we claim, who can see us, and how we collaborate. Entities give each organization that surface without a separate CRM.
Members create profiles at /entities/add; public and role-gated listings at /entities.
/entities/my tabs: All (owned), Store (owned + storeActivated), Member of.
Jobs and partnerships attach to an entity — verified presence improves trust in matching.
No. The active catalog comes from entities.preset. Default platform ships 26 industry ids (technologySoftware … other). agricultural swaps in a wellness/farm vertical catalog. Clones can overlay presets via ringdom-clone-build.
They are Ring’s native org graph for discovery, opportunities, store, and confidential desks — not a LinkedIn sync product.
Yes. Public, non-confidential entities are listed and viewable without signing in. Everything else still needs an account.
Authenticated users with member privileges (or platform admin / confidential role mapping). Confidential entities require confidential access (canCreateEntity).
DELETE /api/entities/{id} with JSON { "confirm": true }, or the UI delete flow under /entities/[id]/delete. Missing confirm returns 400.
The Store tab only lists entities where addedBy === currentUser and storeActivated === true. Activate the vendor store first.
No. requestEntityVerification opens/submits a verification_procedures record (entity_identity) and sets entity verificationStatus to pending. Review is an ops/admin workflow.
Next-step: REST/MCP contract detail for the same CRUD, invite, verify, and analytics routes.
Depends-on: how syncEntityDiscovery invalidates caches and publishes Tunnel entity:* events.
Same-workflow: opportunities attach to entities as organizationId / members post from entity context.
Next-step: activate storeActivated on an entity and operate the multi-vendor marketplace.
Entities are the organization profiles at the center of Ring’s product loop: discover or create a profile, invite members, post opportunities, optionally activate a store, and keep discovery fresh after every mutation.
Use Founder / Developer tabs in the docs sidebar to filter this page. Sidebar article visibility is controlled by lib/docs/audience-curated-docs.ts (Layer1); this page is curated for both audiences.
Entities are not a business-directory page bolted on later — they are the primary organization record that opportunities, vendor stores, verification procedures, and Tunnel discovery hang off.
| Concern | What Ring ships |
|---|---|
| Industry catalog | Vertical preset via ring-config entities.preset (platform = 26 types; agricultural = alternate catalog) |
| Visibility | public · subscriber · member · confidential (+ isConfidential flag) |
| Verification | Queue statuses none → pending / under_review → verified / rejected via POST /api/entities/{id}/verify |
| Team | addedBy owner, members[], and stored invite roles in memberRoles (OWNER, ADMIN, MEMBER); invite by existing-user email |
| Guests | Visitors can open /entities and /entities/<id> without an account and see public, non-confidential profiles (since 2026-10-17) |
| Groups | Optional parentEntityId links a branch to a group entity, and optional geo holds coordinates |
| Freshness | syncEntityDiscovery() — cache tags, revalidatePath, Tunnel entity:* |
| Data plane | PostgreSQL JSONB through DatabaseService; UI reads SerializedEntity (ISO dates) |
Your settlers and operators need a trusted organization surface: who we are, which industry we claim, who can see us, and how we collaborate. Entities give each organization that surface without a separate CRM.
Members create profiles at /entities/add; public and role-gated listings at /entities.
/entities/my tabs: All (owned), Store (owned + storeActivated), Member of.
Jobs and partnerships attach to an entity — verified presence improves trust in matching.
No. The active catalog comes from entities.preset. Default platform ships 26 industry ids (technologySoftware … other). agricultural swaps in a wellness/farm vertical catalog. Clones can overlay presets via ringdom-clone-build.
They are Ring’s native org graph for discovery, opportunities, store, and confidential desks — not a LinkedIn sync product.
Yes. Public, non-confidential entities are listed and viewable without signing in. Everything else still needs an account.
Authenticated users with member privileges (or platform admin / confidential role mapping). Confidential entities require confidential access (canCreateEntity).
DELETE /api/entities/{id} with JSON { "confirm": true }, or the UI delete flow under /entities/[id]/delete. Missing confirm returns 400.
The Store tab only lists entities where addedBy === currentUser and storeActivated === true. Activate the vendor store first.
No. requestEntityVerification opens/submits a verification_procedures record (entity_identity) and sets entity verificationStatus to pending. Review is an ops/admin workflow.
Next-step: REST/MCP contract detail for the same CRUD, invite, verify, and analytics routes.
Depends-on: how syncEntityDiscovery invalidates caches and publishes Tunnel entity:* events.
Same-workflow: opportunities attach to entities as organizationId / members post from entity context.
Next-step: activate storeActivated on an entity and operate the multi-vendor marketplace.
Entities are the organization profiles at the center of Ring’s product loop: discover or create a profile, invite members, post opportunities, optionally activate a store, and keep discovery fresh after every mutation.
Use Founder / Developer tabs in the docs sidebar to filter this page. Sidebar article visibility is controlled by lib/docs/audience-curated-docs.ts (Layer1); this page is curated for both audiences.
Entities are not a business-directory page bolted on later — they are the primary organization record that opportunities, vendor stores, verification procedures, and Tunnel discovery hang off.
| Concern | What Ring ships |
|---|---|
| Industry catalog | Vertical preset via ring-config entities.preset (platform = 26 types; agricultural = alternate catalog) |
| Visibility | public · subscriber · member · confidential (+ isConfidential flag) |
| Verification | Queue statuses none → pending / under_review → verified / rejected via POST /api/entities/{id}/verify |
| Team | addedBy owner, members[], and stored invite roles in memberRoles (OWNER, ADMIN, MEMBER); invite by existing-user email |
| Guests | Visitors can open /entities and /entities/<id> without an account and see public, non-confidential profiles (since 2026-10-17) |
| Groups | Optional parentEntityId links a branch to a group entity, and optional geo holds coordinates |
| Freshness | syncEntityDiscovery() — cache tags, revalidatePath, Tunnel entity:* |
| Data plane | PostgreSQL JSONB through DatabaseService; UI reads SerializedEntity (ISO dates) |
Your settlers and operators need a trusted organization surface: who we are, which industry we claim, who can see us, and how we collaborate. Entities give each organization that surface without a separate CRM.
Members create profiles at /entities/add; public and role-gated listings at /entities.
/entities/my tabs: All (owned), Store (owned + storeActivated), Member of.
Jobs and partnerships attach to an entity — verified presence improves trust in matching.
No. The active catalog comes from entities.preset. Default platform ships 26 industry ids (technologySoftware … other). agricultural swaps in a wellness/farm vertical catalog. Clones can overlay presets via ringdom-clone-build.
They are Ring’s native org graph for discovery, opportunities, store, and confidential desks — not a LinkedIn sync product.
Yes. Public, non-confidential entities are listed and viewable without signing in. Everything else still needs an account.
Authenticated users with member privileges (or platform admin / confidential role mapping). Confidential entities require confidential access (canCreateEntity).
DELETE /api/entities/{id} with JSON { "confirm": true }, or the UI delete flow under /entities/[id]/delete. Missing confirm returns 400.
The Store tab only lists entities where addedBy === currentUser and storeActivated === true. Activate the vendor store first.
No. requestEntityVerification opens/submits a verification_procedures record (entity_identity) and sets entity verificationStatus to pending. Review is an ops/admin workflow.
Next-step: REST/MCP contract detail for the same CRUD, invite, verify, and analytics routes.
Depends-on: how syncEntityDiscovery invalidates caches and publishes Tunnel entity:* events.
Same-workflow: opportunities attach to entities as organizationId / members post from entity context.
Next-step: activate storeActivated on an entity and operate the multi-vendor marketplace.
An entity can become a vendor; store metrics appear on entity analytics for owners/members.
visibility: confidential entities for restricted collaboration (/confidential/entities).entities.preset to agricultural (or a clone overlay preset) so industry pickers match the niche instead of the default 26 platform industries.Platform verification is a review queue, not a marketing badge ladder. Owners/admins request review; platform staff resolve via verification procedures (subjectType: entity_identity).
entities.preset in ring-config.json (empire org overlay uses platform).features/entities/services/create-entity.ts, update-entity.ts, delete-entity.ts |
| Invite / verify / analytics | invite-entity-member.ts, request-entity-verification.ts, get-entity-analytics.ts |
| My Entities views | features/entities/lib/my-entities-views.ts (all | store | member) |
| Server Actions | app/_actions/entities.ts |
| Ownership gate | features/entities/lib/assert-entity-owner.ts (addedBy or platform admin) |
Empire overlay (ring-platform-org) does not fork entity services in web/ for this feature — compose Layer1; locales/config may overlay via merge.
| Route | Purpose |
|---|---|
/[locale]/entities | Discovery list |
/[locale]/entities/add | Create form |
/[locale]/entities/my | Owned / store / member tabs |
/[locale]/entities/[id] | Showcase / detail |
/[locale]/entities/[id]/edit | Edit |
/[locale]/entities/[id]/delete | Delete confirm UI |
/[locale]/confidential/entities | Confidential listing |
/[locale]/entities/status/[action]/[status] | Status feedback page |
| Method | Path | Notes |
|---|---|---|
GET | /api/entities | List / query |
POST | /api/entities/create | Create |
GET | /api/entities/{id} | Detail |
PUT | /api/entities/{id} | Full update |
PATCH | /api/entities/{id} | Partial (Zod entityPatchSchema) |
DELETE | /api/entities/{id} | Body { "confirm": true } required |
POST | /api/entities/{id}/verify | Queue verification |
POST | /api/entities/{id}/invite | Invite existing user by email |
GET | /api/entities/{id}/analytics | Owner / member / platform admin |
POST | /api/entities/upload | Authenticated media upload |
MCP mirrors: /api/mcp/v1/entities, /api/mcp/v1/entities/search, /api/mcp/v1/entities/{id}.
Discovery filters use platform roles (visitor → admin). Confidential rows require hasConfidentialAccess. Setting visibility: confidential or isConfidential: true on create/update is gated the same way.
Authenticate as a user who may create entities (canCreateEntity — member+; confidential create needs confidential access).
Call the service (or POST /api/entities/create). Required shape centers on name, type, descriptions, addedBy, locale, location, visibility, members, opportunities.
After mutations, rely on syncEntityDiscovery — do not invent a separate search-index table; PostgreSQL JSONB is SSOT.
Invite role (OWNER | ADMIN | MEMBER) is now stored in memberRoles[userId] as well as members[]. assertEntityOwnerOrAdmin accepts addedBy, a stored OWNER or ADMIN role, or a platform admin. features/entities/lib/entity-roles.ts adds getEntityMemberRole, assertEntityRole and loadViewerEntityAccessIds, which also grants access to child entities of a group you belong to. Members invited before this change have no stored role and count as MEMBER.
GET /api/entities and the /entities page resolve anonymous callers to role visitor. getEntityById no longer throws for guests on public rows; non-public rows still require a session. Creating an entity as a guest redirects to login with callbackUrl back to /entities/add.
GET /api/entities/{id}/analytics returns EntityAnalytics: member count, opportunity id list length, linked opportunities (organizationId count), verification / moderation fields, optional storeMetrics / storeVerification, and generatedAt.
See-also: role ladder and confidential access patterns that gate entity visibility.
An entity can become a vendor; store metrics appear on entity analytics for owners/members.
visibility: confidential entities for restricted collaboration (/confidential/entities).entities.preset to agricultural (or a clone overlay preset) so industry pickers match the niche instead of the default 26 platform industries.Platform verification is a review queue, not a marketing badge ladder. Owners/admins request review; platform staff resolve via verification procedures (subjectType: entity_identity).
entities.preset in ring-config.json (empire org overlay uses platform).features/entities/services/create-entity.ts, update-entity.ts, delete-entity.ts |
| Invite / verify / analytics | invite-entity-member.ts, request-entity-verification.ts, get-entity-analytics.ts |
| My Entities views | features/entities/lib/my-entities-views.ts (all | store | member) |
| Server Actions | app/_actions/entities.ts |
| Ownership gate | features/entities/lib/assert-entity-owner.ts (addedBy or platform admin) |
Empire overlay (ring-platform-org) does not fork entity services in web/ for this feature — compose Layer1; locales/config may overlay via merge.
| Route | Purpose |
|---|---|
/[locale]/entities | Discovery list |
/[locale]/entities/add | Create form |
/[locale]/entities/my | Owned / store / member tabs |
/[locale]/entities/[id] | Showcase / detail |
/[locale]/entities/[id]/edit | Edit |
/[locale]/entities/[id]/delete | Delete confirm UI |
/[locale]/confidential/entities | Confidential listing |
/[locale]/entities/status/[action]/[status] | Status feedback page |
| Method | Path | Notes |
|---|---|---|
GET | /api/entities | List / query |
POST | /api/entities/create | Create |
GET | /api/entities/{id} | Detail |
PUT | /api/entities/{id} | Full update |
PATCH | /api/entities/{id} | Partial (Zod entityPatchSchema) |
DELETE | /api/entities/{id} | Body { "confirm": true } required |
POST | /api/entities/{id}/verify | Queue verification |
POST | /api/entities/{id}/invite | Invite existing user by email |
GET | /api/entities/{id}/analytics | Owner / member / platform admin |
POST | /api/entities/upload | Authenticated media upload |
MCP mirrors: /api/mcp/v1/entities, /api/mcp/v1/entities/search, /api/mcp/v1/entities/{id}.
Discovery filters use platform roles (visitor → admin). Confidential rows require hasConfidentialAccess. Setting visibility: confidential or isConfidential: true on create/update is gated the same way.
Authenticate as a user who may create entities (canCreateEntity — member+; confidential create needs confidential access).
Call the service (or POST /api/entities/create). Required shape centers on name, type, descriptions, addedBy, locale, location, visibility, members, opportunities.
After mutations, rely on syncEntityDiscovery — do not invent a separate search-index table; PostgreSQL JSONB is SSOT.
Invite role (OWNER | ADMIN | MEMBER) is now stored in memberRoles[userId] as well as members[]. assertEntityOwnerOrAdmin accepts addedBy, a stored OWNER or ADMIN role, or a platform admin. features/entities/lib/entity-roles.ts adds getEntityMemberRole, assertEntityRole and loadViewerEntityAccessIds, which also grants access to child entities of a group you belong to. Members invited before this change have no stored role and count as MEMBER.
GET /api/entities and the /entities page resolve anonymous callers to role visitor. getEntityById no longer throws for guests on public rows; non-public rows still require a session. Creating an entity as a guest redirects to login with callbackUrl back to /entities/add.
GET /api/entities/{id}/analytics returns EntityAnalytics: member count, opportunity id list length, linked opportunities (organizationId count), verification / moderation fields, optional storeMetrics / storeVerification, and generatedAt.
See-also: role ladder and confidential access patterns that gate entity visibility.
An entity can become a vendor; store metrics appear on entity analytics for owners/members.
visibility: confidential entities for restricted collaboration (/confidential/entities).entities.preset to agricultural (or a clone overlay preset) so industry pickers match the niche instead of the default 26 platform industries.Platform verification is a review queue, not a marketing badge ladder. Owners/admins request review; platform staff resolve via verification procedures (subjectType: entity_identity).
entities.preset in ring-config.json (empire org overlay uses platform).features/entities/services/create-entity.ts, update-entity.ts, delete-entity.ts |
| Invite / verify / analytics | invite-entity-member.ts, request-entity-verification.ts, get-entity-analytics.ts |
| My Entities views | features/entities/lib/my-entities-views.ts (all | store | member) |
| Server Actions | app/_actions/entities.ts |
| Ownership gate | features/entities/lib/assert-entity-owner.ts (addedBy or platform admin) |
Empire overlay (ring-platform-org) does not fork entity services in web/ for this feature — compose Layer1; locales/config may overlay via merge.
| Route | Purpose |
|---|---|
/[locale]/entities | Discovery list |
/[locale]/entities/add | Create form |
/[locale]/entities/my | Owned / store / member tabs |
/[locale]/entities/[id] | Showcase / detail |
/[locale]/entities/[id]/edit | Edit |
/[locale]/entities/[id]/delete | Delete confirm UI |
/[locale]/confidential/entities | Confidential listing |
/[locale]/entities/status/[action]/[status] | Status feedback page |
| Method | Path | Notes |
|---|---|---|
GET | /api/entities | List / query |
POST | /api/entities/create | Create |
GET | /api/entities/{id} | Detail |
PUT | /api/entities/{id} | Full update |
PATCH | /api/entities/{id} | Partial (Zod entityPatchSchema) |
DELETE | /api/entities/{id} | Body { "confirm": true } required |
POST | /api/entities/{id}/verify | Queue verification |
POST | /api/entities/{id}/invite | Invite existing user by email |
GET | /api/entities/{id}/analytics | Owner / member / platform admin |
POST | /api/entities/upload | Authenticated media upload |
MCP mirrors: /api/mcp/v1/entities, /api/mcp/v1/entities/search, /api/mcp/v1/entities/{id}.
Discovery filters use platform roles (visitor → admin). Confidential rows require hasConfidentialAccess. Setting visibility: confidential or isConfidential: true on create/update is gated the same way.
Authenticate as a user who may create entities (canCreateEntity — member+; confidential create needs confidential access).
Call the service (or POST /api/entities/create). Required shape centers on name, type, descriptions, addedBy, locale, location, visibility, members, opportunities.
After mutations, rely on syncEntityDiscovery — do not invent a separate search-index table; PostgreSQL JSONB is SSOT.
Invite role (OWNER | ADMIN | MEMBER) is now stored in memberRoles[userId] as well as members[]. assertEntityOwnerOrAdmin accepts addedBy, a stored OWNER or ADMIN role, or a platform admin. features/entities/lib/entity-roles.ts adds getEntityMemberRole, assertEntityRole and loadViewerEntityAccessIds, which also grants access to child entities of a group you belong to. Members invited before this change have no stored role and count as MEMBER.
GET /api/entities and the /entities page resolve anonymous callers to role visitor. getEntityById no longer throws for guests on public rows; non-public rows still require a session. Creating an entity as a guest redirects to login with callbackUrl back to /entities/add.
GET /api/entities/{id}/analytics returns EntityAnalytics: member count, opportunity id list length, linked opportunities (organizationId count), verification / moderation fields, optional storeMetrics / storeVerification, and generatedAt.
See-also: role ladder and confidential access patterns that gate entity visibility.