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, live subscription streams over Server-Sent Events, 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 protected endpoints require a Bearer token. Read, write, admin, and metrics tokens can be separated with the corresponding environment variables; when a specialized token is unset, the main token is used for that class.

Authorization: Bearer <token>

Health endpoints are public. Metrics are public unless PG_RIPPLE_HTTP_METRICS_TOKEN is configured. All other endpoints are protected by their access class.


Configuration

Environment VariableDefaultDescription
PG_RIPPLE_HTTP_PG_URLpostgresql://localhost/postgresPostgreSQL connection URL
PG_RIPPLE_HTTP_MODEproductiondevelopment or production
PG_RIPPLE_HTTP_BIND127.0.0.1:7878TCP listen address
PG_RIPPLE_HTTP_PORT7878TCP listening port used when bind is unset
PG_RIPPLE_HTTP_POOL_SIZE16PostgreSQL connection pool size
PG_RIPPLE_HTTP_AUTH_TOKEN[_FILE](none)Read bearer token
PG_RIPPLE_HTTP_WRITE_TOKEN[_FILE](falls back to auth token)Write bearer token
PG_RIPPLE_HTTP_ADMIN_TOKEN[_FILE](falls back to auth token)Admin bearer token
PG_RIPPLE_HTTP_METRICS_TOKEN[_FILE](none)Optional metrics bearer token
PG_RIPPLE_HTTP_ALLOW_UNAUTHENTICATED0Development-only explicit auth bypass
PG_RIPPLE_HTTP_PG_PASSWORD[_FILE](unset)PostgreSQL password or mounted secret file
PG_RIPPLE_HTTP_PG_SSLMODEdisabledisable, require, verify-ca, or verify-full
PG_RIPPLE_HTTP_PG_CA_FILE(unset)CA file required for verify-ca and verify-full
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
PG_RIPPLE_HTTP_QUERY_TIMEOUT_MS300000Default streaming query deadline
PG_RIPPLE_HTTP_QUERY_TIMEOUT_MAX_MS900000Maximum streaming query deadline
PG_RIPPLE_HTTP_STREAM_IDLE_TIMEOUT_MS60000Maximum wait between streamed rows
PG_RIPPLE_HTTP_STREAM_CHUNK_BYTES65536Maximum coalesced response chunk
PG_RIPPLE_HTTP_STREAM_MAX_ROW_BYTES1048576Maximum encoded row size
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/sparqlWriteSPARQL 1.1 query/update via request body
POST/sparql/bindingsReadSPARQL query with typed initial bindings
POST/sparql/streamReadExplicit streaming SPARQL compatibility alias
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/extensionMetricsExtension-internal Prometheus metrics
GET/voidReadVoID dataset description
GET/serviceReadSPARQL service description
GET/openapi.yamlReadOpenAPI 3.1 specification
GET/explorerAdminWeb-based SPARQL explorer UI
GET/admin/bench-historyAdminRecent benchmark history from _pg_ripple.bench_history
GET/admin/diagnostic-snapshotAdminDiagnostic bundle with schema, GUC, version, and metrics data
POST/flight/do_getReadArrow 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/cacheAdminRule plan cache statistics
GET/datalog/stats/tablingAdminTabling cache statistics
GET/POST/datalog/latticesRead/AdminList or create lattice structures
GET/POST/datalog/viewsRead/AdminList or create Datalog-backed views
DELETE/datalog/views/{name}AdminDrop 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-duplicatesWriteFind 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/hypotheticalReadWhat-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/draftReadDraft rules from natural-language guidance
POST/rules/validateReadValidate 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_similarityWriteDice similarity over encoded values
POST/dp/noisy_countWriteDifferential privacy noisy count
POST/dp/noisy_histogramWriteDifferential privacy noisy histogram
GET/dp/budget/{dataset}/{principal}ReadPrivacy budget status
POST/entity-resolution/resolveWriteRun entity resolution
POST/entity-resolution/evaluateWriteEvaluate 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
GET/json-mapping/{name}/writeback/configReadValidated JSON mapping writeback configuration

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/bindings

Execute a read-only SELECT, ASK, CONSTRUCT, or DESCRIBE query with one-row typed initial bindings. The request body is JSON; binding values use the W3C SPARQL Results JSON term shape and support uri and literal terms.

{
  "query": "SELECT ?s WHERE { ?s <https://example.org/email> ?email }",
  "bindings": {
    "email": {"type": "literal", "value": "alice@example.test"}
  },
  "prefix_mode": "strict",
  "timeout_ms": 1000
}

Use prefix_mode: "registered" to resolve undeclared prefixes from the governed registry. Query-local declarations take precedence. Binding payloads are validated before streaming begins; SPARQL Update, blank-node, RDF-star, and multi-row bindings are rejected.

The response uses the same content negotiation and streaming formats as POST /sparql/stream.


POST /sparql/stream

Explicit streaming compatibility alias. Results are delivered from the PostgreSQL row stream with natural HTTP backpressure.

Request: Same as POST /sparql.

Response Content-Type: application/sparql-results+json, text/csv, text/tab-separated-values, or application/n-triples, selected by Accept. JSON is a complete SPARQL Results JSON document, not JSON-Lines or SSE. XML, Turtle, and JSON-LD remain buffered on /sparql.

Example:

curl -X POST http://localhost:7878/sparql/stream \
  -H "Content-Type: application/sparql-query" \
  -H "Accept: application/sparql-results+json" \
  -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)
422writeback_key_column_missingA configured key-column predicate has no value for this subject (PT0552)

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
}

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

Return the validated relational target and writeback health for one mapping. The response mirrors pg_ripple.writeback_inspect() and requires read auth when authentication is enabled.

Response (200 OK):

{
  "target_schema": "public",
  "target_table": "contacts",
  "key_columns": ["contact_id"],
  "conflict_policy": "replace",
  "writeback_enabled": false,
  "trigger_count": 0,
  "queue_depth": 0
}

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