Authentication
Flux API delivers published content. Each Flux API instance can be public or require API keys. When authentication is enabled, every request must present a valid Flux API key using one of the supported methods.
Overview
- Configuration – Toggle authentication per API when creating or updating it through the Management API.
- Keys – Generate Flux API keys through the dashboard or Management API. Each key contains a Base64 public key and a private key that is shown only once.
- Methods – Flux API supports Secure (signature-based) and Simple (development-only) authentication. Secure mode is strongly recommended for production APIs.
When an API is marked as “authentication required”, unauthenticated requests return 401 with error_code authentication_required.
API Key Components
When you create a Flux API key you receive:
- Name
public_key- Type
- string
- Description
Base64 encoded compressed P-256 public key. Appears in the
Authorizationheader.
- Name
secret_key- Type
- string
- Description
Base64 encoded private key in DER format. Used to sign data for Secure auth. The service never stores the full secret, so keep it safe.
Both authentication methods expect Base64 values exactly as they were issued. Do not decode or re-encode using different alphabets.
Authentication Methods
- Name
Secure- Description
Signs each request using ECDSA P-256 + SHA256. Provides integrity, timestamp validation, and replay protection. Strongly recommended for production APIs.
- Name
Simple- Description
Sends
{public}:{private}without signatures. Available only for development or internal testing. Disable in production environments.
Secure Authentication
Secure authentication verifies a signature built from the request path, body hash, and timestamp.
Required Headers
- Name
Authorization- Type
- string
- Required
- required
- Description
Secure <public_key>:<signature>where<signature>is Base64-encoded ECDSA output.
- Name
Date- Type
- string
- Required
- required
- Description
ISO 8601 UTC timestamp, e.g.,
2025-01-12T08:15:30Z. Requests older than 15 minutes are rejected.
Data to Sign
- Compute the SHA-256 hash of the request body. Use the empty string when no body is present (
e3b0c442…b855in hex). - Concatenate the pieces:
data_to_sign = "<request_path>|<body_hash>|<timestamp>"
request_path– The exact path sent to Flux API, including the API prefix and resource path (e.g.,/blog-api/articles/_search). Do not include the protocol or host.body_hash– Lowercase hex digest of the SHA-256 hash.timestamp– Same value as theDateheader.
- Sign
data_to_signwith your private key using ECDSA over the P-256 curve and SHA-256. Encode the signature in Base64 and include it in theAuthorizationheader.
import crypto from 'crypto';
import fetch from 'node-fetch';
const publicKey = process.env.FLUX_PUBLIC_KEY;
const privateKey = process.env.FLUX_PRIVATE_KEY; // Base64 DER
const uri = '/blog-api/articles/_search';
const body = JSON.stringify({
where: {
$: { all_of: [{ status__eq: 'published' }] }
}
});
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const timestamp = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
const dataToSign = `${uri}|${bodyHash}|${timestamp}`;
const sign = crypto.createSign('SHA256');
sign.update(dataToSign);
const signature = sign.sign({
key: Buffer.from(privateKey, 'base64'),
format: 'der',
type: 'pkcs8'
}).toString('base64');
const headers = {
Authorization: `Secure ${publicKey}:${signature}`,
Date: timestamp,
'Content-Type': 'application/json'
};
const response = await fetch(`https://7c9h4pwu.fxns.io${uri}`, {
method: 'POST',
headers,
body
});
console.log(await response.json());
Simple Authentication
Simple authentication sends both public and private keys in a single header:
Authorization: Simple <public_key>:<private_key>
Use this only in secure development or internal testing environments. Simple mode does not sign requests and offers no replay protection. Disable it for public-facing APIs by requiring secure authentication exclusively.
Error Responses
When authentication fails, the Flux API returns 401 with JSON content similar to:
{
"message": "Invalid signature",
"error_code": "authentication_required",
"detail": null
}
Common reasons:
- Missing
AuthorizationorDateheader. - Incorrect path or body hash used during signature generation.
- Timestamp outside the ±15 minute window.
- Keys revoked or not authorized for the requested API prefix.
Verify all inputs before retrying to avoid throttling.