Salami Gateway

API Documentation
Back to Dashboard

API Token Management

Manage the lifecycle of API tokens used to authenticate with the Salami Gateway API. Create tokens with specific scopes, monitor usage, set expiration dates, and revoke compromised tokens.

Table of Contents

  1. Overview
  2. Create Token
  3. List Tokens
  4. Test Token
  5. Revoke Token
  6. Token Abilities & Scopes
  7. Token Lifecycle
  8. Status Codes

Overview

Salami uses Laravel Sanctum for API token authentication. Tokens are personal access tokens tied to a user account and can be scoped to specific API modules.

Endpoint Summary

Method Endpoint Description
POST /api/account/tokens Create a new API token
GET /api/account/tokens List all tokens
POST /api/account/tokens/test Test token validity
DELETE /api/account/tokens/{id} Revoke a token

Authentication

Token management endpoints require authentication via an existing valid token or session authentication.


Create Token

Generate a new API token with specified abilities (scopes).

Endpoint: POST /api/account/tokens

Request Body:

Field Type Required Description
name string Yes Descriptive token name
abilities array Yes Array of scope strings
expires_at string No Expiration date (YYYY-MM-DD), null for no expiration

Request:

curl -X POST \
  https://yourtenant.salami.dgl.co.ke/api/account/tokens \
  -H 'Authorization: Bearer EXISTING_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Production Server",
    "abilities": ["payments:read", "payments:write", "sms:write"],
    "expires_at": "2026-12-31"
  }'

Response:

{
  "success": true,
  "data": {
    "token_id": 15,
    "name": "Production Server",
    "plain_text_token": "3|laravel_sanctum_abc123def456ghi789jkl012mno345pqr678stu901vwx",
    "abilities": ["payments:read", "payments:write", "sms:write"],
    "expires_at": "2026-12-31T23:59:59Z",
    "created_at": "2026-03-29T18:00:00Z"
  },
  "message": "Token created successfully. Copy the token now - it will not be shown again."
}

Critical: The plain_text_token is returned only once at creation time. Store it securely. If lost, revoke the token and create a new one.

Creating a Full Access Token

{
  "name": "Admin Full Access",
  "abilities": ["*"]
}

Creating a Read-Only Token

{
  "name": "Reporting Dashboard",
  "abilities": ["payments:read", "sms:read", "etims:read", "kra:apps", "kra:checkers"]
}

Creating a KRA-Only Token

{
  "name": "KRA Integration Server",
  "abilities": [
    "kra:apps", "kra:checkers", "kra:payments",
    "kra:compliance", "kra:registration", "kra:returns"
  ]
}

List Tokens

Retrieve all tokens for the authenticated user.

Endpoint: GET /api/account/tokens

Request:

curl -X GET \
  https://yourtenant.salami.dgl.co.ke/api/account/tokens \
  -H 'Authorization: Bearer YOUR_API_TOKEN'

Response:

{
  "success": true,
  "data": [
    {
      "id": 15,
      "name": "Production Server",
      "abilities": ["payments:read", "payments:write", "sms:write"],
      "last_used_at": "2026-03-29T17:45:00Z",
      "usage_count": 1247,
      "expires_at": "2026-12-31T23:59:59Z",
      "revoked_at": null,
      "status": "active",
      "created_at": "2026-03-29T18:00:00Z"
    },
    {
      "id": 12,
      "name": "Mobile App",
      "abilities": ["payments:read", "sms:read"],
      "last_used_at": "2026-03-28T09:30:00Z",
      "usage_count": 456,
      "expires_at": null,
      "revoked_at": null,
      "status": "active",
      "created_at": "2026-03-15T10:00:00Z"
    },
    {
      "id": 8,
      "name": "Old Dev Token",
      "abilities": ["*"],
      "last_used_at": "2026-02-15T12:00:00Z",
      "usage_count": 89,
      "expires_at": "2026-03-01T00:00:00Z",
      "revoked_at": null,
      "status": "expired",
      "created_at": "2026-01-01T10:00:00Z"
    }
  ]
}

Token Status Values

Status Description
active Token is valid and can be used
expired Token has passed its expiration date
revoked Token has been manually revoked

Response Fields

