NewRelease 0.12.3 is out: Engine v0.12.3, Dashboard 0.5.2, Helm 0.12.3, the four SDKs, CLI 0.8.2 and MCP 0.12.3Release 0.12.3 is outSee what's new →
Advanced Retrieval

Knowledge Graph Entity Linking

⏱ ~45 min to implement 📦 Requires: Dakera v0.12.2+

Go beyond flat semantic search. Turn on entity extraction and Dakera tags every stored memory with the named entities it mentions and links memories that share an entity into a traversable graph, enabling multi-hop retrieval your vector store simply cannot do.

Get Started Free →
Prerequisites
  • Running Dakera server (Quickstart guide)
  • Familiarity with graph concepts (nodes, edges, traversal depth)
  • Dakera Python, TypeScript, Rust, or Go SDK installed

The Problem with Flat Memory

Vector search finds semantically similar memories but cannot reason about relationships. The query "Who works at the company providing our cloud hosting?" requires chaining three facts across separate memories: a person's employer, that employer's vendor contracts, and which vendor handles cloud. A flat vector store returns unrelated chunks. You need a graph.

Building and maintaining that graph yourself adds weeks of infrastructure work: entity extraction pipelines, a graph store, traversal APIs. With entity extraction turned on for an agent's namespace, Dakera tags every memory you store with the entities it mentions and links it to the agent's other memories, so store_memory is all your agent calls.

How Dakera extracts entities

Extraction is opt-in per namespace: set "extract_entities": true and the entity_types you care about (for example person, organization, technology) with PATCH /v1/namespaces/{ns}/config. A rule-based pre-pass finds dates, URLs, UUIDs, emails and IP addresses; GLiNER, a zero-shot named-entity model served locally through ONNX, finds the types you listed, with no external API calls. LLM providers are available per namespace instead. Each memory is tagged entity:<type>:<value>. The GLiNER model (about 782 MB) downloads on first use; a store into an extracting namespace waits up to 10 s for it, then answers 503 with Retry-After.

Architecture: How the Graph Is Built

The nodes of Dakera's graph are memories, and entities are tags on them. When a memory is stored, Dakera links it to the same agent's other memories with typed edges: by similarity and, when the namespace extracts entities, by shared entity. Your agent can add its own edges with explicit links. Questions about entities ("everything about Acme Corp") follow the shares_entity edges between the memories that mention them.

Memory Graph: CRM Agent Example

Memory graph built from four CRM memories in a namespace that extracts entities. Sarah Kim is VP Sales at Acme Corp shares the entity Acme Corp with Marcus Lee evaluates AWS for Acme Corp, and the entity Sarah Kim with Sarah Kim is leading the CloudMigrate Q2 deal, which shares CloudMigrate Q2 with CloudMigrate Q2 deal is $240k. Dakera creates these shares_entity edges on store. The deal memory also has an explicit linked_by edge to the AWS memory, labeled uses_vendor by the application.Memory graph built from four CRM memories in a namespace that extracts entities. Sarah Kim is VP Sales at Acme Corp shares the entity Acme Corp with Marcus Lee evaluates AWS for Acme Corp, and the entity Sarah Kim with Sarah Kim is leading the CloudMigrate Q2 deal, which shares CloudMigrate Q2 with CloudMigrate Q2 deal is $240k. Dakera creates these shares_entity edges on store. The deal memory also has an explicit linked_by edge to the AWS memory, labeled uses_vendor by the application.
Memories are the nodes; shared entities and explicit links are the edges.Full size ↗Full size ↗

The Five Edge Types

Edge TypeCreated whenUse case
related_toTwo memories have a cosine similarity of at least 0.85Semantic clustering and association
shares_entityTwo memories carry the same entity:* tagEntity-centric retrieval ("everything about Acme Corp")
precedesA related memory was created before anotherTimelines and event chains
linked_byYou link two memories with POST /v1/memories/{id}/linksCustom associations, with an optional label
supersedesA newer memory is very similar (cosine of at least 0.92) to an older one and shares an entity with itRecall demotes the outdated fact

Typed business relations such as "works at" or "uses vendor" are application data. Keep them in the memory text, where extraction and recall can use them, or record them as explicit links with a label, as the example does with uses_vendor.

