Documentation
Open GeoFeed Protocol
Conceptual guide to OGP's core primitives. For formal schemas and field-level specs, see the Protocol Spec.
Overview
OGP is built on a simple premise: every piece of local activity — a restaurant's daily special, a store opening, a neighborhood event — happens at a specific place in a specific part of the world. OGP gives that place a stable, human-readable identifier and defines how activity feeds anchored to it are published, discovered, and consumed.
The protocol has three layers:
A geographic hierarchy of slugs — SubdivisionPaths. These are the primary keys of the protocol.
A DNS-like root that maps paths to authoritative content servers. Operated by geofeed.ai, open to anyone.
ActivityPub-based activity streams published by any actor (business, person, government) for any path.
The registry and the protocol spec are operated by geofeed.ai and licensed Apache 2.0. Any implementation — including Findera — is a conforming server that can register with the public registry.
SubdivisionPath
A SubdivisionPath is the canonical identifier for a geographic subdivision. It is a slash-separated sequence of lowercase slugs, starting with an ISO 3166-1 alpha-3 country code.
Alpha-2 normalization
Paths may begin with a 2-letter country code (ISO 3166-1 alpha-2). They are silently normalized to alpha-3.
br/sp/sao-paulo becomes
bra/sp/sao-paulo.
All canonical storage and API responses use alpha-3.
Short paths
Some contexts expose a short form that omits the country prefix when the country is implicit:
sp/sao-paulo/tatuape.
Short paths are display-only — canonical storage and all API responses always use the full path.
Subdivision Context
A SubdivisionPath is always resolved within a context. A context defines which geographic hierarchy is active for a country. The same physical subdivision can have different paths in different contexts.
Context IDs follow the format {COUNTRY}-{scheme},
e.g. BRA-administrative.
Each country has exactly one default context. When a context is not specified in a request,
the country's default context is used.
Context is never embedded in the path string itself. It is passed as a query parameter:
Hierarchy & local_level
Every subdivision has a SubdivisionType with a numeric
local_level that defines its position in the hierarchy.
Higher values = more granular.
| local_level | type_id | name (Brazil) | example path |
|---|---|---|---|
| 1 | bra | País | bra |
| 2 | bra-state | Estado (UF) | bra/sp |
| 3 | bra-municipality | Município | bra/sp/sao-paulo |
| 4 | bra-district | Distrito | bra/sp/sao-paulo/se |
| 5 | bra-subdistrict | Subdistrito | bra/sp/sao-paulo/se/bela-vista |
| 6 | bra-neighborhood | Bairro | bra/sp/sao-paulo/tatuape |
The minimal_local_level parameter on reverse geocoding
endpoints controls response granularity. For example,
minimal_local_level=3 returns at most the municipality
level — useful when neighborhood precision is unnecessary or unavailable.
Parent-child relationships
Relationships are stored as a many-to-many through table scoped by context (SubdivisionHierarchy).
A subdivision can have multiple parents within a context — e.g., a neighborhood that spans district
boundaries. Root nodes are self-referencing: parent == child.
GeoFeed Format
GeoFeeds use the ActivityStreams 2.0 wire
format (as used by ActivityPub). OGP extends it with a single
geopath field on any
Place or Object.
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://geofeed.ai/ns/v1"
],
"type": "Create",
"actor": {
"type": "Organization",
"id": "https://findera.app/actors/salao-gi-matos",
"name": "Salão Gi Matos",
"geopath": "bra/sp/sao-paulo/tatuape"
},
"object": {
"type": "Note",
"geopath": "bra/sp/sao-paulo/tatuape",
"content": "Agenda aberta para esta semana!",
"published": "2025-03-23T10:00:00Z"
}
}
Because OGP uses ActivityStreams, any Fediverse client can consume an OGP feed without modification.
The geopath field is additive — it doesn't break
existing ActivityPub implementations that don't understand it.
Actor types
Any Schema.org type may be used for actors. Commonly used types:
Registry Architecture
The registry operates like DNS root servers: it knows what geopaths exist and which servers are authoritative for them, but delegates actual content to registered servers. Anyone can register as a content server without permission from the registry operator.
Server types
Static presence — name, address, contact. No activity feed. Corresponds to Findera Presença (free tier).
Activity feed — posts, events, offers anchored to the geopath. Updated periodically.
Real-time feed — high-frequency updates, sensor data, live events. Corresponds to Findera Pro.
Promoted placement — shown above organic results in registry responses. Findera Ads layer.
API Endpoints
All endpoints are read-only (GET). The same data is served via three subdomains in different formats. Server registration is not yet open — contact geofeed.ai.
Returns registry metadata for a geopath.
Lists direct children of a geopath.
Reverse geocodes a coordinate to a geopath. Queries local DB first; falls back to Google Maps.
Resolves a path to its full registry metadata.
Geocodes a free-form address to a geopath via Google Maps + local registry.
Suggests geopaths as the user types. Returns signed tokens to avoid re-querying on selection.
Hint System
Reverse geocoding responses include a hint field
that tells the consumer where the result originated:
Result found in the local registry database. Fast, fully resolved, includes a Subdivision ID.
Result came from an external source (Google Maps). May not have a matching subdivision in the registry yet. A MissingGeoPath record is created for data quality tracking.
Both values are valid GeoPath responses. The
subdivision field is only populated on
internal hints.
Consumers should handle both gracefully.