Skip to main content
method
POST
/signals
Authentication: Required (if enabled) Ingests an ordered sequence of entity–attribute–value triples. Unlike POST /signal, this endpoint calls ingest_sequence() internally, which analyses co-occurrence across adjacent signals: two entities that share the same attribute value in consecutive signals get an edge created (or incremented) between them.
Use this endpoint when you need a connected graph via HTTP. POST /signal inserts isolated nodes — it never creates edges.

Why this endpoint exists

POST /signal calls ingest() — a single-signal path that stores nodes but never creates edges. Edges are the backbone of queries like strongest_path, intersect, and retract. If you ingest signals one-by-one via HTTP, these queries always return found: false. POST /signals fixes this by accepting a batch and delegating to ingest_sequence(), the same function used by the CLI kremis ingest command.

Request Body

{
  "signals": [
    { "entity_id": 1, "attribute": "name", "value": "Alice" },
    { "entity_id": 2, "attribute": "name", "value": "Bob" }
  ]
}
FieldTypeRequiredConstraintsDescription
signalsarrayYesMax 10,000 itemsOrdered list of signals.
signals[].entity_idinteger (u64)YesEntity identifier.
signals[].attributestringYesMax 256 bytes, non-emptyAttribute name.
signals[].valuestringYesMax 64 KB, non-emptyAttribute value.
An empty array {"signals": []} is a valid no-op.

Response

{
  "success": true,
  "ingested": 2,
  "node_ids": [9876543210, 1234567890],
  "error": null
}
FieldTypeDescription
successbooleanWhether all signals were ingested.
ingestedintegerNumber of signals processed.
node_idsarray of integerNode IDs assigned to each entity, in order.
errorstring or nullError message (if failed).
If any signal in the batch is invalid (empty attribute, oversized value), the entire request is rejected with 400. No signals are ingested.

Example

curl -X POST http://localhost:8080/signals \
     -H "Authorization: Bearer your-api-key" \
     -H "Content-Type: application/json" \
     -d '{
       "signals": [
         {"entity_id": 1, "attribute": "name", "value": "Alice"},
         {"entity_id": 2, "attribute": "name", "value": "Bob"}
       ]
     }'
Expected response:
{
  "success": true,
  "ingested": 2,
  "node_ids": [0, 1],
  "error": null
}
After this call, GET /status shows edge_count >= 1, and POST /query with strongest_path from Alice’s node to Bob’s node returns found: true.

Limits

ConstraintValue
Max signals per request10,000 (MAX_SEQUENCE_LENGTH)
Max request body2 MB
Max attribute length256 bytes
Max value length64 KB (65,536 bytes)
Last modified on March 9, 2026