HTTP API Reference

pg_ripple_http is a standalone Rust binary that exposes the full pg_ripple feature set over HTTP. It supports the W3C SPARQL 1.1 Protocol, Server-Sent Events streaming, Datalog REST operations, PageRank, probabilistic reasoning, Arrow Flight bulk export, and administrative endpoints.

Start the service:

PG_RIPPLE_HTTP_PG_URL=postgresql://localhost/mydb \
PG_RIPPLE_HTTP_PORT=7878 \
PG_RIPPLE_HTTP_AUTH_TOKEN=mysecret \
pg_ripple_http

Authentication

All endpoints that mutate state require a Bearer token when PG_RIPPLE_HTTP_AUTH_TOKEN is set.

Authorization: Bearer <token>

Read-only endpoints (GET /health, GET /metrics, GET /openapi.yaml) do not require authentication.


Configuration

Environment VariableDefaultDescription
PG_RIPPLE_HTTP_PG_URLpostgresql://localhost/postgresPostgreSQL connection URL
PG_RIPPLE_HTTP_PORT7878TCP listening port
PG_RIPPLE_HTTP_POOL_SIZE16PostgreSQL connection pool size
PG_RIPPLE_HTTP_AUTH_TOKEN(none)Bearer token; set to enable auth
PG_RIPPLE_HTTP_DATALOG_WRITE_TOKEN(falls back to auth token)Optional separate token for mutating Datalog/rule endpoints
PG_RIPPLE_HTTP_RATE_LIMIT100Per-IP rate limit (req/s; 0 = unlimited)
PG_RIPPLE_HTTP_CORS_ORIGINS''Comma-separated allowed CORS origins; * enables permissive CORS
PG_RIPPLE_HTTP_MAX_BODY_BYTES10485760Max request body size (10 MiB)
PG_RIPPLE_HTTP_SKIP_COMPAT_CHECK(unset)Set to 1 to skip extension version check
PG_RIPPLE_HTTP_STRICT_COMPAT(unset)Set to 1 to fail startup on incompatible extension versions
PG_RIPPLE_HTTP_METRICS_TOKEN(none)Optional bearer token for /metrics
PG_RIPPLE_HTTP_AUTH_REALMpg_rippleWWW-Authenticate realm for 401 responses
PG_RIPPLE_HTTP_REPLICA_DSN(none)Optional read-replica PostgreSQL DSN
PG_RIPPLE_HTTP_TRUST_PROXY(none)Trusted upstream proxy IP/CIDR list for forwarded headers
PG_RIPPLE_HTTP_CA_BUNDLE(system roots)Extra CA bundle for outbound HTTPS clients
PG_RIPPLE_HTTP_PIN_FINGERPRINTS(none)Optional pinned TLS certificate fingerprints
PG_RIPPLE_HTTP_SHUTDOWN_TIMEOUT_SECS30Graceful shutdown timeout
ARROW_FLIGHT_SECRET(none)HMAC secret for Arrow Flight tickets
ARROW_UNSIGNED_TICKETS_ALLOWEDfalseAllow unsigned Arrow tickets for local development
ARROW_NONCE_CACHE_MAX10000Replay-protection nonce cache size

Complete Endpoint Reference

Read and Write mean the endpoint calls the HTTP companion's read or write authentication check when PG_RIPPLE_HTTP_AUTH_TOKEN is configured. None means the endpoint is intentionally unauthenticated.

