Authentication
All protected endpoints require authentication. This page covers the authentication methods available.
Authentication Methods
| Method | Header(s) | Use Case |
|---|---|---|
| Bearer token | Authorization: Bearer ... | Admin and standard protected API routes |
| POS HMAC | X-API-Key-ID, X-Timestamp, X-Signature | POS terminal integrations |
| Partner HMAC | X-API-Key-ID, X-Partner-ID, X-Timestamp, X-Signature | Partner API routes |
| Service Auth | X-Service-Name, X-Service-Timestamp, X-Service-Signature | Internal services |
Bearer Authentication
Used by admin users and other bearer-protected routes.
Request Format
curl -X GET https://demo.api.vultlocal.com/api/v1/admin/users \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
API Key Prefixes
| Prefix | Environment |
|---|---|
olive_live_ | Production |
olive_test_ | Staging/Testing |
POS HMAC Authentication
POS routes under /api/v1/pos/* are protected by HMAC, not bearer tokens.
Mintlify's manual endpoint playground cannot generate these HMAC headers automatically, so POS pages use playground: "simple" and provide copy-paste cURL examples.
Request Format
BODY='{"card_serial":"OLIV0001","pin":"1234"}'
TIMESTAMP='2026-03-10T12:00:00Z'
SIGNATURE=$(printf 'POST\n/api/v1/pos/verify-card\n%s\n%s' "$TIMESTAMP" "$BODY" | openssl dgst -sha256 -hmac "$SMARTPAY_HMAC_SECRET" -hex | sed 's/^.* //')
curl -X POST https://demo.api.vultlocal.com/api/v1/pos/verify-card \
-H "X-API-Key-ID: $SMARTPAY_API_KEY_ID" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE" \
-H "Content-Type: application/json" \
-d "$BODY"
The signature string is exactly:
POST
/api/v1/pos/verify-card
2026-03-10T12:00:00Z
{"card_serial":"OLIV0001","pin":"1234"}
JWT Authentication
For admin operations and protected dashboard endpoints.
Obtaining a Token
curl -X POST https://demo.api.vultlocal.com/api/v1/admin/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@smartpay.example.com",
"password": "your-password"
}'
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
}
Using the Token
curl -X GET https://demo.api.vultlocal.com/api/v1/admin/users \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Error Responses
401 Unauthorized
Missing or invalid authentication:
{
"error": "Unauthorized",
"code": "UNAUTHORIZED",
"message": "Invalid or missing authentication token"
}
403 Forbidden
Authenticated but lacking permission:
{
"error": "Forbidden",
"code": "FORBIDDEN",
"message": "Insufficient permissions for this operation"
}
Service Authentication
Internal service routes use dedicated service headers, not X-Service-Auth.
Headers
X-Service-Name: wallet-core
X-Service-Timestamp: 1710072000
X-Service-Signature: <hex-hmac>
Signature Format
The canonical string is pipe-delimited:
METHOD|PATH|QUERY|TIMESTAMP
If there is no query string, keep the empty segment:
POST|/api/v1/compliance/alerts||1710072000
HMAC Routes In Docs
- Partner and POS pages use
playground: "simple"because their signatures must be computed from the exact raw request body. - Bearer-protected and public routes can keep the interactive playground.
Best Practices
Secure Storage
Store API keys securely; never expose in client-side code or version control.
Key Rotation
Rotate API keys periodically and immediately after any suspected compromise.
Minimum Scope
Request only the scopes needed for your integration.
HTTPS Only
Always use HTTPS in production to protect credentials in transit.