Getting started
Every snippet on this page was executed against a broker built from this repository before being committed.
Install
Docker (multi-arch, amd64 + arm64):
docker run --rm -p 9090:9090 ghcr.io/joinedcontext/antares-broker:latest
From source (Rust toolchain per rust-toolchain.toml):
cargo run -p antares-broker # serves http://0.0.0.0:9090
Release binary: attached to GitHub releases (from v0.1.1 on).
The default configuration needs zero infrastructure: in-memory store, in-process bus, all roles in one process. Check it is up:
curl -s localhost:9090/q/health # {"status":"UP","store":"memory",...}
First entity
curl -i -X POST localhost:9090/ngsi-ld/v1/entities \
-H 'Content-Type: application/ld+json' \
-d '{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"temperature": {"type": "Property", "value": 21.5, "unitCode": "CEL"},
"@context": "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"
}'
# HTTP/1.1 201 Created
# Location: /ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001
curl -s 'localhost:9090/ngsi-ld/v1/entities?type=TemperatureSensor'
First subscription
Start something that shows incoming HTTP requests — nc -l 9491 is enough —
then subscribe:
curl -i -X POST localhost:9090/ngsi-ld/v1/subscriptions \
-H 'Content-Type: application/ld+json' \
-d '{
"id": "urn:ngsi-ld:Subscription:demo",
"type": "Subscription",
"entities": [{"type": "TemperatureSensor"}],
"watchedAttributes": ["temperature"],
"notification": {"endpoint": {"uri": "http://127.0.0.1:9491/notify"}},
"@context": "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"
}'
# HTTP/1.1 201 Created
Change the watched attribute — the fragment is application/ld+json (with
Content-Type: application/json the @context would have to travel in the
Link header instead; mixing both is rejected per CIM 009 clause 6.3.5):
curl -i -X PATCH \
localhost:9090/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001/attrs/temperature \
-H 'Content-Type: application/ld+json' \
-d '{"type": "Property", "value": 42.0,
"@context": "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"}'
# HTTP/1.1 204 No Content
The listener receives:
{"id": "urn:ngsi-ld:Notification:ca63483a-bc7e-4731-a36f-1168f455eb97", "type": "Notification",
"subscriptionId": "urn:ngsi-ld:Subscription:demo", "notifiedAt": "2026-08-26T16:16:00.851Z",
"data": [{"id": "urn:ngsi-ld:TemperatureSensor:001", "type": "TemperatureSensor",
"temperature": {"type": "Property", "unitCode": "CEL", "value": 42.0}}]}
MQTT delivery works the same way with an mqtt[s]:// endpoint URI.
First federation pair
Two brokers, one Context Source Registration. Local processes talk over
loopback, which the egress policy allows by default; on an
internet-facing deployment set ANTARES_EGRESS_ALLOW_PRIVATE=false
(see Configuration):
ANTARES_HTTP_PORT=9391 antares & # broker A
ANTARES_HTTP_PORT=9392 antares & # broker B
Create an entity only broker B knows:
curl -s -X POST localhost:9392/ngsi-ld/v1/entities \
-H 'Content-Type: application/ld+json' \
-d '{"id": "urn:ngsi-ld:ParkingSpot:B:042", "type": "ParkingSpot",
"status": {"type": "Property", "value": "free"},
"@context": "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"}'
Tell broker A that broker B serves ParkingSpot entities:
curl -i -X POST localhost:9391/ngsi-ld/v1/csourceRegistrations \
-H 'Content-Type: application/ld+json' \
-d '{
"id": "urn:ngsi-ld:ContextSourceRegistration:brokerB",
"type": "ContextSourceRegistration",
"information": [{"entities": [{"type": "ParkingSpot"}]}],
"endpoint": "http://127.0.0.1:9392",
"@context": "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"
}'
# HTTP/1.1 201 Created
Query broker A — the result comes from broker B through the registration:
curl -s 'localhost:9391/ngsi-ld/v1/entities?type=ParkingSpot'
# [{"id":"urn:ngsi-ld:ParkingSpot:B:042","type":"ParkingSpot",
# "status":{"type":"Property","value":"free"}}]
That is the whole federation model: registrations route queries (and writes, subscriptions, temporal queries) to the sources that declared the matching types and id patterns.
Next
- Subscriptions and notifications: formats,
showChanges, periodic delivery, throttling, MQTT, retries. - Temporal API: how history is recorded and queried.
- Federation: registration modes, loop protection, partial failures, context source subscriptions.
- Deployment and Operations when it leaves the laptop.