Skip to main content

Concepts

The five terms you need to know before writing queries against the Geo API.

Space

A governance container. Two flavors:

  • Personal space — owned by one wallet. The wallet controls every edit.
  • DAO space — community-governed. Edits go through a proposal/voting flow before being applied.

Every entity lives in at least one space. The space determines who can publish edits and who can vote on them.

Entity

A node in the graph. An entity has:

  • An id (UUID, stored as bytes16 hex on chain)
  • A name (text)
  • An optional description (text)
  • Zero or more values — typed property data ({ property, value, type })
  • Zero or more relations — typed edges to other entities

Entities are typeless until you tag them. There's no class-vs-instance distinction the way there is in traditional ORMs.

Type

A tag applied to an entity via a Types relation. To say "this entity is a Project," you create a relation from the entity to the Project type entity using the Types property.

Two important consequences:

  1. An entity can have multiple types (e.g. both Project and Open Source).
  2. Types themselves are entities. The "Project" type entity has a name, an ID, and is tagged with the meta-type Schema Type.

Property

A field definition. Defines:

  • The property's name and ID
  • Its data type (Text, Integer, Float, Boolean, Date, URL, Relation, etc.)
  • Optional metadata (description, format hints)

When you publish a value on an entity, you reference the property's ID:

{
property: "a126ca530c8e48d5b88882c734c38935", // "Name" property
value: { type: "text", value: "Stable Diffusion" }
}

Like types, properties are themselves entities tagged with the meta-type Property.

Relation

A directed edge between two entities, with its own ID and its own type. Unlike values (which are scalar fields on a single entity), relations are first-class graph edges.

A relation has:

  • id — the relation's own UUID
  • fromEntityId — the source entity (joined as fromEntity in queries)
  • toEntityId — the target entity (joined as toEntity)
  • typeId — the property that defines what kind of edge this is (joined as typeEntity)

Every type tag is a relation (entity → type, with typeEntity.name = "Types"). Every authored connection is a relation (project → person, with typeEntity.name = "Authors"). Every block attachment is a relation (entity → text block, with typeEntity.name = "Blocks").

This is the part of the model that surprises people coming from SQL — there's no foreign key column. There's an entity with a typed relation pointing somewhere else, and that's how you traverse.

Putting it together

A Project entity in a DAO Space might look like:

Stable Diffusion (entity)
├── values
│ ├── Name: "Stable Diffusion"
│ ├── Description: "Latent diffusion model..."
│ └── GitHub Stars: 68000
└── relations
├── Types → Project (entity → type)
├── Authors → Robin Rombach (entity → person)
├── Authors → Patrick Esser (entity → person)
├── Backed by → Stability AI (entity → organization)
└── Topics → Generative AI (entity → topic)

Each line under values is a value op. Each line under relations is a createRelation op. Each target (Project, Robin Rombach, etc.) is itself an entity with its own ID and its own values/relations.

You're now ready for the Cookbook.