What Happens on Every Store

With extraction on, each store_memory call runs the same steps: extract entities, tag the memory, then link it into the agent's graph. A memory that mentions an entity another memory already carries gets a shares_entity edge to it, so "Acme Corp" in two memories connects them without any schema on your side.

Workflow of what Dakera does on every store_memory() call in a namespace that extracts entities. A rule-based pre-pass finds dates, URLs, UUIDs, emails and IP addresses, and GLiNER, running locally through ONNX, finds the entity types the namespace lists. The memory is tagged entity:type:value and linked into the agent's memory graph: related_to for similar memories, shares_entity for memories with the same entity tag, precedes for timelines and supersedes for a newer version of a fact. Your agent adds linked_by edges with POST /v1/memories/{id}/links.Workflow of what Dakera does on every store_memory() call in a namespace that extracts entities. A rule-based pre-pass finds dates, URLs, UUIDs, emails and IP addresses, and GLiNER, running locally through ONNX, finds the entity types the namespace lists. The memory is tagged entity:type:value and linked into the agent's memory graph: related_to for similar memories, shares_entity for memories with the same entity tag, precedes for timelines and supersedes for a newer version of a fact. Your agent adds linked_by edges with POST /v1/memories/{id}/links.
Extract, tag, link: shared entities connect memories without a schema.Full size ↗Full size ↗
Tip: Entity extraction is one config call

You do not need to label entities or define schemas. Turn extraction on for the agent's namespace once, store natural language memories, and Dakera tags and links them. The graph grows as your agent learns more about the world it operates in.

Real-World Scenario: CRM Agent

A CRM agent needs to answer questions like: "What other deals does the champion on the Acme renewal know about?" or "Which contacts at Acme Corp are evaluating AWS?" These require multi-hop traversal, which vector search alone cannot do.

  1. Turn on extraction and index contact data
    Set extract_entities with the types person, organization, technology and deal on the agent's namespace (_dakera_agent_crm-agent). Then store meeting notes, email summaries, and deal updates as memories; GLiNER tags people, companies, and deal names on every store.
  2. Let the graph grow over time
    When you store "Sarah Kim is VP Sales at Acme Corp" and later "Sarah Kim is leading the CloudMigrate Q2 deal", both carry the tag for Sarah Kim, so Dakera links them with a shares_entity edge. Relations your application knows for certain can be added as explicit links with a label.
  3. Traverse for multi-hop answers
    Traverse from a memory at depth 2 (GET /v1/memories/{id}/graph?depth=2, at most 5) to reach memories one or two shared entities away, or find the path between two memories with GET /v1/memories/{id}/path, without writing graph traversal code yourself.
  4. Combine graph results with semantic recall
    Use traversal to collect the memories around an entity, then call recall() with the user's question to rank supporting memories. Graph narrows scope; recall provides context.
  5. Update stale facts
    When contacts change companies or deals close, store the new fact. A newer memory that is very similar to an older one and shares an entity with it gets a supersedes edge, and recall demotes the outdated fact. Forget memories that should not be kept at all.

Implementation

# 1. Create the agent and turn on entity extraction for its namespace
curl -X POST http://localhost:3000/v1/agents \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "crm-agent"}'

curl -X PATCH http://localhost:3000/v1/namespaces/_dakera_agent_crm-agent/config \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{"extract_entities": true, "entity_types": ["person", "organization", "technology", "deal"]}'

# 2. Store memories: each one is tagged entity:<type>:<value> and linked into the graph
curl -X POST http://localhost:3000/v1/memory/store \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "crm-agent",
    "content": "Sarah Kim is VP Sales at Acme Corp",
    "importance": 0.9,
    "memory_type": "semantic",
    "tags": ["crm", "contact"]
  }'

curl -X POST http://localhost:3000/v1/memory/store \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "crm-agent",
    "content": "Marcus Lee evaluates AWS for Acme Corp",
    "importance": 0.85,
    "memory_type": "semantic",
    "tags": ["crm", "contact"]
  }'

# 3. See the entities extracted from a memory
curl http://localhost:3000/v1/memory/entities/mem_sarah \
  -H "Authorization: Bearer dk-..."