Field Type Description
id integer Token ID
name string Descriptive name
abilities array Granted scopes
last_used_at string/null Last API request timestamp
usage_count integer Total number of API requests made
expires_at string/null Expiration timestamp (null = no expiry)
revoked_at string/null Revocation timestamp (null = not revoked)
status string active, expired, or revoked
created_at string Creation timestamp

Note: The actual token value is never returned in list responses for security.


Test Token

Verify that a token is valid and check its abilities.

Endpoint: POST /api/account/tokens/test

Request:

curl -X POST \
  https://yourtenant.salami.dgl.co.ke/api/account/tokens/test \
  -H 'Authorization: Bearer TOKEN_TO_TEST' \
  -H 'Accept: application/json'

Valid Token Response:

{
  "success": true,
  "data": {
    "valid": true,
    "token_id": 15,
    "name": "Production Server",
    "user": "admin@company.co.ke",
    "abilities": ["payments:read", "payments:write", "sms:write"],
    "expires_at": "2026-12-31T23:59:59Z",
    "usage_count": 1248,
    "last_used_at": "2026-03-29T18:05:00Z"
  },
  "message": "Token is valid"
}

Invalid/Expired Token Response:

{
  "success": false,
  "message": "Unauthenticated.",
  "error": "unauthenticated"
}

Revoke Token

Permanently invalidate a token. Revoked tokens cannot be restored.

Endpoint: DELETE /api/account/tokens/{id}

Path Parameters:

Parameter Type Required Description
id integer Yes Token ID to revoke

Request:

curl -X DELETE \
  https://yourtenant.salami.dgl.co.ke/api/account/tokens/15 \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Accept: application/json'

Response:

{
  "success": true,
  "data": {
    "token_id": 15,
    "name": "Production Server",
    "revoked_at": "2026-03-29T18:10:00Z"
  },
  "message": "Token revoked successfully"
}

Warning: Revocation is immediate and permanent. Any application using this token will immediately lose access.


Token Abilities & Scopes

Available Scopes

See Account Scopes for the complete scopes reference.

Summary:

Scope Module Description
* All Full access to all endpoints
payments:read Payments View transactions, balances
payments:write Payments Create transactions, send money
payments:callback Payments Handle provider callbacks
sms:read SMS View messages, inbox/outbox
sms:write SMS Send SMS messages
sms:sync SMS Sync from mobile apps
sms:receive SMS Receive incoming messages
etims:read eTIMS View sales, purchases, items
etims:write eTIMS Submit sales, manage items
etims:callback eTIMS Handle KRA callbacks
kra:apps KRA Manage KRA app configurations
kra:checkers KRA PIN validation, lookups
kra:payments KRA PRN generation
kra:compliance KRA TCC applications
kra:registration KRA PIN registration
kra:returns KRA Tax return filing

Full Access Token

A token with ["*"] abilities bypasses all scope checks and has access to every endpoint.

Scope Enforcement

Scopes are enforced by the CheckTokenScopes middleware. When a request arrives:

  1. The middleware extracts the token's abilities
  2. If * is present, access is granted
  3. Otherwise, it checks if any ability maps to the current route
  4. If no match, a 403 response is returned

Token Lifecycle

Created (plain text shown once)
    |
    v
Active (in use, usage_count incrementing)
    |
    +---> Expired (past expires_at date)
    |
    +---> Revoked (manually invalidated)

Recommended Practices

Practice Recommendation
Token naming Use descriptive names: "Production POS", "Staging Mobile App"
Expiration Set 90-day expiration for production tokens
Scope assignment Follow principle of least privilege
Rotation Create a new token before revoking the old one
Monitoring Review usage_count and last_used_at regularly
Incident response Revoke immediately if a token is compromised
Storage Use environment variables, never hardcode tokens

Status Codes

Code Description
200 Success
201 Token created successfully
401 Not authenticated
403 Insufficient permissions
404 Token not found
422 Validation error (missing name or abilities)

Related Documentation


Back to: Getting Started | Account Scopes


Need help? Contact us at support@dgl.co.ke
© 2026 Deadan Group Limited. All rights reserved.
⚡ API Explorer
LIVE
// Response will appear here...