MethodPathAuthDescription
GET/sparqlReadSPARQL 1.1 query via URL parameters
POST/sparqlQuery-dependentSPARQL 1.1 query/update via request body; updates require write auth
POST/sparql/streamReadStreaming SPARQL SELECT (SSE)
POST/ragReadRAG retrieval / NL-to-SPARQL
GET/healthNoneLiveness probe
GET/readyNoneKubernetes readiness probe
GET/health/readyNoneDeep extension readiness probe
GET/metricsNone or metrics tokenPrometheus metrics
GET/metrics/extensionNoneExtension-internal Prometheus metrics
GET/voidNoneVoID dataset description
GET/serviceNoneSPARQL service description
GET/openapi.yamlNoneOpenAPI 3.1 specification
GET/explorerReadWeb-based SPARQL explorer UI
GET/admin/bench-historyWriteRecent benchmark history from _pg_ripple.bench_history
GET/admin/diagnostic-snapshotWriteDiagnostic bundle with schema, GUC, version, and metrics data
POST/flight/do_getWriteArrow Flight bulk export
GET/subscribe/{subscription_id}ReadLive SPARQL subscription SSE stream
GET/datalog/rulesReadList Datalog rule sets
POST/DELETE/datalog/rules/{rule_set}WriteLoad or drop a rule set
POST/datalog/rules/{rule_set}/builtinWriteLoad built-in rules for a rule set
POST/datalog/rules/{rule_set}/addWriteAdd a rule to a rule set
PUT/datalog/rules/{rule_set}/enableWriteEnable a rule set
PUT/datalog/rules/{rule_set}/disableWriteDisable a rule set
DELETE/datalog/rules/{rule_set}/{rule_id}WriteDelete a specific rule
POST/datalog/infer/{rule_set}WriteRun forward-chaining inference
POST/datalog/infer/{rule_set}/statsWriteRun inference and return stats
POST/datalog/infer/{rule_set}/aggWriteRun inference with aggregation
POST/datalog/infer/{rule_set}/wfsWriteRun well-founded semantics inference
POST/datalog/infer/{rule_set}/demandWriteGoal-directed demand inference
POST/datalog/infer/{rule_set}/latticeWriteLattice-based inference
POST/datalog/query/{rule_set}ReadGoal-directed Datalog query
GET/datalog/constraintsReadCheck all constraint rules
GET/datalog/constraints/{rule_set}ReadCheck constraints for one rule set
GET/datalog/stats/cacheReadRule plan cache statistics
GET/datalog/stats/tablingReadTabling cache statistics
GET/POST/datalog/latticesRead/WriteList or create lattice structures
GET/POST/datalog/viewsRead/WriteList or create Datalog-backed views
DELETE/datalog/views/{name}WriteDrop a Datalog-backed view
POST/pagerank/runWriteStart PageRank computation
GET/pagerank/statusReadPageRank computation status
GET/pagerank/resultsReadRetrieve PageRank scores
GET/pagerank/exportReadExport PageRank scores
GET/pagerank/explain/{node_iri}ReadExplain PageRank score for a node
GET/pagerank/queue-statsReadPageRank queue statistics
POST/pagerank/vacuum-dirtyWriteVacuum stale PageRank rows
POST/centrality/runWriteCompute centrality metrics
GET/centrality/resultsReadRetrieve centrality results
POST/pagerank/find-duplicatesReadFind near-duplicate nodes
POST/confidence/loadWriteLoad triples with confidence scores
GET/confidence/shacl-scoreReadGet SHACL soft-validation scores
GET/confidence/shacl-reportReadGet scored SHACL validation report
POST/confidence/vacuumWriteVacuum stale confidence rows
POST/confidence/updateWriteRun Bayesian confidence update
POST/confidence/bulk-updateWriteBulk confidence update
POST/explainReadNatural-language explanation of a query or result
GET/explainReadExplanation endpoint metadata/query form
POST/hypotheticalWriteWhat-if reasoning against hypothetical facts
GET/rule-conflicts/{ruleset}ReadDetect rule conflicts in a rule set
GET/rule-librariesReadList rule libraries
GET/rule-libraries/{name}/streamReadStream a published rule library
POST/rule-libraries/{name}/subscribeWriteSubscribe to a remote rule library stream
POST/rules/draftWriteDraft rules from natural-language guidance
POST/rules/validateWriteValidate a drafted rule
GET/rules/{id}/explainReadExplain a rule by ID
GET/POST/temporal/markRead/WriteList or mark temporal predicates
POST/temporal/point_in_timeWriteSet point-in-time temporal context
GET/temporal/factsReadList temporal facts
GET/temporal/graphs/{iri}/snapshotReadMaterialize a point-in-time graph snapshot
GET/temporal/graphs/{iri}/diffReadDiff a named graph between two timestamps
POST/pprl/bloom_encodeWritePrivacy-preserving Bloom encoding
POST/pprl/dice_similarityReadDice similarity over encoded values
POST/dp/noisy_countReadDifferential privacy noisy count
POST/dp/noisy_histogramReadDifferential privacy noisy histogram
GET/dp/budget/{dataset}/{principal}ReadPrivacy budget status
POST/entity-resolution/resolveWriteRun entity resolution
POST/entity-resolution/evaluateReadEvaluate entity-resolution output
POST/entity-resolution/monitoring/enableWriteEnable entity-resolution monitoring
POST/entity-resolution/monitoring/disableWriteDisable entity-resolution monitoring
GET/proof-tree/{subject}/{predicate}/{object}ReadExplain derivation/proof tree for a triple
GET/POST/tenantsRead/WriteList or create tenants
GET/DELETE/tenants/{name}Read/WriteGet or delete a tenant
GET/POST/tenants/{name}/quotaRead/WriteGet or update tenant quota
GET/federation/{endpoint}/auth-statusWritePer-endpoint federation credential status
POST/json-mapping/{name}/writebackWriteSynchronous JSON mapping relational writeback
GET/json-mapping/{name}/writeback/statusReadJSON mapping writeback queue status