# 4. Traverse the graph from a memory (BFS, depth 2; the server caps depth at 5)
curl "http://localhost:3000/v1/memories/mem_sarah/graph?depth=2" \
  -H "Authorization: Bearer dk-..."

# 5. Shortest path between two memories
curl "http://localhost:3000/v1/memories/mem_sarah/path?to=mem_marcus" \
  -H "Authorization: Bearer dk-..."

# 6. Record an application-level relation as an explicit link (edge type linked_by)
curl -X POST http://localhost:3000/v1/memories/mem_deal/links \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "crm-agent", "target_id": "mem_marcus", "label": "uses_vendor"}'

# 7. Export the agent's whole graph
curl http://localhost:3000/v1/agents/crm-agent/graph/export \
  -H "Authorization: Bearer dk-..."
from dakera import DakeraClient

client = DakeraClient(base_url="http://localhost:3000", api_key="dk-...")
AGENT = "crm-agent"

# Turn on entity extraction for the agent's namespace (once)
client.create_agent(AGENT)  # v0.12.2; otherwise the first store creates it
client.configure_namespace_ner(
    f"_dakera_agent_{AGENT}",
    extract_entities=True,
    entity_types=["person", "organization", "technology", "deal"],
)

# Store memories: each is tagged entity:<type>:<value> and linked into the graph
sarah = client.store_memory(agent_id=AGENT, content="Sarah Kim is VP Sales at Acme Corp",
                            importance=0.9, memory_type="semantic", tags=["crm", "contact"])
marcus = client.store_memory(agent_id=AGENT, content="Marcus Lee evaluates AWS for Acme Corp",
                             importance=0.85, memory_type="semantic", tags=["crm", "contact"])
lead = client.store_memory(agent_id=AGENT, content="Sarah Kim is leading the CloudMigrate Q2 deal",
                           importance=0.85, memory_type="semantic", tags=["crm", "deal"])
deal = client.store_memory(agent_id=AGENT, content="CloudMigrate Q2 deal is $240k",
                           importance=0.8, memory_type="semantic", tags=["crm", "deal"])

# Entities Dakera extracted from a memory
for e in client.memory_entities(sarah["id"]).entities:
    print(e.entity_type, e.value)  # one line per entity: its type and value

# An application-level relation: link the deal to the AWS evaluation (edge type linked_by)
client.memory_link(deal["id"], marcus["id"], agent_id=AGENT, label="uses_vendor")

# Multi-hop: "Who at Acme Corp knows about AWS?"
# BFS from the Sarah memory: memories that share Acme Corp are one hop away
graph = client.memory_graph(sarah["id"], depth=2)
for node in graph.nodes:
    print(node.depth, node.content_preview)
for edge in graph.edges:
    print(edge.source_id, edge.edge_type.value, edge.target_id)  # shares_entity, linked_by, ...

aws_people = [n for n in graph.nodes if "AWS" in n.content_preview]

# Shortest path between two memories
path = client.memory_path(sarah["id"], deal["id"])
print(path.hops, path.path)

# Graph narrows the scope; recall ranks the supporting memories for the question
context = client.recall(agent_id=AGENT, query="who at Acme Corp knows about AWS", top_k=5)
import { DakeraClient } from '@dakera-ai/dakera';

const client = new DakeraClient({ baseUrl: 'http://localhost:3000', apiKey: 'dk-...' });
const AGENT = 'crm-agent';

// Turn on entity extraction for the agent's namespace (once)
await client.createAgent(AGENT); // v0.12.2; otherwise the first store creates it
await client.configureNamespaceNer(`_dakera_agent_${AGENT}`, {
  extract_entities: true,
  entity_types: ['person', 'organization', 'technology', 'deal'],
});

// Store memories: each is tagged entity:<type>:<value> and linked into the graph
const { memory: sarah } = await client.storeMemory(AGENT, {
  content: 'Sarah Kim is VP Sales at Acme Corp',
  importance: 0.9,
  memory_type: 'semantic',
  tags: ['crm', 'contact'],
});
const { memory: marcus } = await client.storeMemory(AGENT, {
  content: 'Marcus Lee evaluates AWS for Acme Corp',
  importance: 0.85,
  memory_type: 'semantic',
  tags: ['crm', 'contact'],
});
const { memory: deal } = await client.storeMemory(AGENT, {
  content: 'CloudMigrate Q2 deal is $240k',
  importance: 0.8,
  memory_type: 'semantic',
  tags: ['crm', 'deal'],
});

