FlureeLabs

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 jwk field use the Ed25519 verification path
  • Tokens with a kid field use the OIDC/JWKS verification path (requires oidc feature)

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