Skip to main content

Authentication

Thiqwave uses two authentication mechanisms depending on the caller:

CallerMechanismUsed for
Partner dashboard / adminBearer token (JWT)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 dashboard token​

Sign in to the Thiqwave Dashboard to manage applications and keys interactively. To script the same steps, exchange your dashboard credentials at the OAuth2 token endpoint for your environment:

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

THIQWAVE_AUTH_URL is issued with your onboarding pack. The resulting bearer token is used only for application and key management — never for payment calls, which use X-API-Key.

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"
}

:::danger 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 API gateway:

LimitValue
Requests per minute100
Requests per hour5,000

Enterprise plans have custom limits. Contact support to adjust.


Error Codes​

Authentication failures use the standard error envelope:

StatusCodeDescription
401ATH_0001Missing or invalid API key
403ATH_0002Key is valid but lacks permission for this action
403ATH_0002Application is deactivated

Revoked-key conflicts (409) and rate limiting (429) return the same envelope. See Errors for the full code list and Idempotency & Rate Limits for throttling behaviour.


Next Steps​