SPARQL Endpoints

GET /sparql

W3C SPARQL 1.1 Protocol query endpoint.

Query Parameters:

ParameterRequiredDescription
queryYes (query)URL-encoded SPARQL SELECT/CONSTRUCT/ASK/DESCRIBE query
updateYes (update)URL-encoded SPARQL UPDATE
default-graph-uriNoDefault graph URI
named-graph-uriNoNamed graph URI (repeatable)

Accept header controls the result format:

AcceptFormat
application/sparql-results+jsonSPARQL JSON (default)
application/sparql-results+xmlSPARQL XML
text/turtleTurtle (for CONSTRUCT/DESCRIBE)
application/n-triplesN-Triples (for CONSTRUCT/DESCRIBE)
application/ld+jsonJSON-LD (for CONSTRUCT/DESCRIBE)

Example:

curl -G "http://localhost:7878/sparql" \
  --data-urlencode 'query=SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10' \
  -H "Accept: application/sparql-results+json"

POST /sparql

Accepts the query either as an application/x-www-form-urlencoded body (form post) or as a raw application/sparql-query / application/sparql-update body.

Form body parameters: same as GET /sparql query parameters.

Example (SELECT):

curl -X POST http://localhost:7878/sparql \
  -H "Content-Type: application/sparql-query" \
  -d 'SELECT ?label WHERE { <https://example.org/Alice> rdfs:label ?label }'

Example (UPDATE, requires auth):

curl -X POST http://localhost:7878/sparql \
  -H "Content-Type: application/sparql-update" \
  -H "Authorization: Bearer $TOKEN" \
  -d 'INSERT DATA { <:Alice> rdfs:label "Alice" }'

POST /sparql/stream

Streaming SPARQL SELECT using Server-Sent Events. Results are delivered as SSE data: events, one result row per event, as the query executes.

Request: Same as POST /sparql.

Response Content-Type: text/event-stream

Event format:

event: row
data: {"?name": "\"Alice\"^^xsd:string", "?age": "\"30\"^^xsd:integer"}

event: done
data: {"total_rows": 42}

Example:

curl -X POST http://localhost:7878/sparql/stream \
  -H "Content-Type: application/sparql-query" \
  -H "Accept: text/event-stream" \
  -d 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }' \
  --no-buffer

RAG Endpoint

POST /rag

Execute a hybrid SPARQL + vector-similarity RAG retrieval query. The endpoint embeds the question, finds the nearest RDF entities by cosine similarity, and returns structured results with a plain-text context string suitable for use as an LLM prompt.

Content-Type: application/json

Request body:

