API Keys
API key management endpoints for server-to-server integrations.
API Keys
API keys are long-lived tokens for server-to-server integrations. They support scoped permissions, IP allowlisting, expiry, and audit trails.
List API keys
curl -X GET https://totalaccess.co.za/api/v1/integrations/api-keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"success": true,
"data": [
{
"id": 42,
"key_name": "Production Integration",
"description": "Main production API key",
"display_name": null,
"avatar_url": null,
"key_type": "integration",
"environment": "production",
"is_active": true,
"permissions": {
"scopes": ["invoices:read", "invoices:write", "contacts:read"]
},
"allowed_ips": [],
"rate_limit_per_minute": null,
"last_used_at": "2026-07-22T14:30:00Z",
"expires_at": "2027-07-22T00:00:00Z",
"user_id": 15,
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-07-22T14:30:00Z",
"api_key_masked": "ta_sk_a1...wxyz",
"api_key_full": null
}
],
"available_scopes": {
"users:read": "Read user information",
"employees:read": "Read employee records and details",
...
},
"can_view_all_users": false
}The api_key_masked field shows the first 8 and last 4 characters. For testing environment keys, api_key_full contains the complete key. For production keys, api_key_full is null — use the reveal endpoint to see the full key.
Create API key
curl -X POST https://totalaccess.co.za/api/v1/integrations/api-keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key_name": "Production Integration",
"description": "Main production API key",
"environment": "production",
"permissions": {
"invoices:read": true,
"invoices:write": true,
"contacts:read": true
},
"allowed_ips": ["192.168.1.100", "10.0.0.0/24"],
"expires_in_days": 365,
"rate_limit_per_minute": 100
}'Response:
{
"success": true,
"data": {
"id": 43,
"key_name": "Production Integration",
"description": "Main production API key",
"display_name": null,
"avatar_url": null,
"key_type": "integration",
"environment": "production",
"permissions": {
"scopes": ["invoices:read", "invoices:write", "contacts:read"]
},
"allowed_ips": ["192.168.1.100", "10.0.0.0/24"],
"is_active": true,
"rate_limit_per_minute": 100,
"expires_at": "2027-07-22T15:00:00Z",
"created_at": "2026-07-22T15:00:00Z"
},
"api_key": "ta_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6..."
}The full api_key is only returned once at creation time. Store it securely — it cannot be retrieved later without a password-protected reveal.
Validation rules
- Key name: Must be unique per client (duplicate names return
400 Bad Request) - Scopes: Must be from the available scopes list. Provided as an object with scope names as keys and
trueas values (e.g.{ "invoices:read": true }) - IP allowlist: Supports individual IPs and CIDR notation (e.g.
10.0.0.0/24) - Expiry: Optional. Use
expires_in_daysto set the expiry duration. If omitted, key never expires - Environment:
productionortesting(default:production). Production keys require production API access to be enabled - Rate limit: Optional
rate_limit_per_minute— must not exceed your tier ceiling
Get API key details
curl -X GET https://totalaccess.co.za/api/v1/integrations/api-keys/42 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"success": true,
"data": {
"id": 42,
"key_name": "Production Integration",
"description": "Main production API key",
"display_name": null,
"avatar_url": null,
"key_type": "integration",
"permissions": {
"scopes": ["invoices:read", "invoices:write", "contacts:read"]
},
"allowed_ips": [],
"is_active": true,
"rate_limit_per_minute": null,
"last_used_at": "2026-07-22T14:30:00Z",
"expires_at": "2027-07-22T00:00:00Z",
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-07-22T14:30:00Z",
"api_key_masked": "ta_sk_a1...wxyz",
"usage_stats": {
"total_requests": 15420,
"requests_24h": 320,
"requests_7d": 2100
}
}
}Update API key
curl -X PATCH https://totalaccess.co.za/api/v1/integrations/api-keys/42 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key_name": "Renamed Integration",
"is_active": false,
"permissions": {
"invoices:read": true
},
"allowed_ips": ["192.168.1.100"],
"rate_limit_per_minute": 50,
"expires_at": "2027-12-31T00:00:00Z"
}'Updatable fields
| Field | Type | Description |
|---|---|---|
key_name | string | Display name (must be unique) |
description | string | null | Optional description |
display_name | string | null | Optional display name |
avatar_url | string | null | Optional avatar URL |
is_active | boolean | Activate or deactivate the key |
permissions | object | Object with scope names as keys and true values |
allowed_ips | string[] | IP allowlist (empty = all IPs) |
rate_limit_per_minute | number | null | Per-key rate limit (must not exceed tier ceiling) |
expires_at | string | null | ISO 8601 expiry date, or null for no expiry |
Reveal API key
Revealing an API key requires the user's account password and is logged to an audit trail.
curl -X POST https://totalaccess.co.za/api/v1/integrations/api-keys/42/reveal \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"password": "your_account_password"
}'Response:
{
"success": true,
"api_key": "ta_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6..."
}Delete (revoke) API key
curl -X DELETE https://totalaccess.co.za/api/v1/integrations/api-keys/42 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Deletion is a soft delete — the key is marked as inactive and can no longer be used for authentication, but the record is retained for audit purposes.
Available scopes
See the Authentication page for the complete scope catalog.
Finance document scopes are gated by subscription tier
The Finance Documents scope category includes scopes for all finance document types (invoices, quotes, credit notes, purchase orders, etc.). However, the scopes visible and selectable in the API Key Modal are filtered by the client's Total Finance subscription tier. Scopes for document types not included in the client's tier are hidden from the scope selection UI.
For example, if a client's tier does not include credit_note access, the credit_notes:read and credit_notes:write scopes will not appear when creating or editing an API key. This ensures that API keys cannot be granted permissions for finance document types that the client is not subscribed to.
See Finance Tier Restrictions for the list of gated document types.