// Entities extracted from a memory
const { entities } = await client.memoryEntities(sarah.id);

// An application-level relation as an explicit link (edge type linked_by)
await client.memoryLink(deal.id, marcus.id, { agentId: AGENT, label: 'uses_vendor' });

// BFS from the Sarah memory, two hops
const graph = await client.memoryGraph(sarah.id, { depth: 2 });
graph.edges.forEach(e => console.log(e.source_id, e.edge_type, e.target_id));
const awsPeople = graph.nodes.filter(n => n.content_preview?.includes('AWS'));

// Shortest path between two memories
const path = await client.memoryPath(sarah.id, deal.id);

// Graph narrows the scope; recall ranks the supporting memories
const { memories } = await client.recall(AGENT, 'who at Acme Corp knows about AWS', { top_k: 5 });
use dakera_client::{DakeraClient, GraphOptions, MemoryType, NamespaceNerConfig, StoreMemoryRequest};

let client = DakeraClient::builder("http://localhost:3000")
    .api_key("dk-...")
    .build()?;
let agent = "crm-agent";

// Turn on entity extraction for the agent's namespace (once)
client.create_agent(agent).await?;
client.configure_namespace_ner("_dakera_agent_crm-agent", NamespaceNerConfig {
    extract_entities: true,
    entity_types: Some(vec!["person".into(), "organization".into(), "technology".into(), "deal".into()]),
}).await?;

// Store memories: each is tagged entity:<type>:<value> and linked into the graph
let sarah = client.store_memory(
    StoreMemoryRequest::new(agent, "Sarah Kim is VP Sales at Acme Corp")
        .with_type(MemoryType::Semantic)
        .with_importance(0.9),
).await?;
let marcus = client.store_memory(
    StoreMemoryRequest::new(agent, "Marcus Lee evaluates AWS for Acme Corp")
        .with_type(MemoryType::Semantic)
        .with_importance(0.85),
).await?;

// Entities extracted from a memory
let entities = client.memory_entities(&sarah.memory_id).await?;

// BFS from the Sarah memory, two hops
let graph = client.memory_graph(&sarah.memory_id, GraphOptions { depth: Some(2), ..Default::default() }).await?;
for edge in &graph.edges {
    println!("{} -{:?}-> {}", edge.source_id, edge.edge_type, edge.target_id);
}

// Shortest path between two memories
let path = client.memory_path(&sarah.memory_id, &marcus.memory_id).await?;
println!("{} hops", path.hops);
client := dakera.NewClientWithOptions(dakera.ClientOptions{
    BaseURL: "http://localhost:3000",
    APIKey:  "dk-...",
})
ctx := context.Background()
agent := "crm-agent"
f32 := func(v float32) *float32 { return &v }

// Turn on entity extraction for the agent's namespace (once)
client.CreateAgent(ctx, agent)
client.ConfigureNamespaceNer(ctx, "_dakera_agent_crm-agent", dakera.NamespaceNerConfig{
    ExtractEntities: true,
    EntityTypes:     []string{"person", "organization", "technology", "deal"},
})

// Store memories: each is tagged entity:<type>:<value> and linked into the graph
sarah, _ := client.StoreMemory(ctx, agent, dakera.StoreMemoryRequest{
    Content:    "Sarah Kim is VP Sales at Acme Corp",
    MemoryType: "semantic",
    Importance: f32(0.9),
})
marcus, _ := client.StoreMemory(ctx, agent, dakera.StoreMemoryRequest{
    Content:    "Marcus Lee evaluates AWS for Acme Corp",
    MemoryType: "semantic",
    Importance: f32(0.85),
})

// Entities extracted from a memory
entities, _ := client.MemoryEntities(ctx, sarah.Memory.ID)

// BFS from the Sarah memory, two hops
graph, _ := client.MemoryGraph(ctx, sarah.Memory.ID, &dakera.GraphOptions{Depth: 2})
for _, e := range graph.Edges {
    fmt.Println(e.SourceID, e.EdgeType, e.TargetID)
}

