Skip to main content
Every REST request must include both an API key and a signed JWT:
The API key identifies the API application. The JWT proves possession of the private key that matches the public key stored on the application, binds the token to the exact request, and prevents replay.

JWT requirements

Use RS256 and include these claims: For requests without a body, hash the empty byte string. For JSON requests, hash the exact JSON bytes sent to the API. Do not sign a pretty-printed body and send a minified body.

Node.js example

Shell and OpenSSL example

This example requires jq, openssl, and xxd.

Python example

cURL flow

Generate the JWT immediately before calling the endpoint. Use the same exact URL, method, and body bytes for signing and sending.

Multipart body hash

For multipart requests, the JWT bodyHash is not the raw multipart stream hash. Nuvera validates a canonical multipart hash after parsing fields and files:
  1. Convert each form field value to a string.
  2. Sort repeated values for a field.
  3. Sort fields by name and value.
  4. For each file, include fieldName, fileName, mimeType, size, and the SHA-256 hash of the file bytes.
  5. Sort files by field name, file name, size, and file SHA-256.
  6. Hash JSON.stringify({ fields, files }).
This is the same shape used in proof artifacts for multipart requests. Store field names, file names, MIME types, sizes, and file hashes in proofs, not raw file bytes.
A changed query string, body byte, multipart file name, or repeated jti will reject the request even when the API key is valid.