Skip to main content

Knowledge Graph (SPARQL, RDF & Vault-LD)

Everything your agents remember is projected into a W3C RDF knowledge graph. It's not a separate database — the same store that does remember / recall also exposes a queryable, validatable, dereferenceable graph built on open standards:

  • RDF / Turtle / JSON-LD — lossless graph projection of your memory.
  • SPARQL 1.1 — read-only SELECT / ASK / CONSTRUCT over your namespace.
  • SHACL — validate data against shapes derived from your ontology.
  • OWL RL — materialize inferred triples (subclass, transitive, inverse).
  • OWL-Time + PROV-O — bi-temporal validity and provenance on every edge.
  • Dereferenceable IRIs — every entity resolves at memory.ainative.studio.

Base URL: https://api.ainative.studio/api/v1/public/memory/v2/graph · Authorization: Bearer <token>

All graph routes are namespace-scoped

Every endpoint below is scoped to the caller's tenant + namespace. A query, resolve, or descriptor can only ever name nodes in your own namespace — there is no cross-tenant read path.


IRI scheme

Entities, classes, and concepts get stable IRIs so they can be referenced, linked, and dereferenced:

https://memory.ainative.studio/{tenant}/{namespace}/{kind}/{local}
  • tenant — your tenant id.
  • namespaceglobal | project-<id> | session-<id>.
  • kindentity | class | property | concept | scheme.
  • local — a stable slug for the node.

Two different tenants — or two namespaces within a tenant — never share an IRI, so an IRI is a safe, collision-free global name for a fact.

Dereferenceable. These IRIs resolve over HTTP — GET the IRI directly (with your token) and it content-negotiates Turtle / JSON-LD / Markdown:

curl -H "Authorization: Bearer $TOKEN" -H "Accept: text/turtle" \
"https://memory.ainative.studio/{tenant}/{namespace}/entity/{local}"

Auth-required and tenant-isolated: you can only dereference IRIs in your own graph (401 without a token, 403 if the IRI belongs to another tenant).


POST /sparql — query the graph

A read-only SPARQL 1.1 endpoint. SELECT, ASK, and CONSTRUCT are allowed; any update form (INSERT, DELETE, LOAD, CLEAR, …) is rejected, and result rows are capped — safe to expose directly to an agent.

curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"https://api.ainative.studio/api/v1/public/memory/v2/graph/sparql" -d '{
"query": "SELECT ?person ?role WHERE { ?person a mem:Person ; mem:hasRole ?role } LIMIT 25"
}'

Response (application/json): SPARQL JSON results for SELECT/ASK; Turtle for CONSTRUCT.

FieldTypeDescription
querystringrequired — a SPARQL 1.1 read query
max_rowsintoptional cap (server enforces an upper bound)
reasonboolwhen true, augments the graph with OWL-RL inferred triples (transitive/inverse/subclass closure) before querying

Write queries return 400 with a read-only violation; oversized result sets are truncated to the row cap.


POST /vault-ld/validate — SHACL validation

Validate your graph against SHACL shapes auto-derived from your ontology (domain / range / datatype). Returns a structured report — catch contradictions and malformed edges before they poison recall.

curl -X POST -H "Authorization: Bearer $TOKEN" \
"https://api.ainative.studio/api/v1/public/memory/v2/graph/vault-ld/validate"

Response: {"conforms": true|false, "violation_count": N, "violations": [...]}. Each violation carries focus_node, path, message, severity. Namespace-scoped; never mutates your data.


POST /vault-ld/materialize — git/Obsidian vault

Materialize your namespace as a {path: text} map of .md notes + context.jsonld — exactly what you'd write to disk and open in Obsidian.

curl -X POST -H "Authorization: Bearer $TOKEN" \
"https://api.ainative.studio/api/v1/public/memory/v2/graph/vault-ld/materialize"

Response: {"vault": {"<path>": "<text>", ...}, "file_count": N, "note_count": N, "instructions": "..."}. Write the files, git init && git commit, open the folder in Obsidian — wiki-links resolve, and editing a note round-trips back into the graph via import/vault-ld.


GET /vault-ld/resolve — dereference your namespace

Content-negotiated dereference of your namespace vault. This is the on-ramp used by the resolver at memory.ainative.studio.

curl -H "Authorization: Bearer $TOKEN" \
"https://api.ainative.studio/api/v1/public/memory/v2/graph/vault-ld/resolve?format=turtle"
format= (or Accept:)Media type
turtle (text/turtle)text/turtle
jsonld (application/ld+json)application/ld+json
markdown (text/markdown)text/markdown

Add ?project_id=<id> to scope to a project namespace.


GET /vault-ld/dprod — data-product descriptor

Returns a DPROD DataProduct descriptor (Turtle) for your namespace — the machine-readable catalog entry that advertises the graph's distributions (Turtle / JSON-LD / Markdown) and their access URLs.

curl -H "Authorization: Bearer $TOKEN" \
"https://api.ainative.studio/api/v1/public/memory/v2/graph/vault-ld/dprod"
@prefix dprod: <https://ekgf.github.io/dprod/> .
@prefix dcat: <http://www.w3.org/ns/dcat#> .
@prefix dcterms: <http://purl.org/dc/terms/> .

<https://memory.ainative.studio/{tenant}/{namespace}/#data-product> a dprod:DataProduct ;
dcterms:title "ZeroMemory Data Product" ;
dprod:outputPort <.../#turtle>, <.../#jsonld>, <.../#markdown> .

<https://memory.ainative.studio/{tenant}/{namespace}/#turtle> a dcat:Distribution ;
dcat:mediaType "text/turtle" ;
dcat:accessURL <https://memory.ainative.studio/{tenant}/{namespace}/?format=turtle> .

GET /export/vault-ld · POST /import/vault-ld

Export the whole namespace graph as a Vault-LD vault (markdown notes + context.jsonld) or Turtle, and import a vault back — losslessly.

# Export as Vault-LD (git/Obsidian-friendly notes)
curl -H "Authorization: Bearer $TOKEN" \
".../memory/v2/graph/export/vault-ld?format=vault-ld"

# Export as Turtle (RDF)
curl -H "Authorization: Bearer $TOKEN" \
".../memory/v2/graph/export/vault-ld?format=turtle"

# Import a vault back
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
".../memory/v2/graph/import/vault-ld" -d '{ "files": { "alice.md": "..." } }'

The importer reports {status, lossless, flagged, ...}. Constructs that can't be represented losslessly (e.g. certain blank nodes / language-tagged literals) are flagged, never silently dropped — so a round-trip is either exact or explicitly annotated.


Bi-temporal edges & provenance

Every relationship is reified as an RDF statement carrying validity time (OWL-Time time:Interval with validFrom / validUntil), a supersededBy link, a PROV-O trail (prov:wasDerivedFrom, prov:wasGeneratedBy), and a trust level. That's what lets you ask "what did the agent believe as of last Tuesday?" — an as-of query — instead of only reading the latest state.


Round-trip & standards

The graph is a faithful RDF projection: export to Turtle and re-import, and the graph is isomorphic to the original (verified against the reference Vault-LD tooling). Built on RDF, SPARQL 1.1, SHACL, OWL-Time, PROV-O, SKOS, schema.org, and DPROD — so your knowledge graph is portable and interoperable by construction, not locked to us.

See also: Memory Interchange (MIF & Vault-LD) for the single-memory export/import surface and provider migration.