{
  "question": "what treats headaches?",
  "sparql_filter": "?entity a <https://pharma.example/Drug>",
  "k": 5,
  "model": "text-embedding-3-small",
  "output_format": "jsonb"
}
FieldTypeRequiredDefaultDescription
questionstringyesNatural-language question
sparql_filterstringnonullSPARQL WHERE fragment to filter candidates
kintegerno5Number of nearest neighbors
modelstringno(GUC)Override pg_ripple.embedding_model
output_formatstringno"jsonb""jsonb" or "jsonld"

Response (200 OK):

{
  "results": [
    {
      "entity_iri": "https://pharma.example/aspirin",
      "label": "aspirin",
      "context_json": {
        "label": "aspirin",
        "types": ["Drug", "NSAID"],
        "properties": [{"predicate": "treats", "object": "headache"}],
        "contextText": "aspirin. Type: NSAID, Drug."
      },
      "distance": 0.12
    }
  ],
  "context": "aspirin. Type: NSAID, Drug.\n\nibuprofen. Type: Drug."
}

The context field is a concatenated plain-text summary ready for use as an LLM system prompt.


JSON Mapping Writeback

POST /json-mapping/{name}/writeback

Synchronously write one RDF subject back to the relational table configured for the named JSON mapping. This calls pg_ripple.writeback_json_row(name, subject_iri) and requires write auth when authentication is enabled.

Content-Type: application/json

{
  "subject_iri": "https://example.com/contacts/c001"
}

Response (200 OK):

{
  "rows_affected": 1
}

Error mapping:

StatusErrorCause
422writeback_target_not_configuredThe mapping has no writeback table or key columns (PT0550)
409writeback_conflictConflict policy is error and a conflicting row exists (PT0551)

GET /json-mapping/{name}/writeback/status

Return queue depth, error count, and last processed timestamp for one mapping. This is a filtered HTTP view over pg_ripple.json_writeback_status() and requires read auth when authentication is enabled.

Response (200 OK):

{
  "mapping_name": "contacts",
  "pending": 0,
  "errors": 0,
  "last_error": null,
  "last_processed_at": null
}

Arrow Flight Bulk Export

POST /flight/do_get

Bulk-export SPARQL query results as an Apache Arrow IPC record stream. Suitable for high-throughput extract pipelines (DuckDB, pandas, Spark).

Content-Type: application/json

Request body:

{
  "ticket": "eyJhbGciOiJIUzI1NiJ9...",
  "query": "SELECT ?s ?p ?o WHERE { ?s ?p ?o }"
}
FieldTypeRequiredDescription
ticketstringyesHMAC-signed JWT ticket issued by pg_ripple.arrow_flight_ticket(query)
querystringnoInline query (only when pg_ripple.arrow_unsigned_tickets_allowed = on)

Response: application/vnd.apache.arrow.stream — Arrow IPC stream.

Example (Python):

import requests, pyarrow as pa

# 1. Get a signed ticket from PostgreSQL
ticket = pg.execute("SELECT pg_ripple.arrow_flight_ticket('SELECT ?s ?p ?o WHERE { ?s ?p ?o }')")

# 2. Stream the Arrow IPC export
r = requests.post("http://localhost:7878/flight/do_get",
    json={"ticket": ticket},
    headers={"Authorization": f"Bearer {token}"},
    stream=True)

reader = pa.ipc.open_stream(r.raw)
table = reader.read_all()
print(table.to_pandas())

Streaming Subscriptions

GET /subscribe/{subscription_id}

Subscribe to a live SPARQL result stream via Server-Sent Events. The subscription_id is returned by pg_ripple.subscribe(query).

Response Content-Type: text/event-stream

Event types:

EventPayloadDescription
rowJSON objectNew result row
retractJSON objectRetracted row (triple deleted)
heartbeat{}Keep-alive every 30 s
error{"message": "..."}Subscription error

Example:

# Create subscription in PostgreSQL
psql -c "SELECT pg_ripple.subscribe('SELECT ?s ?p ?o WHERE { ?s ?p ?o }')"
-- Returns: sub_abc123

