> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.paymentkit.com/guides/integration/api-tokens/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paymentkit.com/_mcp/server. # Manage API tokens programmatically > Create, list, update, and revoke API tokens using the API instead of the dashboard. Automate key provisioning and rotation for your integrations. You can manage the same API tokens available under **Developers > API Tokens** in the dashboard through the `/api/{account_id}/api-tokens` endpoints: create, list, get, update, and delete. > **Note** > > Managing tokens requires the **Developer** permission. Listing and getting tokens need view access; creating, updating, and deleting tokens need edit access. # Token types Each API token bundles two credentials: | Credential | Prefix | Use | | --------------------- | ---------- | ------------------------------------------------------------------ | | **Secret token** | `st_prod_` | Server-side API calls. Sent as `Authorization: Bearer st_prod_...` | | **Publishable token** | `pt_prod_` | Client-side SDKs. Safe to expose in browser code | Both live and sandbox accounts use the `_prod_` prefix in production. The token record itself is identified by an id with the `tkn_` prefix (e.g., `tkn_prod_a1b2c3d4e5f6g7h8`). > **Warning** > > The full **secret token** is only returned once, in the response to the create request. Store it securely — it cannot be retrieved again. Subsequent responses only include `secret_token_preview` (the first 12 characters, e.g. `st_prod_secr...`) for identification. # Authentication All requests use your existing secret token: ```bash curl https://app.paymentkit.com/api/{account_id}/api-tokens \ -H "Authorization: Bearer st_prod_..." ``` Replace `{account_id}` with your account's external id (e.g., `acc_prod_...`). # Create a token Generate a new API token. The response includes the full `secret_token` — this is the only time it is returned, so store it securely. ```bash curl -X POST https://app.paymentkit.com/api/{account_id}/api-tokens \ -H "Authorization: Bearer st_prod_..." \ -H "Content-Type: application/json" \ -d '{ "description": "Production key for mobile app", "expires_at": "2025-12-31T23:59:59Z" }' ``` **Body parameters** (both optional): | Field | Type | Description | | ------------- | ------------------- | ----------------------------------------------------------- | | `description` | string | Human-readable label for the token | | `expires_at` | datetime (ISO 8601) | When the token should expire. Omit for a non-expiring token | **Response** (`ApiTokenWithSecret`): ```json { "id": "tkn_prod_a1b2c3d4e5f6g7h8", "description": "Production key for mobile app", "secret_token": "st_prod_secret123xyz", "secret_token_preview": "st_prod_secr...", "publishable_token": "pt_prod_abc123xyz", "is_active": true, "expires_at": "2025-12-31T23:59:59Z", "created_at": "2025-01-15T10:00:00Z", "updated_at": "2025-01-15T10:00:00Z" } ``` # List tokens Retrieve a paginated list of tokens for the account. The `secret_token` is never included — only `secret_token_preview`. ```bash curl "https://app.paymentkit.com/api/{account_id}/api-tokens?limit=20" \ -H "Authorization: Bearer st_prod_..." ``` **Query parameters:** | Parameter | Description | | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `limit` | Number of items per page (1–100, default 50) | | `offset` | Number of items to skip (default 0) | | `filter` | JSON-encoded filter object. Supported fields: `description`, `is_active`, `created_at`, `expires_at`. A `description` value also matches via text search | | `sortBy` | Field to sort by: `created_at`, `updated_at`, or `description` | | `sortOrder` | `1` for ascending, `-1` for descending (default) | The response is a paginated envelope: an `items` array of token objects, plus `total` (the total match count) and `has_more`. # Get a token Fetch a single token by its `id`. The response is the token object (without the secret token). ```bash curl https://app.paymentkit.com/api/{account_id}/api-tokens/tkn_prod_a1b2c3d4e5f6g7h8 \ -H "Authorization: Bearer st_prod_..." ``` A token that does not exist, or that belongs to another account, returns `404`. # Update a token Update a token's `description` or toggle its `is_active` status. Only the fields you include in the request body are changed; omitted fields keep their current values. The response is the updated token object (without the secret token). ```bash curl -X PATCH https://app.paymentkit.com/api/{account_id}/api-tokens/tkn_prod_a1b2c3d4e5f6g7h8 \ -H "Authorization: Bearer st_prod_..." \ -H "Content-Type: application/json" \ -d '{ "is_active": false }' ``` **Body parameters** (both optional): | Field | Type | Description | | ------------- | ------- | ---------------------------------------------------------- | | `description` | string | Updated label for the token | | `is_active` | boolean | Set to `false` to deactivate the token without deleting it | Deactivating a token (`is_active: false`) immediately stops it from authenticating requests — any call using its secret token is rejected with `401` — while keeping the token in your list for audit purposes. Set `is_active: true` to re-enable it. # Revoke a token Permanently delete a token. This is a hard delete and cannot be undone. ```bash curl -X DELETE https://app.paymentkit.com/api/{account_id}/api-tokens/tkn_prod_a1b2c3d4e5f6g7h8 \ -H "Authorization: Bearer st_prod_..." ``` **Response:** ```json { "message": "API token deleted successfully" } ``` > **Tip** > > To disable a token temporarily instead of deleting it, update it with `is_active: false`. You can re-enable it later by setting `is_active: true`. # Rotate a token There is no dedicated rotate endpoint. Rotate a credential by creating a replacement and then retiring the old one: 1. **Create** a new token and deploy its `secret_token` to your integration. 2. Verify the new token works in production. 3. **Deactivate** the old token by sending `PATCH` with `is_active: false` (reversible), or **delete** it (permanent). Deactivating first and deleting only after a grace period lets you roll back quickly if the new token was misconfigured. > **Note** > > Set an `expires_at` when creating a token to enforce a rotation schedule automatically. # Next steps #### [API authentication](/guides/integration) Review how API keys authenticate requests. #### [Explore the API](/api-reference) Browse the full API reference documentation.