// Shortest path between two memories
path, _ := client.MemoryPath(ctx, sarah.Memory.ID, marcus.Memory.ID)
fmt.Println(entities.Count, path.Hops)

Build your first memory graph

Dakera's one-line Docker install has you storing memories and querying graphs immediately.

Start Free →

Before / After: Flat Memory vs. Graph-Linked Memory

Before: Flat memory store
# Three disconnected memory chunks
# Vector search can find each individually
# but cannot answer relationship questions

Memory 1:
"Sarah Kim is VP Sales at Acme Corp"

Memory 2:
"Marcus Lee evaluates AWS for Acme Corp"

Memory 3:
"CloudMigrate Q2 deal is $240k"

# Query: "Who at Acme knows about AWS?"
# Result: memory 2 returned by similarity
# But: no link to Sarah Kim, no deal context
After: Graph-linked memory
# Same memories, extraction on: entity tags
Memory 1: person:Sarah Kim, organization:Acme Corp
Memory 2: person:Marcus Lee, technology:AWS,
          organization:Acme Corp
Memory 3: deal:CloudMigrate Q2
Memory 4: "Sarah Kim is leading the CloudMigrate
          Q2 deal" (person:Sarah Kim, deal:...)

Edges:
Memory 1 -shares_entity (Acme Corp)-> Memory 2
Memory 1 -shares_entity (Sarah Kim)-> Memory 4
Memory 4 -shares_entity (CloudMigrate Q2)-> Memory 3
Memory 3 -linked_by "uses_vendor"-> Memory 2

# Query: "Who at Acme knows about AWS?"
# Traverse from Memory 1 (depth 2)
# -> Memory 2: Marcus Lee evaluates AWS
# -> Memory 4 and 3: Sarah's deal context

Performance Considerations

Entity extraction runs on the store path, inside the Dakera process, with no external calls when GLiNER is the provider. The graph is durable by default and lives under the data root next to the memories (DAKERA_GRAPH_PATH sets another location), and its edges are scoped by namespace, so one agent's links are never read or deleted by another.

5
Edge types: related_to, shares_entity, precedes, linked_by, supersedes
5
Maximum depth of a graph traversal (the server caps it)
~782 MB
GLiNER model, downloaded on first use
Watch: traversal depth on dense graphs

A memory that mentions a common entity links to every other memory with that entity, so each extra hop can multiply the nodes a traversal returns. Keep depth at 2 for most queries, and filter the returned edges by type in your code (the Python, TypeScript, Go and Rust clients do this for you with their edge-type option) when you only need, say, shares_entity or linked_by.

Edge Cases

1. Entity Disambiguation

Two different people named "Alex Chen" produce the same entity tag if their memories only give the name, and shares_entity then links memories about both. Solution: always include organizational context in memories containing person names, so recall and your application can tell them apart, and add explicit links where you know the relation.

# Ambiguous: only the name connects these memories
client.store_memory(agent_id="crm-agent", content="Alex Chen called today", importance=0.5)

# Unambiguous: employer and role are in the memory itself
client.store_memory(agent_id="crm-agent",
    content="Alex Chen (Acme Corp, VP Eng) reviewed the proposal",
    importance=0.8, tags=["contact", "acme"]
)
client.store_memory(agent_id="crm-agent",
    content="Alex Chen (BetaCo, Director of Finance) declined the meeting",
    importance=0.8, tags=["contact", "betaco"]
)

2. Aliases

Aliases like "AWS", "Amazon Web Services", and "Amazon AWS" can produce different entity tags, and memories that use different aliases are then not linked by shares_entity. Normalize names in your own text before storing (for example, write "AWS (Amazon Web Services)"), or link the memories explicitly. Similar memories are still connected by related_to when their cosine similarity is at least 0.85.

3. Stale Relationship Cleanup

When a contact changes companies, the old memory still says they work at the old one. Store the new fact: if it is very similar to the old memory and shares an entity, Dakera adds a supersedes edge and recall demotes the outdated fact. Use forget() to remove a memory entirely, or update_memory() to rewrite its content.

