All Value Types — GRC-20 Reference
The Geo wire format (GRC-20 v2) defines 11 value types. Every value attached to an entity carries data in exactly one of these. The API's Value type exposes a typed scalar field for each — only one is non-null per Value, depending on the property's declared dataType.
The mapping
| GRC-20 type | Value field | Example data | Notes |
|---|---|---|---|
| Boolean | boolean | true, false | Real booleans, not "yes"/"no" strings |
| Integer | integer | "68000", "2009" | Returned as string-encoded BigInt |
| Float | float | 0.763, -12.5 | IEEE 754 double |
| Decimal | decimal | "19.99" | Arbitrary precision (Req #11 — lossless) |
| Text | text | "Stable Diffusion" | UTF-8, may have language BCP-47 tag |
| Bytes | bytes | "SGVsbG8=" | Base64-encoded byte array |
| Timestamp | datetime (and datetimeUtc) | "2022-08-22T14:30:00Z" | ISO 8601 with timezone |
| Date | date | "2022-08-22Z" | Calendar date, no time |
| Point | point | [lon, lat] | WGS84 coordinate |
| Embedding | embedding | [0.12, -0.45, ...] | JSON array of floats (vector) |
| Ref | (via entity accessor) | — | Reference to another entity. Most "ref" semantics are modeled as relations, not values |
The Value type also exposes a few extras not in GRC-20's 11: time, timeUtc, schedule, rect. They're useful but not part of the wire spec's core list.
Universal "select-everything" query
Always select every typed field you might care about. Only the matching one is non-null; the rest return null. That way the same query works for any property.
query AllValuesOfEntity($id: UUID!) {
entity(id: $id) {
name
values(first: 50) {
nodes {
propertyEntity { name }
text
integer
float
boolean
decimal
date
datetime
point
embedding
bytes
language
unit
}
}
}
}
{ "id": "9e49e5a95d2a41a6ba90cd84944080b5" }
Real response (excerpt)
{
"data": {
"entity": {
"name": "Stable Diffusion",
"values": {
"nodes": [
{
"propertyEntity": { "name": "Date founded" },
"date": "2022-08-22Z",
"text": null,
"integer": null
},
{
"propertyEntity": { "name": "Website" },
"text": "https://stability.ai/stable-image",
"language": "090adac0-fca4-822e-8e71-9263e67620ec",
"date": null
},
{
"propertyEntity": { "name": "Description" },
"text": "Stable Diffusion is an open-source text-to-image diffusion model.",
"language": "090adac0-fca4-822e-8e71-9263e67620ec"
}
]
}
}
}
}
Per-type tips
Integer — string-encoded BigInt
Integers come back as strings to preserve precision. A GitHub star count of 68000 is "68000" in JSON.
const stars = BigInt(value.integer); // safe for arbitrarily large ints
const starsAsNumber = Number(value.integer); // OK if you know it fits in 53 bits
Date vs Datetime
- Date =
YYYY-MM-DD(no time component):"2022-08-22Z" - Datetime = full timestamp:
"2022-08-22T14:30:00Z"
If you only have a year + month ("2022-08"), GRC-20 rejects it. Always store full YYYY-MM-DD.
Decimal — preserves precision
Use decimal for money, scientific measurements, or anywhere a float would lose precision (Req #11):
{ values(first: 1 filter: { decimal: { isNull: false } }) {
decimal # returned as exact string
propertyEntity { name }
} }
Float is faster but lossy. Decimal is exact but more expensive. Pick based on whether you need exactness.
Text + language tag
Text values can carry an optional language (BCP-47 reference). Multi-language data is modeled as multiple Values on the same property, each with a different language:
query MultilingualValues($id: UUID!) {
entity(id: $id) {
values(first: 10) {
nodes { text language } # group by language client-side
}
}
}
Embedding — vector data
embedding is a JSON array of floats. Useful for semantic search applications:
const vec: number[] = JSON.parse(value.embedding);
// cosine similarity, ANN, etc.
Point — WGS84 coordinate
point is a tuple [longitude, latitude]. Order matters — longitude first.
Bytes — opaque byte array
bytes returns base64-encoded data. Decode client-side:
const raw = Uint8Array.from(atob(value.bytes), c => c.charCodeAt(0));
Notes
- Only one scalar field is non-null per Value. Always over-select the typed fields you care about — the others come back null.
unitis a free-form string hint (e.g."USD","meters","GB") — doesn't affect the value's actual encoding, but useful for display.- Spec source: see GRC-20 v2 requirements Req #9, #11 for the canonical type list and precision guarantees.