Skip to content

Authentication

The Spritz API supports multiple authentication methods depending on your integration type.

For user-facing applications with Cognito authentication:

Terminal window
curl https://api.spritz.finance/v1/users/me \
-H "Authorization: Bearer <cognito-jwt>"

For frontend integrators. Tokens are prefixed with spr_ and obtained via the token exchange endpoint:

Terminal window
curl https://api.spritz.finance/v1/users/me \
-H "Authorization: Bearer spr_<token>"

For backend integrators requiring the strongest authentication. Requires three headers in addition to the bearer token:

HeaderDescription
X-Integrator-KeyYour integrator API key (format: int_...)
X-SignatureHMAC-SHA256 signature (format: sha256=<hex>)
X-TimestampUnix timestamp in milliseconds

The HMAC payload is: {timestamp}.{METHOD}.{path}.{bodyHash}

  • timestamp: Unix timestamp in milliseconds (same as X-Timestamp)
  • METHOD: HTTP method in uppercase (GET, POST, etc.)
  • path: Request path (e.g., /v1/users/me)
  • bodyHash: SHA256 hex digest of the request body (empty string hash if no body)

Timestamp tolerance is 5 minutes (300 seconds).

import { createHmac, createHash } from "crypto";
function signRequest(
method: string,
path: string,
body: string | undefined,
secret: string,
) {
const timestamp = Date.now().toString();
const bodyHash = createHash("sha256")
.update(body ?? "")
.digest("hex");
const payload = `${timestamp}.${method.toUpperCase()}.${path}.${bodyHash}`;
const signature = createHmac("sha256", secret).update(payload).digest("hex");
return {
"X-Timestamp": timestamp,
"X-Signature": `sha256=${signature}`,
};
}

For programmatic access. Keys are prefixed with sk_test_ (sandbox) or sk_live_ (production):

Terminal window
curl https://api.spritz.finance/v1/users/me \
-H "Authorization: Bearer sk_live_abc123..."

For backward compatibility with older SDKs. Uses the X-INTEGRATION-KEY header alongside a bearer token. Less secure than HMAC — migrate to HMAC when possible.

StatusTypeMeaning
401urn:problem-type:auth:unauthorizedMissing or invalid credentials
401urn:problem-type:auth:invalid-tokenToken expired or malformed
403urn:problem-type:auth:forbiddenValid credentials but insufficient permissions
429Rate limited (check Retry-After header)
Prompt for your LLM Copy this into Claude, Cursor, or your AI assistant
You are integrating authentication for the Spritz Finance API.

Base URLs:

- Production: https://api.spritz.finance
- Sandbox: https://api-staging.spritz.finance

Auth methods (choose based on integration type):

1. API Key (simplest — for server-to-server):
 Header: Authorization: Bearer sk*test*<key> (sandbox) or sk*live*<key> (production)

2. HMAC Signature (most secure — for backend integrators):
 Required headers:
 - Authorization: Bearer <user-api-key>
 - X-Integrator-Key: int_<your-key>
 - X-Signature: sha256=<hmac-hex>
 - X-Timestamp: <unix-ms>

 Signature payload: "{timestamp}.{METHOD}.{path}.{bodyHash}"
 - timestamp = unix milliseconds (same as X-Timestamp header)
 - METHOD = uppercase HTTP method
 - path = request path e.g. /v1/users/me
 - bodyHash = SHA256 hex of request body (or empty string if no body)
 - Sign with HMAC-SHA256 using your integrator secret
 - Timestamp tolerance: +/- 5 minutes

 Implementation:
 ```typescript
 import { createHmac, createHash } from "crypto";

 function signRequest(method: string, path: string, body: string | undefined, secret: string) {
 const timestamp = Date.now().toString();
 const bodyHash = createHash("sha256").update(body ?? "").digest("hex");
 const payload = `${timestamp}.${method.toUpperCase()}.${path}.${bodyHash}`;
 const signature = createHmac("sha256", secret).update(payload).digest("hex");
 return { "X-Timestamp": timestamp, "X-Signature": `sha256=${signature}` };
 }
 ```

3. Integrator JWT (for frontend integrators):
 Token prefix: spr*
 Header: Authorization: Bearer spr*<jwt>
 Obtained via token exchange endpoint.

4. Legacy integration key (deprecated):
 Header: X-INTEGRATION-KEY: <key>
 Plus: Authorization: Bearer <user-api-key>
 No HMAC signing. Migrate to HMAC auth.

Auth errors:

- 401 + type "urn:problem-type:auth:unauthorized" → missing/invalid credentials
- 401 + type "urn:problem-type:auth:invalid-token" → expired/malformed token
- 403 + type "urn:problem-type:auth:forbidden" → insufficient permissions
- 429 → rate limited, check Retry-After header

Rate limiting:

- Per-user and per-integrator limits applied after authentication
- Read endpoints have higher limits than write endpoints
- Rate limit headers included in responses