A tenant is the top-level container for everything in Geldstuck - users, KYC records, transactions, source-of-funds documents, and webhooks. Every row of data in our system is stamped with a tenantId, and every API request is scoped to exactly one tenant via the key pair you send.

Mental model

Single-product apps

One tenant per environment (test + live). Your entire company’s data lives inside it.

Platforms / marketplaces

One tenant per merchant, broker, or sub-account. Each gets its own keys and webhooks.

White-label resellers

One tenant per reseller customer. Ideal for keeping data, branding, and keys fully isolated.

Isolation guarantees

  • Data: Queries are scoped to tenantId at the database layer. A key from tenant A can never read or mutate tenant B’s data.
  • Webhooks: Each tenant has its own webhook endpoints and signing secret. Events emitted for tenant A are never sent to tenant B’s URL.
  • Keys: Revoking a tenant’s key doesn’t affect other tenants. Rotating a webhook secret doesn’t affect other tenants.
  • Rate limits: Each tenant has its own quota. A noisy neighbor can’t starve other tenants.

Creating a tenant

Tenants can be created from the dashboard or via API (admin-only).
curl https://api.geldstuck.com/v1/tenants \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Escrow"}'
The response contains three secrets - shown once, never again:
{
  "tenantId": "tnt_01HX3Z8MQW...",
  "name": "Acme Escrow",
  "accessKey": "pk_live_51H...",
  "secretKey": "sk_live_51H...",
  "webhookSecret": "whsec_xS..."
}
Store secretKey and webhookSecret in a secrets manager immediately. If you lose them, you’ll need to regenerate - which invalidates the old ones.

Resolving the current tenant

Your backend doesn’t need to track tenantId - the key pair resolves it automatically. Every response includes it so your application can stamp logs and traces:
{
  "tenantId": "tnt_01HX3Z8MQW...",
  ...
}
If you manage multiple tenants (e.g., on a platform), store the tenantIdsecretKey mapping in your own database and load the right key before each outgoing call.

The x-tenant-id header (user-auth only)

When a request is authenticated with a user JWT instead of API keys - rare for integrators - the tenant is resolved from the user’s profile, or from the x-tenant-id header if the user has access to multiple tenants. You don’t need to set this for API-key requests.
TL;DR for integrators: use API keys, don’t set x-tenant-id, trust the tenantId in responses.