Optional but powerful

Universal Fields

Six optional fields you can add to anything you store. Add dates, people, places, amounts, text, or files — then search across everything at once.

The Six Types

T

_texts

Words, messages, descriptions. Automatically searchable by keyword or meaning.

Array of strings.
Multiple entries for title + body, multilingual, or multi-part content.
D

_dates

When things happened or will happen. Search by time range across everything.

start needed for indexing, end tz label optional.
Standard date format.
@

_identifiers

People, companies, accounts — anyone or anything involved.

Type and value needed for indexing.
Name, role, and label are optional.
B

_blobs

Images, documents, attachments — any file, linked to what it belongs to.

Link and file type needed for indexing.
name size optional.
G

_locations

Addresses and locations. Find everything near a specific place.

Latitude and longitude needed for indexing.
name address city country optional.
#

_amounts

Money, quantities, measurements. Find everything above or below a threshold.

value needed for indexing (number).
unit label optional. Standard currency codes (USD, EUR, etc.)

Design Principles

Optional, never enforced

These fields are completely optional. Add them when they're useful. Everything works without them.

Always lists

Every field is a list, even for single values. Consistent, no special cases.

Search everywhere

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.

Writes always succeed

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.

Independent from validation

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.


Full Example

A meeting with all six fields

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.


Identifier Types

Types are not enforced — any string works. These are common conventions:

TypeExample ValueIdentifies
email[email protected]A person
tel+1555123456A phone number
keyabc123...An IO ocean key
dropwork/meetings\0q3-reviewAnother drop (route\0key)
githuboctocatA GitHub account
domainexample.comA domain / asset
ibanDE89370400...A bank account
eik123456789A company registration
urlhttps://example.comAn external URL

Cross-Folder Search

Search across all your data at once. Combine filters — find meetings in March with Bob near Copenhagen, in one question.

By Date Range

Everything in March 2026

{
  "dates": {
    "$gte": "2026-03-01",
    "$lt": "2026-04-01"
  }
}

By Location

Within 5 km of Copenhagen

{
  "locations": {
    "$near": {
      "lat": 55.68,
      "lon": 12.57,
      "radius_km": 5
    }
  }
}

By Identifier

Everything involving Bob

{
  "identifiers": {
    "$has": {
      "type": "email",
      "value": "[email protected]"
    }
  }
}

By Amount

USD amounts over 1000

{
  "amounts": {
    "$gte": 1000,
    "$unit": "USD"
  }
}

Combined Query

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" }
  }'

Drops Command

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"

Identifier query variants

{ "$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


Folder-Scoped Queries

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 }
  }'

For AI Agents

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.

AI Tool Call

query_primitives

{
  "dates": { "$gte": "2026-03-01" },
  "identifiers": {
    "$has": "[email protected]"
  },
  "locations": {
    "$near": {
      "lat": 55.68,
      "lon": 12.57,
      "radius_km": 10
    }
  }
}

Why This Matters

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.