# Store the newer fact; recall demotes the one it supersedes
client.store_memory(
    agent_id="crm-agent",
    content="Sarah Kim is VP Sales at NewCo (formerly Acme Corp)",
    importance=0.9
)

# Or rewrite the old memory in place
client.update_memory(
    agent_id="crm-agent",
    memory_id="mem_sarah_employer",
    content="Sarah Kim is VP Sales at NewCo (formerly Acme Corp)"
)

4. Cross-Agent Entity Sharing

Each agent's memories, entity tags and edges live in its own namespace. If two agents (e.g., a research agent and a CRM agent) both know about "Acme Corp", their graphs stay separate. To see what several agents have in common, map their shared entities and related memories with POST /v1/knowledge/network/cross-agent (an admin key with no namespace restriction), or store canonical knowledge in a shared agent that several agents recall from.

5. High-Cardinality Entity Types

Extracting identifiers from many memories (transaction IDs, ticket numbers, timestamps) creates many low-value tags and links. Leave such types out of entity_types, and keep transactional data in ephemeral memories with ttl_seconds so it is deleted on schedule.

SDK Reference

MethodSDKPurpose
configure_namespace_ner(namespace, extract_entities, entity_types)PythonTurn on entity extraction for an agent's namespace
store_memory(agent_id, content, importance, memory_type, tags)PythonStore memory; tags entities and links it into the graph
memory_entities(memory_id)PythonEntities extracted from a stored memory
memory_graph(memory_id, depth)PythonBFS traversal from a memory (GET /v1/memories/{id}/graph)
memory_path(source_id, target_id)PythonShortest path between two memories
memory_link(source_id, target_id, agent_id=, label=)PythonExplicit linked_by edge with an optional label
knowledge_graph(agent_id, memory_id, depth)PythonGraph around a seed memory (POST /v1/knowledge/graph)
agent_graph_export(agent_id)PythonExport an agent's whole graph
configureNamespaceNer(ns, {extract_entities, entity_types})TypeScriptTurn on entity extraction
memoryGraph(memoryId, {depth})TypeScriptBFS traversal from a memory
memoryLink(sourceId, targetId, {agentId, label})TypeScriptExplicit link between memories
client.memory_graph(&id, GraphOptions{...}).await?RustBFS traversal from a memory
client.MemoryGraph(ctx, id, &dakera.GraphOptions{Depth: 2})GoBFS traversal from a memory
recall(agent_id, query, top_k)PythonSemantic recall: use alongside graph traversal
forget(agent_id, memory_id)PythonRemove a memory
Advanced Configuration: Tuning Entity Extraction

Choosing entity types

GLiNER is zero-shot: the entity_types you set on the namespace are the labels it looks for, including domain-specific ones such as deal, contract or feature. PUT /v1/namespaces/{ns}/config replaces the whole configuration (an omitted entity_types clears the list); PATCH changes only the fields you send.

curl -X PATCH http://localhost:3000/v1/namespaces/_dakera_agent_crm-agent/config \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{"extract_entities": true, "entity_types": ["person", "organization", "technology", "deal", "contract"]}'

Testing extraction without storing

Send text to POST /v1/memories/extract to see what would be tagged; nothing is stored.

curl -X POST http://localhost:3000/v1/memories/extract \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{"content": "Marcus Lee evaluates AWS for Acme Corp", "entity_types": ["person", "organization", "technology"]}'

Another extraction provider

To extract with an LLM (OpenAI, OpenRouter, Anthropic or Ollama) instead of GLiNER, set the namespace's provider with PATCH /v1/namespaces/{ns}/extractor, or server-wide with DAKERA_EXTRACTOR_PROVIDER. Pre-fetch the GLiNER model with dakera models pull gliner to avoid the first-store wait.

When to Use This Pattern

Graph + recall = best of both worlds

Graph traversal narrows scope; semantic recall provides context. The recommended pattern: traverse from a memory to collect the memories around the right entities, then call recall() with the question to rank the supporting memories. You get structured relationship reasoning plus natural language context in one pipeline.

Try it live

Run this pattern against a real Dakera.

The Playground executes live API calls in your browser. No account, no install. Then run it on your own server in five minutes.