This document covers HTTP headers, content type negotiation, request size limits, and related considerations for the Fluree HTTP API.
Specifies the format of the request body.
Supported Values:
JSON-LD Transactions and Queries:
Content-Type: application/jsonDefault for JSON-LD transactions and JSON-LD queries.
Content-Type: application/ld+jsonExplicit JSON-LD content type.
SPARQL Queries:
Content-Type: application/sparql-queryFor SPARQL SELECT, ASK, CONSTRUCT queries.
Content-Type: application/sparql-updateFor SPARQL UPDATE operations. See SPARQL Transactions for supported operations.
RDF Formats:
Content-Type: text/turtleFor Turtle RDF format transactions. Supported on /insert (fast direct path) and /upsert.
Content-Type: application/trigFor TriG format transactions with named graphs (GRAPH blocks). Only supported on /upsert - returns 400 error on /insert because named graph ingestion requires the upsert path.
Content-Type: application/n-triplesFor N-Triples format (future support).
Content-Type: application/rdf+xmlFor RDF/XML format (future support).
Specifies the desired response format.
Supported Values:
Accept: application/jsonCompact JSON format (default).
Accept: application/ld+jsonFull JSON-LD with @context.
Accept: application/sparql-results+jsonSPARQL JSON Results format (for SPARQL queries).
Accept: application/sparql-results+xmlSPARQL XML Results format (for SPARQL SELECT/ASK queries).
Accept: text/turtleTurtle RDF format (for CONSTRUCT queries).
Accept: application/rdf+xmlRDF/XML graph format (for CONSTRUCT/DESCRIBE queries).
Accept: application/vnd.fluree.agent+jsonAgent JSON format — optimized for LLM/agent consumption. Returns a self-describing envelope with schema, compact rows, and pagination support. See Output Formats for details.
Use the Fluree-Max-Bytes header to set a byte budget for response truncation:
Fluree-Max-Bytes: 32768Accept: application/n-triplesN-Triples format (future support).
Multiple Accept Values:
You can specify multiple formats with quality values:
Accept: application/ld+json; q=1.0, application/json; q=0.8The server will choose the best match based on quality values and support.
Authentication credentials. Only required when the server has authentication enabled for the relevant endpoint group (see Configuration).
Bearer Token (Ed25519 JWS or OIDC):
Authorization: Bearer eyJhbGciOiJFZERTQSIsImp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Ii4uLiJ9fQ...The server automatically dispatches to the correct verification path based on the token header:
- Tokens with an embedded
jwkfield use the Ed25519 verification path - Tokens with a
kidfield use the OIDC/JWKS verification path (requiresoidcfeature)
Signed Requests:
For JWS/VC signed request bodies, set Content-Type to application/jose:
Content-Type: application/joseSee Signed Requests for details.
The server requires Content-Length for all POST requests:
Content-Length: 1234Most HTTP clients set this automatically.
Request compressed responses:
Accept-Encoding: gzip, deflateThe server will compress responses when appropriate, reducing bandwidth usage.
Response Header:
Content-Encoding: gzipIdentify your client application:
User-Agent: MyApp/1.0.0 (https://example.com)Helpful for server logs and troubleshooting.
Client-supplied request ID for tracing:
X-Request-ID: abc-123-def-456The server will include this in logs and response headers for correlation. When a request queues background indexing work, the copied X-Request-ID also appears on the background indexer worker logs so you can connect the foreground request and later indexing activity in plain log search.
Request a hard read-after-write guarantee for query and explain endpoints:
Fluree-Min-T: 42Before executing the request, the server refreshes the referenced ledger(s) until each has reached at least the requested transaction time. If the target t is not visible before query_min_t_timeout_ms, the server returns a read-after-write timeout error. JSON-LD query bodies may also specify the same requirement as opts.min-t, opts.min_t, or opts.minT; body opts take precedence over the header for that query body.
Numeric time-travel snapshots such as from: "ledger:main@t:42" also wait until that t is visible, then query that pinned snapshot. Fluree-Min-T is useful when the query itself reads current HEAD but must not run until a known transaction has arrived.
The header must resolve to at least one target ledger. On a ledger-scoped endpoint the endpoint's ledger is used; on the connection-scoped query endpoint the target comes from the query's FROM clause. Sending Fluree-Min-T to the connection-scoped endpoint with no FROM (and no other resolvable ledger) is rejected with 400 Bad Request rather than silently ignored.
Indicates the format of the response body:
Content-Type: application/json; charset=utf-8Size of the response body in bytes:
Content-Length: 5678The transaction time of the data returned (for queries):
X-Fluree-T: 42Useful for tracking which version of data was queried.
The commit ContentId of the data returned:
X-Fluree-Commit: abc123def456789...Entity tag for caching:
ETag: "abc123def456"Can be used with If-None-Match for conditional requests.
Caching directives:
For current queries:
Cache-Control: no-cacheFor historical queries:
Cache-Control: public, max-age=31536000, immutableHistorical queries are immutable and cache indefinitely.
Rate limit information (if enabled):
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642857600Echo of client-supplied request ID or server-generated ID:
X-Request-ID: abc-123-def-456Server processing time in milliseconds:
X-Response-Time: 45Request Example:
{
"@context": {
"ex": "http://example.org/ns/",
"schema": "http://schema.org/"
},
"@graph": [
{
"@id": "ex:alice",
"@type": "schema:Person",
"schema:name": "Alice"
}
]
}Compact vs Expanded:
application/json returns compact JSON:
[
{ "name": "Alice" }
]application/ld+json returns with full context:
{
"@context": {
"name": "http://schema.org/name"
},
"@graph": [
{ "name": "Alice" }
]
}Request Example:
PREFIX ex: <http://example.org/ns/>
PREFIX schema: <http://schema.org/>
SELECT ?name
FROM <mydb:main>
WHERE {
?person a schema:Person .
?person schema:name ?name .
}Plain text SPARQL query in the request body.
Response Example:
{
"head": {
"vars": ["name"]
},
"results": {
"bindings": [
{
"name": {
"type": "literal",
"value": "Alice",
"datatype": "http://www.w3.org/2001/XMLSchema#string"
}
}
]
}
}Follows W3C SPARQL 1.1 Query Results JSON Format specification.
Transaction Request:
@prefix ex: <http://example.org/ns/> .
@prefix schema: <http://schema.org/> .
ex:alice a schema:Person ;
schema:name "Alice" ;
schema:age 30 .CONSTRUCT Response:
@prefix ex: <http://example.org/ns/> .
@prefix schema: <http://schema.org/> .
ex:alice a schema:Person .
ex:alice schema:name "Alice" .The server enforces size limits to prevent resource exhaustion:
Transaction Requests:
- Default limit: 10 MB
- Configurable:
--max-transaction-size
Query Requests:
- Default limit: 1 MB
- Configurable:
--max-query-size
History Requests:
- Default limit: 1 MB
- Configurable:
--max-history-size
If a request exceeds size limits:
Status Code: 413 Payload Too Large
Response:
{
"error": "Request body exceeds maximum size of 10485760 bytes",
"status": 413,
"@type": "err:http/PayloadTooLarge"
}Set custom limits when starting the server:
./fluree-db-server \
--max-transaction-size 20971520 \ # 20 MB
--max-query-size 2097152 \ # 2 MB
--max-response-size 104857600 # 100 MBThe server also limits response sizes:
Default limit: 100 MB
If a query result exceeds the limit:
Status Code: 413 Payload Too Large
Response:
{
"error": "Query result exceeds maximum response size",
"status": 413,
"@type": "err:http/ResponseTooLarge"
}Solution: Use LIMIT and pagination:
{
"select": ["?name"],
"where": [...],
"limit": 1000,
"offset": 0
}Send compressed requests (for large transactions):
Content-Encoding: gzip
Content-Type: application/jsonThe request body should be gzip-compressed JSON.
Request compressed responses:
Accept-Encoding: gzip, deflateThe server will compress responses when:
- Client accepts compression
- Response is larger than threshold (typically 1 KB)
- Content-Type is compressible
Response Headers:
Content-Encoding: gzip
Vary: Accept-EncodingCompression Benefits:
- Reduced bandwidth usage (typically 70-90% for JSON)
- Faster response times on slower connections
- Lower costs for cloud deployments
All text content uses UTF-8 encoding.
Request:
Content-Type: application/json; charset=utf-8Response:
Content-Type: application/json; charset=utf-8Unicode characters are supported in:
- IRIs
- Literal values
- Property names
- Comments
For web browser access, the server supports Cross-Origin Resource Sharing (CORS).
Preflight Request:
OPTIONS /query HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-TypePreflight Response:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400Actual Response:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: trueConfigure CORS when starting the server:
./fluree-db-server \
--cors-origin "https://example.com" \
--cors-methods "GET,POST,OPTIONS" \
--cors-headers "Content-Type,Authorization"Allow all origins (development only):
./fluree-db-server --cors-origin "*"Never use --cors-origin "*" in production with credentials.
The server supports ETags for efficient caching.
Initial Request:
GET /ledgers/mydb:main HTTP/1.1Response:
HTTP/1.1 200 OK
ETag: "abc123def456"
Cache-Control: no-cacheConditional Request:
GET /ledgers/mydb:main HTTP/1.1
If-None-Match: "abc123def456"Not Modified Response:
HTTP/1.1 304 Not Modified
ETag: "abc123def456"Historical queries with time specifiers are immutable:
Query:
POST /query HTTP/1.1
{"from": "mydb:main@t:100", ...}Response:
HTTP/1.1 200 OK
Cache-Control: public, max-age=31536000, immutable
ETag: "mydb:main@t:100:query-hash"Clients can cache these responses indefinitely.
Set query fuel limit to prevent runaway queries:
X-Fluree-Fuel-Limit: 1000000See Tracking and Fuel Limits for details.
Set query timeout in milliseconds:
X-Fluree-Timeout: 30000Specify a policy to apply (if authorized):
X-Fluree-Policy: ex:restrictive-policyExplicitly set Content-Type for all requests:
Content-Type: application/jsonAlways request compression for better performance:
Accept-Encoding: gzip, deflateRequest the format you need:
Accept: application/jsonIdentify your application:
User-Agent: MyApp/1.0.0Implement ETag caching for frequently accessed resources:
const etag = localStorage.getItem('ledger-etag');
if (etag) {
headers['If-None-Match'] = etag;
}Check rate limit headers and back off when needed:
const remaining = response.headers.get('X-RateLimit-Remaining');
if (remaining < 10) {
// Slow down requests
}Include request IDs for tracing:
X-Request-ID: uuid-v4-here- Overview - API overview
- Endpoints - Endpoint reference
- Signed Requests - Authentication
- Errors - Error handling