Authentication

All Fipto API requests are signed with the HTTP Signatures protocol using RSA-SHA256 (algorithm hs2019). Generate your RSA key pair, register the public key in the Fipto app, and sign every request with the required headers.

All Fipto API requests are signed with the HTTP Signatures protocol using RSA-SHA256 (algorithm hs2019). This page walks through key generation, the required headers, the signing string and a worked example.

Quick facts

  • Protocol: HTTP Signatures
  • Algorithm: RSA-SHA256 (hs2019)
  • Key size: 2048-bit RSA
  • Required headers (all requests): Host, Date, Signature
  • Required headers (POST/PUT/PATCH): plus Content-Type and Digest
  • Demo host: api.demo.fipto.tech
  • Production host: api.fipto.app

Before you start

Before you can authenticate, you need:

  1. A Fipto account in demo or production. See Get started with Fipto.
  2. An RSA key pair. Generate one in the next section.
  3. An API integration created in the Fipto web application (Settings > API integrations) with your public key. Its Key ID is the keyId in every signature. Create one per environment, with a separate key pair for demo and production.

1. Generate an RSA key pair

Generate a 2048-bit RSA private key and a matching public key. The public key is the one you register in the Fipto web application; the private key never leaves your environment.

# Private key
openssl genrsa -out private-key.rsa 2048
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
  -in private-key.rsa -out private-key.pem

# Public key
openssl rsa -in private-key.rsa -pubout -out public-key.pem

In the Fipto web application, go to Settings > API integrations, click Create integration and upload the public key file (public-key.pem in the example above) or paste its content. Once the integration is created, its Key ID is the keyId you use in every signed request.

2. Required headers

Every authenticated Fipto API request must include the following headers.

HeaderRequired onValue
HostAll requestsapi.demo.fipto.tech (demo) or api.fipto.app (production)
DateAll requestsRFC 1123 timestamp, no older than one minute and not in the future
SignatureAll requestsSignature block (see step 4)
Content-TypePOST, PUT, PATCHMIME type of the body, typically application/json
DigestPOST, PUT, PATCHBase64-encoded SHA-256 of the body, prefixed with SHA-256=

Generate the Digest header from the body. On Unix:

echo -n "$BODY" | openssl dgst -sha256 -binary | openssl enc -base64 -A

Prepend SHA-256= to that value to produce the final header.

3. Build the signing string

The signing string concatenates the (request-target) pseudo-header and every header you intend to sign, each on its own line, in the order they will appear in the headers field of the signature block.

For a POST request, the signing string looks like:

(request-target): post /companies/c240e5bf-863e-4f44-91aa-cc74a8b3303f/wallets
host: api.demo.fipto.tech
date: Fri, 24 Jan 2025 08:56:30 GMT
content-type: application/json
digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=

Sign this string with your RSA private key using SHA-256, then base64-encode the result.

4. The Signature header

Place the base64-encoded signature inside the Signature header along with the other required fields.

Signature: keyId="<your-key-id>",algorithm="hs2019",headers="(request-target) host date content-type digest",signature="<base64-encoded-signature>"

Field rules:

  • keyId must be the Key ID of your API integration (shown in Settings > API integrations).
  • algorithm must be hs2019 (its synonym rsa-sha256 is also accepted).
  • headers must list, in order: (request-target), then every header that appears in the signing string. For GET requests, omit content-type and digest.
  • signature is the base64-encoded RSA-SHA256 signature of the signing string.

Worked example: GET request

curl https://api.demo.fipto.tech/companies/$COMPANY_ID/wallets \
  -H "Host: api.demo.fipto.tech" \
  -H "Date: $(date -uR)" \
  -H 'Signature: keyId="<your-key-id>",algorithm="hs2019",headers="(request-target) host date",signature="<base64-encoded-signature>"'

Worked example: POST request with body

BODY='{"data":{"type":"wallet","attributes":{"name":"Merchant · Acme Corp","asset":"USDC_BASE"}}}'
DIGEST="SHA-256=$(echo -n "$BODY" | openssl dgst -sha256 -binary | openssl enc -base64 -A)"

curl https://api.demo.fipto.tech/companies/$COMPANY_ID/wallets \
  -H "Host: api.demo.fipto.tech" \
  -H "Date: $(date -uR)" \
  -H "Content-Type: application/json" \
  -H "Digest: $DIGEST" \
  -H 'Signature: keyId="<your-key-id>",algorithm="hs2019",headers="(request-target) host date content-type digest",signature="<base64-encoded-signature>"' \
  -d "$BODY"

A working Postman collection that signs requests for you is available in the Postman collection guide.

Common errors

HTTP statusLikely causeFix
401 UnauthorizedkeyId does not match a registered keyCheck the Key ID in Settings > API integrations and that the integration uses your current public key
401 UnauthorizedDate header is older than one minute or in the futureSync your clock; regenerate the request
401 UnauthorizedSigning string mismatchReproduce the exact byte order of headers in headers=
400 Bad Request with Digest mismatchDigest does not match the bodyRecompute the base64 SHA-256 of the actual transmitted body
415 Unsupported Media TypeMissing Content-Type on a POSTAlways set Content-Type: application/json for JSON bodies

Frequently asked questions

What algorithm does Fipto use for HTTP Signatures?

RSA-SHA256, declared as hs2019 (also accepted as rsa-sha256).

How do I authenticate Fipto API requests in Python or Node?

Use any library that implements the HTTP Signatures draft. In Python, requests-http-signature works. In Node, http-signature by TJ Fontaine is the reference. The Fipto Postman collection also includes a JavaScript pre-request script you can adapt.

Do I need a new key pair for demo and production?

Yes, we strongly recommend it. Reusing the same key pair is technically possible but bad practice: keep a separate key pair and API integration per environment so a test request can never act on your live company.

How long is a signed request valid?

Up to one minute after the time in its Date header. A Date older than one minute, or set in the future even by a few seconds, is rejected. Keep your clock synchronised (NTP).

What does Fipto support: HMAC or RSA signatures?

RSA only, via HTTP Signatures with the hs2019 algorithm.