# Connect SSE stream
curl -N "http://localhost:7878/subscribe/sub_abc123" \
  -H "Accept: text/event-stream"

Datalog REST API

GET /datalog/rules

List all registered Datalog rule sets.

Response (200 OK):

[
  {"rule_set": "rdfs_closure", "rule_count": 13, "enabled": true},
  {"rule_set": "custom_rules", "rule_count": 5, "enabled": true}
]

POST /datalog/rules/{rule_set}/add

Add a Datalog rule to a rule set.

Content-Type: application/json

{
  "rule": "ancestor(?x, ?z) :- ancestor(?x, ?y), parent(?y, ?z).",
  "enabled": true
}

Response (200 OK):

{"rule_id": "rule_42", "rule_set": "custom_rules"}

POST /datalog/infer/{rule_set}

Run forward-chaining inference for a rule set.

Content-Type: application/json

{
  "graph": "https://example.org/graph1",
  "max_iterations": 100,
  "dry_run": false
}

Response (200 OK):

{
  "derived_count": 847,
  "iterations": 3,
  "elapsed_ms": 42,
  "stratification_order": ["base_rules", "closure_rules"]
}

POST /datalog/infer/{rule_set}/wfs

Run well-founded semantics inference. Returns three-valued results (true / false / undefined) for recursive rules with negation.


POST /datalog/infer/{rule_set}/demand

Goal-directed magic-sets inference. Only derives facts relevant to a specific query goal.

Content-Type: application/json

{
  "goal": "ancestor(<:Alice>, ?z)",
  "graph": "https://example.org/graph1"
}

POST /datalog/query/{rule_set}

Run a single Datalog goal query against a materialized rule set without modifying the store.

Content-Type: application/json

{
  "goal": "ancestor(<:Alice>, ?z)",
  "limit": 100
}

Response (200 OK):

{
  "results": [
    {"?z": "<https://example.org/Bob>"},
    {"?z": "<https://example.org/Carol>"}
  ],
  "total": 2
}

GET /datalog/constraints

Check all constraint rules across all rule sets.

Response (200 OK):

{
  "violations": [
    {
      "rule_set": "integrity_rules",
      "constraint": "uniqueness_violation",
      "violating_bindings": [{"?x": "<:entity1>"}]
    }
  ],
  "total_violations": 1
}

GET /datalog/stats/cache

Returns rule plan cache hit/miss statistics.


GET /datalog/stats/tabling

Returns tabling cache occupancy and eviction statistics.


PageRank API

POST /pagerank/run

Start a PageRank computation job.

Content-Type: application/json

{
  "graph": "https://example.org/graph1",
  "edge_predicates": ["schema:knows", "schema:worksFor"],
  "damping": 0.85,
  "max_iterations": 100,
  "convergence_delta": 0.0001
}

Response (200 OK):

{
  "job_id": "pr_20250503_001",
  "status": "running",
  "started_at": "2025-05-03T12:00:00Z"
}

GET /pagerank/status

Poll the status of the most recent PageRank job.

Response:

{
  "job_id": "pr_20250503_001",
  "status": "completed",
  "iterations": 47,
  "elapsed_ms": 1204,
  "node_count": 50000,
  "edge_count": 250000
}

GET /pagerank/export

Export PageRank scores as JSON or CSV.

Query parameters:

ParameterDefaultDescription
formatjsonjson or csv
limit1000Maximum nodes
offset0Pagination offset
graph(all)Filter by named graph

Response (200 OK, JSON):

{
  "scores": [
    {"iri": "https://example.org/Alice", "score": 0.0423, "rank": 1},
    {"iri": "https://example.org/Bob", "score": 0.0381, "rank": 2}
  ],
  "total": 50000
}

GET /pagerank/explain/{node_iri}

Explain the PageRank score for a specific node, showing top contributing in-edges.

Path parameter: node_iri — URL-encoded IRI.

Response:

{
  "iri": "https://example.org/Alice",
  "score": 0.0423,
  "rank": 1,
  "top_contributors": [
    {"from_iri": "https://example.org/Bob", "edge_weight": 0.012},
    {"from_iri": "https://example.org/Carol", "edge_weight": 0.009}
  ]
}

