Auth, Workspace, and Keys
This section covers the server-authenticated side of Hilt: account bootstrap, merchant workspace settings, OAuth, and API key management.
If you are integrating the buyer checkout itself, jump to Products and Checkout.
Authentication modes
Hilt supports two main auth patterns:
- Dashboard and browser sessions use a JWT:
Authorization: Bearer <jwt>
- Server-side merchant integrations use an API key:
X-Hilt-Key: hk_live_...
Use JWTs for merchant sign-in and app bootstrapping. Use API keys from your backend for operational calls once the merchant workspace is already set up.
OpenAPI and live schema discovery
The live API also exposes:
GET /v1/openapi.json
GET /v1/docs
GET /v1/redoc
Use those for live schema inspection. The docs below focus on the supported launch contract and practical examples.
Auth routes
Register
POST /v1/auth/register
Content-Type: application/json
{
"email": "merchant@example.com",
"password": "StrongPass123!",
"display_name": "Example Merchant"
}
Successful response:
{
"token": "JWT_TOKEN",
"user_id": "uuid",
"tier": "free",
"email": "merchant@example.com",
"claims": {
"hilt_score": false,
"hilt_pay": true,
"hilt_ops": false,
"is_staff": false
}
}
Common failures:
409if the email is already registered422if the payload is invalid
Login
POST /v1/auth/login
Content-Type: application/json
{
"email": "merchant@example.com",
"password": "StrongPass123!"
}
Successful response matches the register response shape.
Common failures:
401invalid email or password403account suspended or deleted
Wallet login
POST /v1/auth/wallet
Content-Type: application/json
{
"wallet_address": "BUYER_OR_MERCHANT_WALLET",
"signed_message": "BASE58_SIGNATURE",
"message_nonce": "ORIGINAL_NONCE"
}
This creates or resumes a wallet-backed merchant account on the free tier.
OAuth provider status
GET /v1/auth/oauth/providers
This returns whether Google and GitHub login are configured, along with their callback URLs and missing settings.
OAuth start
GET /v1/auth/oauth/google/start?mode=login&next=/dashboard
GET /v1/auth/oauth/github/start?mode=register&next=/dashboard
Successful response:
{
"provider": "google",
"callback_url": "https://app.hilt.so/api/auth/oauth/google/callback",
"authorization_url": "https://accounts.google.com/o/oauth2/v2/auth?..."
}
The callback route is browser-oriented and normally handled by the hosted app:
GET /v1/auth/oauth/{provider}/callback
Refresh and logout
POST /v1/auth/refresh
POST /v1/auth/logout
refresh reissues a JWT using the current account state, so plan or claim changes are reflected immediately.
Account bootstrap routes
These are the routes the merchant app uses to load and maintain the workspace.
Get the current workspace
GET /v1/account/me
Authorization: Bearer <jwt>
Representative response:
{
"user_id": "uuid",
"email": "merchant@example.com",
"wallet_address": null,
"display_name": "Example Merchant",
"tier": "growth",
"status": "active",
"email_verified": false,
"timezone": "UTC",
"created_at": "2026-04-14T12:00:00+00:00",
"key_id": null,
"sandbox": false,
"notification_prefs": {},
"merchant_settings": {
"checkout_brand_name": "Example Merchant",
"checkout_logo_url": "https://cdn.example.com/logo.png"
},
"claims": {
"hilt_score": false,
"hilt_pay": true,
"hilt_ops": false,
"is_staff": false
},
"has_password": true,
"auth_providers": ["google"]
}
Workspace summary
GET /v1/account/summary
Authorization: Bearer <jwt>
This returns the dashboard-level merchant snapshot:
- active templates
- paying members
- renewals due
- open support threads
- receipts issued
- total confirmed payments
- asset-by-asset gross, net, and fee totals
Update workspace settings
PATCH /v1/account/me
Authorization: Bearer <jwt>
Content-Type: application/json
{
"display_name": "Example Merchant",
"timezone": "Europe/London",
"merchant_settings": {
"checkout_brand_name": "Example Merchant",
"checkout_logo_url": "https://cdn.example.com/logo.png",
"checkout_hero_image_url": "https://cdn.example.com/hero.png",
"checkout_success_button_label": "Join now",
"checkout_accent_hex": "#1d4ed8",
"default_redirect_url": "https://example.com/welcome",
"default_support_url": "https://example.com/support"
}
}
Successful response:
{
"detail": "Profile updated",
"updated_fields": ["display_name", "timezone", "merchant_settings"]
}
Update email or password
PATCH /v1/account/me/security
Authorization: Bearer <jwt>
Content-Type: application/json
{
"email": "owner@example.com",
"current_password": "OldPassword123!",
"new_password": "NewPassword123!"
}
Common failures:
401current password incorrect409email already registered422new password too short or no changes submitted
Delivery readiness and tests
GET /v1/account/delivery/readiness
POST /v1/account/delivery/test
Use these to verify whether a merchant’s Telegram or Discord delivery settings are ready before publishing a template.
Example test request:
{
"provider": "telegram"
}
Delete account
DELETE /v1/account/account
Note:
- in practice this is mounted as
DELETE /v1/account/accountbecause the router is included with the/v1/accountprefix - it soft-deletes the account and revokes active keys
API key routes
List keys
GET /v1/keys
X-Hilt-Key: hk_live_... or Authorization: Bearer <jwt>
Response items include:
- key id
- key prefix
- permissions
- sandbox flag
- revoked state
- usage summary
- recent activity
Representative item:
{
"id": "uuid",
"name": "Production integration",
"key_prefix": "hk_live_",
"permissions": ["read", "execute"],
"sandbox_mode": false,
"last_used_at": "2026-04-14T11:45:00+00:00",
"created_at": "2026-04-10T09:30:00+00:00",
"revoked_at": null,
"usage_summary": {
"total_calls": 42,
"success_calls": 40,
"error_calls": 2,
"credits_burned": 0,
"latest_activity_at": "2026-04-14T11:45:00+00:00",
"latest_endpoint": "/v1/products"
},
"recent_activity": []
}
Create a key
POST /v1/keys
Authorization: Bearer <jwt>
Content-Type: application/json
{
"name": "Production integration",
"sandbox_mode": false,
"permissions": ["read", "execute"]
}
Successful response:
{
"key": {
"id": "uuid",
"name": "Production integration",
"key_prefix": "hk_live_",
"permissions": ["read", "execute"],
"sandbox_mode": false,
"last_used_at": null,
"created_at": "2026-04-14T12:00:00+00:00",
"revoked_at": null,
"usage_summary": {
"total_calls": 0,
"success_calls": 0,
"error_calls": 0,
"credits_burned": 0,
"latest_activity_at": null,
"latest_endpoint": null
},
"recent_activity": []
},
"raw_key": "hk_live_..."
}
The raw key is only shown once.
Common failures:
403if a non-staff user tries to create anadminkey422invalid permissions429plan key limit reached
Revoke a key
DELETE /v1/keys/{key_id}
Authorization: Bearer <jwt>
Successful response: 204 No Content
Recommended integration sequence
For a backend integration, the clean sequence is:
- merchant signs in through the app
- merchant creates an API key
- your backend stores the raw key securely
- your backend calls product, membership, receipt, and support routes using
X-Hilt-Key
Use JWTs for user-facing browser workflows. Use API keys for server automation.