Headers, Content Types, and Request Sizing
This document covers HTTP headers, content type negotiation, request size limits, and related considerations for the Fluree HTTP API.
Request Headers
Content-Type
Specifies the format of the request body.
Supported Values:
JSON-LD Transactions and Queries:
Content-Type: application/json
Default for JSON-LD transactions and JSON-LD queries.
Content-Type: application/ld+json
Explicit JSON-LD content type.
SPARQL Queries:
Content-Type: application/sparql-query
For SPARQL SELECT, ASK, CONSTRUCT queries.
Content-Type: application/sparql-update
For SPARQL UPDATE operations. See SPARQL Transactions for supported operations.
RDF Formats:
Content-Type: text/turtle
For Turtle RDF format transactions. Supported on /insert (fast direct path) and /upsert.
Content-Type: application/trig
For 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-triples
For N-Triples format (future support).
Content-Type: application/rdf+xml
For RDF/XML format (future support).
Accept
Specifies the desired response format.
Supported Values:
Accept: application/json
Compact JSON format (default).
Accept: application/ld+json
Full JSON-LD with @context.
Accept: application/sparql-results+json
SPARQL JSON Results format (for SPARQL queries).
Accept: application/sparql-results+xml
SPARQL XML Results format (for SPARQL SELECT/ASK queries).
Accept: text/turtle
Turtle RDF format (for CONSTRUCT queries).
Accept: application/rdf+xml
RDF/XML graph format (for CONSTRUCT/DESCRIBE queries).
Accept: application/vnd.fluree.agent+json
Agent 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: 32768
Accept: application/n-triples
N-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.8
The server will choose the best match based on quality values and support.
Authorization
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/jose
See Signed Requests for details.
Content-Length
The server requires Content-Length for all POST requests:
Content-Length: 1234
Most HTTP clients set this automatically.
Accept-Encoding
Request compressed responses:
Accept-Encoding: gzip, deflate
The server will compress responses when appropriate, reducing bandwidth usage.
Response Header:
Content-Encoding: gzip
User-Agent
Identify your client application:
User-Agent: MyApp/1.0.0 (https://example.com)
Helpful for server logs and troubleshooting.
X-Request-ID
Client-supplied request ID for tracing:
X-Request-ID: abc-123-def-456
The 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.
Response Headers
Content-Type
Indicates the format of the response body:
Content-Type: application/json; charset=utf-8
Content-Length
Size of the response body in bytes:
Content-Length: 5678
X-Fluree-T
The transaction time of the data returned (for queries):
X-Fluree-T: 42
Useful for tracking which version of data was queried.
X-Fluree-Commit
The commit ContentId of the data returned:
X-Fluree-Commit: abc123def456789...
ETag
Entity tag for caching:
ETag: "abc123def456"
Can be used with If-None-Match for conditional requests.
Cache-Control
Caching directives:
For current queries:
Cache-Control: no-cache
For historical queries:
Cache-Control: public, max-age=31536000, immutable
Historical queries are immutable and cache indefinitely.
X-RateLimit Headers
Rate limit information (if enabled):
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642857600
X-Request-ID
Echo of client-supplied request ID or server-generated ID:
X-Request-ID: abc-123-def-456
X-Response-Time
Server processing time in milliseconds:
X-Response-Time: 45
Content Type Details
JSON-LD (application/json, application/ld+json)
Request 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" }
]
}
SPARQL Query (application/sparql-query)
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.
SPARQL Results JSON (application/sparql-results+json)
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.
Turtle (text/turtle)
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" .
Request Size Limits
Default Limits
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
Exceeding Limits
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"
}
Configuration
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 MB
Response Size Limits
The 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
}
Compression
Request Compression
Send compressed requests (for large transactions):
Content-Encoding: gzip
Content-Type: application/json
The request body should be gzip-compressed JSON.
Response Compression
Request compressed responses:
Accept-Encoding: gzip, deflate
The 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-Encoding
Compression Benefits:
- Reduced bandwidth usage (typically 70-90% for JSON)
- Faster response times on slower connections
- Lower costs for cloud deployments
Character Encoding
All text content uses UTF-8 encoding.
Request:
Content-Type: application/json; charset=utf-8
Response:
Content-Type: application/json; charset=utf-8
Unicode characters are supported in:
- IRIs
- Literal values
- Property names
- Comments
CORS Headers
For web browser access, the server supports Cross-Origin Resource Sharing (CORS).
CORS Request Headers
Preflight Request:
OPTIONS /query HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
CORS Response Headers
Preflight 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: 86400
Actual Response:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
CORS Configuration
Configure 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.
Caching Headers
ETag and Conditional Requests
The server supports ETags for efficient caching.
Initial Request:
GET /ledgers/mydb:main HTTP/1.1
Response:
HTTP/1.1 200 OK
ETag: "abc123def456"
Cache-Control: no-cache
Conditional Request:
GET /ledgers/mydb:main HTTP/1.1
If-None-Match: "abc123def456"
Not Modified Response:
HTTP/1.1 304 Not Modified
ETag: "abc123def456"
Immutable Historical Data
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.
Custom Headers
X-Fluree-Fuel-Limit
Set query fuel limit to prevent runaway queries:
X-Fluree-Fuel-Limit: 1000000
See Tracking and Fuel Limits for details.
X-Fluree-Timeout
Set query timeout in milliseconds:
X-Fluree-Timeout: 30000
X-Fluree-Policy
Specify a policy to apply (if authorized):
X-Fluree-Policy: ex:restrictive-policy
Best Practices
1. Always Set Content-Type
Explicitly set Content-Type for all requests:
Content-Type: application/json
2. Accept Compression
Always request compression for better performance:
Accept-Encoding: gzip, deflate
3. Use Appropriate Accept Headers
Request the format you need:
Accept: application/json
4. Include User-Agent
Identify your application:
User-Agent: MyApp/1.0.0
5. Handle ETags
Implement ETag caching for frequently accessed resources:
const etag = localStorage.getItem('ledger-etag');
if (etag) {
headers['If-None-Match'] = etag;
}
6. Monitor Rate Limits
Check rate limit headers and back off when needed:
const remaining = response.headers.get('X-RateLimit-Remaining');
if (remaining < 10) {
// Slow down requests
}
7. Use Request IDs
Include request IDs for tracing:
X-Request-ID: uuid-v4-here
Related Documentation
- Overview - API overview
- Endpoints - Endpoint reference
- Signed Requests - Authentication
- Errors - Error handling