Skip to main content

Authentication

Thiqwave uses two authentication mechanisms depending on the caller:

CallerMechanismUsed for
Partner dashboard / adminKeycloak JWT (Bearer token)Managing applications, generating keys, partner onboarding
Server-to-server API callsAPI Key (X-API-Key header)Payment flows, transaction queries, webhooks

Concepts

Partner

A Partner is the company that has signed up to Thiqwave. It represents your organization.

Application

An Application is a logical grouping of credentials for one product or integration. Each application belongs to a single environment — either TEST (testnet/sandbox) or LIVE (mainnet/production).

A typical partner setup:

Acme Corp (Partner)
├── "Payment Gateway" [TEST] → sandbox credentials
└── "Payment Gateway" [LIVE] → production credentials

See Environments for a full guide on the TEST/LIVE model.

API Key

An API Key (also called a client secret) is the credential used for machine-to-machine requests. It:

  • Belongs to one Application and therefore one environment
  • Is shown exactly once at creation — store it securely immediately
  • Can be rotated at any time without downtime (create new, update app, revoke old)
  • Has an optional expiry date

Getting Your API Key

1. Obtain a Keycloak token

Log in to the Thiqwave Dashboard or use the OAuth2 password flow for development:

TOKEN=$(curl -s -X POST \
http://localhost:8080/realms/thiqwave/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=partner-service" \
-d "username=you@company.com" \
-d "password=your-password" \
-d "grant_type=password" | jq -r '.access_token')

2. Register your company (once)

curl -X POST https://api.thiqwave.com/api/v1/auth/register \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"company_name": "Acme Corp",
"email": "dev@acme.com"
}'

3. Create an application

# Create a TEST application
curl -X POST https://api.thiqwave.com/api/v1/applications \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "My Payment App", "environment": "TEST" }'

Note the id in the response — you need it in the next step.

4. Generate an API key

curl -X POST https://api.thiqwave.com/api/v1/applications/<app-id>/keys \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

Response:

{
"api_key_id": "01970000-0000-7000-8000-bbbbbbbbbbbb",
"prefix": "a1b2c3d4",
"type": "TEST",
"expires_at": null,
"created_at": "2026-02-26T12:00:00.000Z",
"client_secret": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
Store the secret immediately

The client_secret is returned once and never stored on our servers. Save it to a secrets manager before closing this response.


Making Authenticated Requests

Use the client_secret in the X-API-Key header for all API calls:

cURL

curl https://api.thiqwave.com/api/v1/transactions \
-H "X-API-Key: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
-H "Content-Type: application/json"

JavaScript / Node.js

const response = await fetch('https://api.thiqwave.com/api/v1/transactions', {
headers: {
'X-API-Key': process.env.THIQWAVE_API_SECRET,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
});

const data = await response.json();

Python

import os
import requests

headers = {
'X-API-Key': os.environ['THIQWAVE_API_SECRET'],
'Content-Type': 'application/json',
'Idempotency-Key': str(uuid.uuid4()),
}

response = requests.post(
'https://api.thiqwave.com/api/v1/transactions',
headers=headers,
json=payload,
)

Environment variable naming convention

# .env (never commit this)
THIQWAVE_TEST_SECRET=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
THIQWAVE_LIVE_SECRET=<your-live-secret>

Idempotency

All money-moving endpoints require an Idempotency-Key header. This prevents duplicate charges if a request is retried:

curl -X POST https://api.thiqwave.com/api/v1/transactions \
-H "X-API-Key: <your-secret>" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ ... }'

Reusing the same Idempotency-Key within 24 hours returns the original response without creating a duplicate transaction.


API Key Security

Best Practices

  • Store secrets in environment variables, never in source code
  • Keep TEST and LIVE secrets in separate variables — never mix them
  • Rotate keys every 90 days in production
  • Use key expiry (expires_at) for CI/CD pipelines and short-lived integrations
  • Revoke a key immediately if you suspect it has been exposed
  • You can have multiple active keys per application, enabling zero-downtime rotation

Key Rotation (zero-downtime)

  1. Generate a new key for the application
  2. Update your application to use the new secret (deploy)
  3. Revoke the old key once traffic has drained
# Step 1: Generate new key
NEW_KEY=$(curl -s -X POST https://api.thiqwave.com/api/v1/applications/<app-id>/keys \
-H "Authorization: Bearer $TOKEN" \
-d '{}' | jq -r '.client_secret')

# Step 2: Deploy with new key, then...

# Step 3: Revoke old key
curl -X DELETE https://api.thiqwave.com/api/v1/applications/<app-id>/keys/<old-key-id> \
-H "Authorization: Bearer $TOKEN"

Rate Limits

API keys are subject to rate limits enforced at the Kong gateway:

LimitValue
Requests per minute100
Requests per hour5,000

Enterprise plans have custom limits. Contact support to adjust.


Error Codes

StatusCodeDescription
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENKey is valid but lacks permission for this action
403FORBIDDENApplication is deactivated
409CONFLICTAPI key already revoked
429RATE_LIMITEDToo many requests

Next Steps