POST /centrality/run

Compute centrality metrics (degree, betweenness, Katz).

Content-Type: application/json

{
  "graph": "https://example.org/graph1",
  "metrics": ["degree", "katz"],
  "katz_alpha": 0.01
}

POST /pagerank/find-duplicates

Find near-duplicate nodes by PageRank score similarity and graph structure.


Confidence / Probabilistic API

POST /confidence/load

Load triples with associated confidence scores.

Content-Type: application/json

{
  "triples": [
    {
      "subject": "https://example.org/Alice",
      "predicate": "rdf:type",
      "object": "schema:Person",
      "confidence": 0.95,
      "graph": "https://example.org/g1"
    }
  ]
}

Response (200 OK):

{"inserted": 1, "updated": 0}

GET /confidence/shacl-score

Get SHACL soft-validation confidence scores for shapes.

Query parameters:

ParameterDefaultDescription
shape_iri(all)Filter by specific shape
min_score0.0Minimum score threshold

GET /confidence/shacl-report

Get a full SHACL validation report with confidence scores per constraint.


POST /confidence/vacuum

Vacuum stale confidence score rows from _pg_ripple.confidence.


Administrative Endpoints

GET /health

Returns {"status": "ok"} when the service is running and the database connection pool is healthy.

Response: 200 OK{"status": "ok"} Response: 503 Service Unavailable — database unreachable.


GET /health/ready

Kubernetes-compatible readiness probe. Checks that the PostgreSQL connection pool has at least one available connection.


GET /metrics

Prometheus-format metrics. No authentication required.

Key metrics:

MetricTypeDescription
pg_ripple_http_requests_totalCounterTotal HTTP requests by method, path, status
pg_ripple_http_request_duration_secondsHistogramRequest latency
pg_ripple_sparql_queries_totalCounterSPARQL queries by type
pg_ripple_sparql_query_duration_secondsHistogramSPARQL query latency
pg_ripple_federation_calls_totalCounterSERVICE clause calls by endpoint
pg_ripple_datalog_infer_duration_secondsHistogramInference run latency

GET /metrics/extension

Extension-internal Prometheus metrics sourced directly from the pg_ripple extension within PostgreSQL.


GET /void

Returns a VoID (Vocabulary of Interlinked Datasets) dataset description, summarizing the RDF store contents: triple counts, predicate frequencies, and class distributions.

Accept: text/turtle or application/ld+json


GET /service

Returns a SPARQL 1.1 Service Description document describing the endpoint's capabilities.

Accept: text/turtle or application/ld+json


GET /openapi.yaml

Returns the full OpenAPI 3.1 specification for the pg_ripple_http API.


GET /explorer

Web-based SPARQL explorer UI — an embedded query editor with syntax highlighting, result table, and endpoint configuration.


Error Responses

All error responses use a consistent JSON envelope:

{
  "error": "PT440",
  "message": "query exceeds maximum algebra depth (256)",
  "hint": "Simplify the query or raise pg_ripple.sparql_max_algebra_depth"
}
HTTP StatusMeaning
400Invalid request body or SPARQL syntax error
401Missing or invalid Bearer token
403Operation not permitted for this role
404Resource not found
422Semantic error (SHACL violation, constraint error)
429Rate limit exceeded
500Internal error (check PostgreSQL logs)
503Database connection unavailable

Security

  • Bearer token authentication controls mutating endpoints
  • SSRF protection: federation SERVICE endpoints are checked against federation_endpoint_policy
  • SQL injection prevention: all queries use parameterized PostgreSQL SPI
  • Arrow Flight tickets are HMAC-SHA256 signed; set pg_ripple.arrow_flight_secret
  • Rate limiting: per-IP, configurable via PG_RIPPLE_HTTP_RATE_LIMIT
  • HTTPS termination should be handled by a reverse proxy (nginx, Caddy, Traefik)
  • Never expose PG_RIPPLE_HTTP_AUTH_TOKEN in URLs or logs