Skip to Content
TaresGuidesThe HTTP API in five minutes

The HTTP API in five minutes

Everything the console and the MCP tools do goes through the daemon’s HTTP API. This guide drives the whole loop with curl: create a source, feed it, read a correlated timeline, define a trigger, watch it fire, and write an observation back. No upstream systems required.

You need a running daemon (Quickstart): tares up, API at http://127.0.0.1:8787.

Ingest: create a source and feed it

Create a push (webhook) source. The config maps payload fields into the envelope; the label marked primary is the entity key:

curl -s -XPOST localhost:8787/api/sources -H 'content-type: application/json' -d '{ "name": "checkout_probe", "connector": "webhook", "config": { "event_type": "probe", "text_template": "latency {latency_ms}ms on {endpoint}", "labels": [{ "name": "service", "field": "service", "primary": true }] } }' # {"ok":true,"name":"checkout_probe","ingest_key":"webhook-…"}

Feed it:

curl -s -XPOST localhost:8787/ingest/checkout_probe -H 'content-type: application/json' \ -d '{"service": "checkout", "endpoint": "/pay", "latency_ms": 120}' curl -s -XPOST localhost:8787/ingest/checkout_probe -H 'content-type: application/json' \ -d '{"service": "checkout", "endpoint": "/pay", "latency_ms": 1450}' curl -s -XPOST localhost:8787/ingest/checkout_probe -H 'content-type: application/json' \ -d '{"service": "search", "endpoint": "/q", "latency_ms": 45}'

Numeric payload fields (latency_ms) become typed fields triggers can aggregate over; the full payload is kept lossless. This is the generic inbound path for anything that can send JSON.

Locally you can post to the source by name. The response’s ingest_key is the stable, unguessable path (/ingest/<ingest_key>). Use that when producers deliver over the network. On a secured instance, producers also send an ingest-scoped API key as Authorization: Bearer <key>.

Read: one correlated timeline

The primary read needs no setup at all: a {label: value} selector across all sources:

curl -s -XPOST localhost:8787/read -H 'content-type: application/json' \ -d '{"selector": {"service": "checkout"}, "window": "15m"}'

You get checkout’s events, time-ordered, from every source that carries the label, with one source it’s modest; the payoff is when logs, metrics, and commits arrive interleaved on one clock.

To fix the source set and reuse it (and to attach triggers), save a view and query through it:

curl -s -XPOST localhost:8787/api/views -H 'content-type: application/json' -d '{ "name": "service_health", "key_field": "service", "sources": ["checkout_probe"] }' curl -s -XPOST localhost:8787/query -H 'content-type: application/json' \ -d '{"view": "service_health", "key": "checkout", "window": "15m"}'

Watch: a trigger that wakes someone

Start a subscriber to be woken (stands in for your agent’s webhook) in a second terminal: examples/woke_receiver.py in the repo listens on http://127.0.0.1:9999/woke. Then define the condition and subscribe it:

curl -s -XPOST localhost:8787/api/triggers -H 'content-type: application/json' -d '{ "name": "slow_checkout", "view": "service_health", "condition": {"aggregate": "max", "field": "latency_ms", "predicate": "> 1000", "window": "5m"}, "emit": {"kind": "slow_checkout", "context_window": "15m"}, "cooldown": "1m" }' curl -s -XPOST localhost:8787/subscribe -H 'content-type: application/json' \ -d '{"trigger": "slow_checkout", "url": "http://127.0.0.1:9999/woke"}'

Cause the condition:

curl -s -XPOST localhost:8787/ingest/checkout_probe -H 'content-type: application/json' \ -d '{"service": "checkout", "endpoint": "/pay", "latency_ms": 2100}'

Within a few seconds the receiver prints the dispatch, with the 15-minute correlated timeline attached. That’s the core move: the store wakes the agent, and the agent starts with context instead of fetching it. Every firing (even with zero subscribers) is logged:

curl -s localhost:8787/api/activity/dispatches

(console: Agents → Trigger dispatches.)

Write back: the agent surface over HTTP

The MCP tools map onto the same endpoints, so you can drive the agent loop by hand. Describe an object: inferred schema, entities, freshness, sample events:

curl -s localhost:8787/catalog/source:checkout_probe

Derive a view the way an agent would (it lands in the catalog tagged with its creator):

curl -s -XPOST localhost:8787/derive -H 'content-type: application/json' -d '{ "sources": ["checkout_probe"], "key_field": "service", "name": "slow_only", "filters": [{"field": "latency_ms", "op": "gt", "value": 1000}]}'

Write an observation back. The first call auto-provisions the agent_memory source, and the memory shows up inside the entity’s timeline on the next read:

curl -s -XPOST localhost:8787/remember -H 'content-type: application/json' \ -d '{"key": "checkout", "content": "latency spikes on /pay correlate with payments deploys"}'

To do all of this from a real agent instead, connect one over MCP: the tool set (read, query, catalog_list / catalog_describe, derive, remember, subscribe, plus the source-setup tools) is this API with discovery built in.

Keep it: the catalog as YAML

Everything you just built is catalog state; YAML is its portable form:

curl -s localhost:8787/api/catalog/export > catalog.yaml # git it, share it

Importing (console → Catalog, or POST /api/catalog/import) supports merge or replace, validated as a whole before anything is written. A fresh daemon pointed at that YAML (TARES_CATALOG=catalog.yaml tares up) reproduces the whole setup on first boot.

Last updated on