Six optional fields you can add to anything you store. Add dates, people, places, amounts, text, or files — then search across everything at once.
Words, messages, descriptions. Automatically searchable by keyword or meaning.
When things happened or will happen. Search by time range across everything.
start needed for indexing, end tz label optional.People, companies, accounts — anyone or anything involved.
Images, documents, attachments — any file, linked to what it belongs to.
name size optional.
Addresses and locations. Find everything near a specific place.
name address city country optional.
Money, quantities, measurements. Find everything above or below a threshold.
value needed for indexing (number).unit label optional. Standard currency codes (USD, EUR, etc.)
These fields are completely optional. Add them when they're useful. Everything works without them.
Every field is a list, even for single values. Consistent, no special cases.
These fields are searchable across all your data, not just one folder. "Show me everything involving [email protected]" works whether the data lives in work/meetings, contacts, or invoices.
If a universal field is malformed or missing sub-fields (e.g. a _dates entry without start), the record saves normally — the field just won't appear in cross-folder search results. No errors, no rejections. This is by design: an append-only system never refuses your data.
Universal fields and patterns (define/validate) are independent systems. Patterns validate your payload structure. Universal fields index specific sub-structures for cross-folder search. They don't interact — you can use one, both, or neither.
This single record is now searchable by date, location, person, amount, text, or any combination — across all your data.
-- Save a meeting with universal fields save work/meetings @q3-budget-review title: "Q3 Budget Review" status: "confirmed" _texts: ("Q3 Budget Review — quarterly budget discussion") _dates: ({"start": "2026-03-15T09:00:00Z", "end": "2026-03-15T10:30:00Z", "tz": "Europe/Copenhagen"}) _identifiers: ( {"type": "email", "value": "[email protected]", "name": "Alice", "role": "organizer"}, {"type": "email", "value": "[email protected]", "name": "Bob", "role": "attendee"}, {"type": "eik", "value": "123456789", "name": "Acme Corp"} ) _locations: ({"lat": 55.6761, "lon": 12.5683, "name": "HQ Copenhagen"}) _amounts: ({"value": 250000, "unit": "USD", "label": "budget"}) _blobs: ({"url": "/blob/q3-slides", "mime": "application/pdf", "name": "Q3-Budget.pdf"})
Note: nested objects inside arrays still use {} — but the outer structure is clean key:value pairs. Simple fields like _texts need no braces at all.
Types are not enforced — any string works. These are common conventions:
| Type | Example Value | Identifies |
|---|---|---|
email | [email protected] | A person |
tel | +1555123456 | A phone number |
key | abc123... | An IO ocean key |
drop | work/meetings\0q3-review | Another drop (route\0key) |
github | octocat | A GitHub account |
domain | example.com | A domain / asset |
iban | DE89370400... | A bank account |
eik | 123456789 | A company registration |
url | https://example.com | An external URL |
Search across all your data at once. Combine filters — find meetings in March with Bob near Copenhagen, in one question.
Everything in March 2026
{
"dates": {
"$gte": "2026-03-01",
"$lt": "2026-04-01"
}
}
Within 5 km of Copenhagen
{
"locations": {
"$near": {
"lat": 55.68,
"lon": 12.57,
"radius_km": 5
}
}
}
Everything involving Bob
{
"identifiers": {
"$has": {
"type": "email",
"value": "[email protected]"
}
}
}
USD amounts over 1000
{
"amounts": {
"$gte": 1000,
"$unit": "USD"
}
}
All filters AND together. Find meetings in March, involving Bob, with budgets over $1000:
curl -X POST https://api.infiniteocean.io/primitives \
-H "X-Ocean-Key: YOUR_KEY" \
-d '{
"dates": { "$gte": "2026-03-01", "$lt": "2026-04-01" },
"identifiers": { "$has": { "type": "email", "value": "[email protected]" } },
"amounts": { "$gte": 1000, "$unit": "USD" }
}'
Query primitives directly from Drops:
-- Find everything involving Bob primitives identifiers email "[email protected]" -- Find and email Bob's upcoming meetings primitives identifiers email "[email protected]" then pick title, _dates then send email to "[email protected]" subject "Your meetings"
{ "$has": { "type": "email", "value": "[email protected]" } } — exact type + value
{ "$has": "[email protected]" } — value across all types
{ "$type": "email" } — all items with email identifiers
{ "$any": [{ "type": "email", "value": "[email protected]" }, ...] } — OR match
Add a primitives filter to POST /query to use smart field indexes within a single folder — combines with existing filters, sort, and aggregation.
curl -X POST https://api.infiniteocean.io/query \
-H "X-Ocean-Key: YOUR_KEY" \
-d '{
"prefix": "work/meetings",
"latest": true,
"primitives": {
"dates": { "$gte": "2026-03-01" },
"identifiers": { "$has": { "type": "email", "value": "[email protected]" } }
},
"filter": { "payload.status": "confirmed" },
"sort": { "payload.title": 1 }
}'
AI assistants can search across all your data using these fields — no setup needed. Natural queries like "find everything involving Bob near Copenhagen in March" map directly to smart field filters.
query_primitives
{
"dates": { "$gte": "2026-03-01" },
"identifiers": {
"$has": "[email protected]"
},
"locations": {
"$near": {
"lat": 55.68,
"lon": 12.57,
"radius_km": 10
}
}
}
No per-folder context needed
Without smart fields, your AI needs to know where everything is stored. With smart fields, it just asks: "who is Bob?" — and gets everything, from everywhere.