# PERS-api Documentation


**PERS API Documentation**

This RESTful API enables seamless integration of Web3 loyalty, token management, and engagement features into your applications.

**Usage Guidelines:**
- **RESTful Design**: Resources are accessed via standard HTTP methods (GET, POST, PUT, DELETE) with predictable, resource-oriented URLs.
- **Authentication**: Secure access is enforced via Bearer Tokens (JWT) and Project Keys (defining the Tenant context).
- **Data Format**: All requests and responses utilize standard JSON formatting.

Explore the modules below for detailed endpoint specifications, schemas, and testing capabilities.


---

### Error Handling

All API errors follow RFC 7807 (Problem Details for HTTP APIs) with a `StructuredError` schema. See the **Schemas** section below for the full structure.


Version: 2.0.53

## Servers

```
https://api.pers.ninja/v2
```

## Security

### authJWT

Authentication JWT token for user/business/admin/system access

Type: http
Scheme: bearer
Bearer Format: JWT

### projectKey

Project API key

Type: apiKey
In: header
Name: x-project-key

## Download OpenAPI description

 - [PERS-api Documentation](https://docs.pers.ninja/_bundle/swagger.yaml)

## Tenants

 - [Tenant Management](https://docs.pers.ninja/swagger/tenants/tenant-management.md): ## Tenant Management <div style="font-size: 14px; line-height: 1.5;"> Tenant management for multi-tenant PERS loyalty platform. Each tenant represents a business or organization running their own rewa
 - [POST /tenants](https://docs.pers.ninja/swagger/tenants/tenantscontroller_createtenant.md): Create a new tenant (project) in the system. This is the initial setup step for new organizations.
 - [PUT /tenants](https://docs.pers.ninja/swagger/tenants/tenantscontroller_updatetenant.md): ADMIN: Update tenant information and settings
 - [GET /tenants/client-config](https://docs.pers.ninja/swagger/tenants/tenantscontroller_getclientconfig.md): Retrieve client-side configuration for the project
 - [GET /tenants/login-token](https://docs.pers.ninja/swagger/tenants/tenantscontroller_getlogintoken.md): Generate a login token for the project
 - [GET /tenants/me](https://docs.pers.ninja/swagger/tenants/tenantscontroller_getcurrenttenant.md): Context-aware endpoint for retrieving your own tenant information. **REQUIREMENTS**: - Header: x-project-key (project identification) - Optional: Authorization Bearer token (for full access) **RETURNS
 - [GET /tenants/{id}](https://docs.pers.ninja/swagger/tenants/tenantscontroller_gettenantbyid.md): Context-aware tenant information retrieval: **UNAUTHENTICATED ACCESS**: - No headers required - Returns: Basic public tenant information
 - [POST /tenants/wallet](https://docs.pers.ninja/swagger/tenants/tenantscontroller_ensuretenantwallet.md): ADMIN: Generates a dedicated EOA for the tenant and stores it in AWS Secrets Manager if one does not already exist. Idempotent — safe to call multiple times.
## Admins

 - [Administrative Management](https://docs.pers.ninja/swagger/admins/administrative-management.md): ## Administrative Management <div style="font-size: 14px; line-height: 1.5;"> Administrative user management for tenant administrators. Handles admin authentication, permissions, and tenant-level admi
 - [GET /admins/me](https://docs.pers.ninja/swagger/admins/adminscontroller_getcurrentadmin.md): ADMIN: Retrieve the currently authenticated admin profile
 - [GET /admins](https://docs.pers.ninja/swagger/admins/adminscontroller_getadmins.md): ADMIN: Retrieve all admins associated with the current tenant. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be remo
 - [POST /admins](https://docs.pers.ninja/swagger/admins/adminscontroller_createorupdateadmin.md): ADMIN: Create a new admin or update an existing admin within the tenant scope
 - [PUT /admins/{adminId}/tenant](https://docs.pers.ninja/swagger/admins/adminscontroller_toggleadmintenantassociation.md): ADMIN: Associate or disassociate the specified admin with the current tenant. This affects admin tenant access.
## Tokens

 - [Token Management System](https://docs.pers.ninja/swagger/tokens/token-management-system.md): ## Token Management System <div style="font-size: 14px; line-height: 1.5;"> Token system for PERS loyalty platform managing various token types including Credits, Rewards, and Status tokens. Provides
 - [GET /tokens](https://docs.pers.ninja/swagger/tokens/tokenscontroller_getalltokens.md): Retrieve all token contracts for the project. Only admins can access inactive tokens via ?active=false parameter. Use pagination parameters (page & limit) for optimal performance. Legacy support: retu
 - [POST /tokens](https://docs.pers.ninja/swagger/tokens/tokenscontroller_createtoken.md): ADMIN: Create a new testnet token contract for the project. This can later be converted to mainnet.
 - [GET /tokens/address/{contractAddress}](https://docs.pers.ninja/swagger/tokens/tokenscontroller_gettokenbyaddress.md): Retrieve token information by contract address
 - [GET /tokens/points](https://docs.pers.ninja/swagger/tokens/tokenscontroller_getactivepointtoken.md): Retrieve the active point token contract for the project
 - [GET /tokens/rewards](https://docs.pers.ninja/swagger/tokens/tokenscontroller_getrewardtokens.md): Retrieve all reward token contracts (ERC1155 tokens). Only admins can access inactive tokens via ?active=false parameter. Use pagination parameters (page & limit) for optimal performance. Legacy suppo
 - [GET /tokens/stamps](https://docs.pers.ninja/swagger/tokens/tokenscontroller_getstamptokens.md): Retrieve all stamp token contracts (ERC721 tokens). Only admins can access inactive tokens via ?active=false parameter. Use pagination parameters (page & limit) for optimal performance. Legacy support
 - [GET /tokens/types](https://docs.pers.ninja/swagger/tokens/tokenscontroller_getalltokentypes.md): Retrieve all available token types for the project. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in futu
 - [POST /tokens/types](https://docs.pers.ninja/swagger/tokens/tokenscontroller_createtokentype.md): ADMIN: Create a new token type for the project
 - [GET /tokens/metadata](https://docs.pers.ninja/swagger/tokens/tokenscontroller_getalltokenmetadata.md): Retrieve all token metadata with filtering and pagination. Useful for displaying rewards/stamps in tables. Non-admin users always get active metadata only.
 - [GET /tokens/metadata/export/csv](https://docs.pers.ninja/swagger/tokens/tokenscontroller_exporttokenmetadataascsv.md): Export all token metadata to CSV format with optional date filtering.
 - [PUT /tokens/{id}](https://docs.pers.ninja/swagger/tokens/tokenscontroller_updatetoken.md): ADMIN: Update token contract information
 - [PUT /tokens/{id}/status](https://docs.pers.ninja/swagger/tokens/tokenscontroller_toggletokenstatus.md): ADMIN: Toggle token active status to enable/disable usage
 - [PUT /tokens/{id}/mainnet](https://docs.pers.ninja/swagger/tokens/tokenscontroller_setmainnetcontract.md): ADMIN: Associate mainnet contract address with existing testnet token
 - [POST /tokens/{id}/metadata](https://docs.pers.ninja/swagger/tokens/tokenscontroller_createtokenmetadata.md): ADMIN: Create metadata for a specific token contract
 - [PUT /tokens/metadata/{metadataId}](https://docs.pers.ninja/swagger/tokens/tokenscontroller_updatetokenmetadata.md): Update metadata for a specific token. Business can only update their own metadata. ERC721: only affects future mints. ERC1155: ⚠️ updates ALL existing minted tokens.
 - [DELETE /tokens/metadata/{metadataId}](https://docs.pers.ninja/swagger/tokens/tokenscontroller_deletetokenmetadata.md): Soft delete token metadata. Business can only delete their own metadata. Returns 409 Conflict if metadata is used by active campaigns or redemptions.
 - [PUT /tokens/metadata/{metadataId}/status](https://docs.pers.ninja/swagger/tokens/tokenscontroller_toggletokenmetadatastatus.md): ADMIN/BUSINESS: Toggle token metadata active status. Business can only toggle their own metadata.
 - [PATCH /tokens/metadata/{metadataId}/approval](https://docs.pers.ninja/swagger/tokens/tokenscontroller_approveorrejecttokenmetadata.md): Sets approval status to approved or rejected. Rejected requires a reason.
 - [POST /tokens/{contractAddress}/migrate-ownership](https://docs.pers.ninja/swagger/tokens/tokenscontroller_migratetokenownership.md): ADMIN: Transfers on-chain ownership of a legacy token proxy from the shared platform wallet to the tenant's dedicated EOA. Generates a fresh EOA and stores the secret in AWS Secrets Manager if the ten
 - [POST /tokens/migrate-ownership/all](https://docs.pers.ninja/swagger/tokens/tokenscontroller_migratealltokenownerships.md): ADMIN: Resolves every token proxy owned by the tenant on the given chain and transfers ownership to the tenant's dedicated EOA. Requires the tenant to already have a wallet (see POST /tenants/wallet).
## Campaigns

 - [Core Campaign Management](https://docs.pers.ninja/swagger/campaigns/core-campaign-management.md): ## Core Campaign Management <div style="font-size: 14px; line-height: 1.5;"> Core campaign CRUD operations with intelligent access detection. Handles campaign lifecycle management including creation,
 - [GET /campaigns](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_getcampaigns.md): Endpoint that adapts based on authentication: Public users get active campaigns with filtering, Business users get all campaigns (active+inactive) for their business only, Admin users get all campaign
 - [POST /campaigns](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_createcampaign.md): Create a new campaign. Admin-only operation. Replaces POST /campaign/admin/
 - [GET /campaigns/{id}](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_getcampaignbyid.md): Get single campaign details by ID. Available to public with project key. Replaces GET /campaign/{id}
 - [PUT /campaigns/{id}](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_updatecampaign.md): Update an existing campaign. Business can only update their own campaigns.
 - [DELETE /campaigns/{id}](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_deletecampaign.md): Delete an existing campaign. Business can only delete their own campaigns.
 - [PUT /campaigns/{id}/status](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_togglecampaignstatus.md): Toggle campaign active/inactive status. Business can only toggle their own campaigns.
 - [PUT /campaigns/{id}/environment](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_togglecampaignenvironment.md): Toggle campaign between testnet and mainnet environment. Accessible by tenant admin and business owner. Replaces PUT /campaign/admin/{id}/environment
 - [PUT /campaigns/{id}/trigger-sources/{triggerSourceId}](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_assigntriggersourcetocampaign.md): Assign a trigger source to a campaign. Businesses may only assign trigger sources they own to campaigns they own.
 - [DELETE /campaigns/{id}/trigger-sources/{triggerSourceId}](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_removetriggersourcefromcampaign.md): Remove a trigger source assignment from a campaign. Businesses may only modify campaigns they own.
 - [GET /campaigns/export/csv](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_exportcampaignsascsv.md): Export all campaigns to CSV format with optional date filtering.
 - [PATCH /campaigns/{id}/approval](https://docs.pers.ninja/swagger/campaigns/campaignscontroller_approveorrejectcampaign.md): Sets approval status to approved or rejected. Rejected requires a reason.
## Campaign Tags

 - [Campaign Organization System](https://docs.pers.ninja/swagger/campaign-tags/campaign-organization-system.md): ## Campaign Organization System <div style="font-size: 14px; line-height: 1.5;"> Campaign tagging system for organization and categorization. Enables efficient campaign discovery through tag-based fil
 - [GET /campaigns/{campaignId}/tags](https://docs.pers.ninja/swagger/campaign-tags/campaigntagscontroller_getalluniquetags.md): Get all unique tags used across all campaigns. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in future).
 - [PUT /campaigns/{campaignId}/tags](https://docs.pers.ninja/swagger/campaign-tags/campaigntagscontroller_updatecampaigntags.md): Replace all tags for a campaign with new tag list. Admin-only operation. Replaces PUT /campaign/admin/{id}/tags
 - [POST /campaigns/{campaignId}/tags](https://docs.pers.ninja/swagger/campaign-tags/campaigntagscontroller_addtagstocampaign.md): Add new tags to existing campaign tags without removing existing ones. Admin-only operation. Replaces POST /campaign/admin/{id}/tags
 - [DELETE /campaigns/{campaignId}/tags/{tag}](https://docs.pers.ninja/swagger/campaign-tags/campaigntagscontroller_removetagfromcampaign.md): Remove a specific tag from campaign while preserving other tags. Admin-only operation. Replaces DELETE /campaign/admin/{id}/tags/{tag}
## Campaign Tokens

 - [Campaign Reward Configuration](https://docs.pers.ninja/swagger/campaign-tokens/campaign-reward-configuration.md): ## Campaign Reward Configuration <div style="font-size: 14px; line-height: 1.5;"> Token unit management for campaign reward distribution. Defines specific token rewards that users receive when campaig
 - [POST /campaigns/{campaignId}/tokens](https://docs.pers.ninja/swagger/campaign-tokens/campaigntokenscontroller_createcampaigntokenunit.md): Add a new token unit to campaign for reward distribution. Admin or owning business.
 - [PUT /campaigns/{campaignId}/tokens/{tokenUnitId}](https://docs.pers.ninja/swagger/campaign-tokens/campaigntokenscontroller_updatecampaigntokenunit.md): Update an existing token unit in campaign. Admin or owning business.
 - [DELETE /campaigns/{campaignId}/tokens/{tokenUnitId}](https://docs.pers.ninja/swagger/campaign-tokens/campaigntokenscontroller_removecampaigntokenunit.md): Remove a token unit from campaign. Admin or owning business.
## Campaign Triggers

 - [Campaign Activation System](https://docs.pers.ninja/swagger/campaign-triggers/campaign-activation-system.md): ## Campaign Activation System <div style="font-size: 14px; line-height: 1.5;"> Campaign trigger system managing activation rules and eligibility conditions. Defines when and how campaigns activate inc
 - [GET /campaign-triggers](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_getalltriggers.md): Get all available triggers for campaign configuration. Public access for catalog browsing. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without param
 - [POST /campaign-triggers](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_createcampaigntrigger.md): Create a new campaign trigger for use in campaigns. Businesses create trigger rules owned by themselves; tenant admins can create shared (tenant-level) trigger rules. Replaces POST /campaign/admin/tri
 - [GET /campaign-triggers/{triggerId}](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_gettriggerbyid.md): Get a specific campaign trigger by ID. Useful for dashboard selection and preview.
 - [PUT /campaign-triggers/{triggerId}](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_updatecampaigntrigger.md): Update an existing campaign trigger. Businesses may only update trigger rules they own. Replaces PUT /campaign/admin/trigger/{id}
 - [DELETE /campaign-triggers/{triggerId}](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_deletecampaigntrigger.md): Delete an existing campaign trigger. Businesses may only delete trigger rules they own. Replaces DELETE /campaign/admin/trigger/{id}
 - [PUT /campaign-triggers/{triggerId}/assign/{campaignId}](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_assigntriggertocampaign.md): Assign a trigger rule to a campaign. Businesses may only assign trigger rules they own to campaigns they own. Replaces PUT /campaign/admin/{id}/trigger/{triggerId}
 - [DELETE /campaign-triggers/{triggerId}/assign/{campaignId}](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_removetriggerfromcampaign.md): Remove a trigger assignment from a campaign. Businesses may only modify campaigns they own.
 - [PUT /campaign-triggers/{triggerId}/conditions](https://docs.pers.ninja/swagger/campaign-triggers/campaigntriggerscontroller_toggleconditionintrigger.md): Add or remove a condition from a trigger rule. Businesses may only modify trigger rules they own. Replaces PUT /campaign/admin/trigger/{triggerId}/condition/{conditionId}
## Campaign Engagements

 - [Business Relationship Management](https://docs.pers.ninja/swagger/campaign-engagements/business-relationship-management.md): ## Business Relationship Management <div style="font-size: 14px; line-height: 1.5;"> B2B engagement management for multi-business campaign relationships. Handles business partnerships and enterprise-l
 - [POST /campaigns/{campaignId}/engagements](https://docs.pers.ninja/swagger/campaign-engagements/campaignengagementscontroller_createbusinessengagementforcampaign.md): Add a business engagement relationship to campaign for business-specific rewards. Admin-only operation. Replaces POST /campaign/admin/{id}/business-engagement
 - [PUT /campaigns/{campaignId}/engagements/{businessEngagementId}](https://docs.pers.ninja/swagger/campaign-engagements/campaignengagementscontroller_updatebusinessengagementincampaign.md): Update an existing business engagement relationship in campaign. Admin-only operation. Replaces PUT /campaign/admin/{id}/business-engagement/{businessEngagementId}
 - [DELETE /campaigns/{campaignId}/engagements/{businessEngagementId}](https://docs.pers.ninja/swagger/campaign-engagements/campaignengagementscontroller_removebusinessengagementfromcampaign.md): Remove a business engagement relationship from campaign. Admin-only operation. Replaces DELETE /campaign/admin/{id}/business-engagement/{businessEngagementId}
## Campaign Claims

 - [Reward Claims Processing](https://docs.pers.ninja/swagger/campaign-claims/reward-claims-processing.md): ## Reward Claims Processing <div style="font-size: 14px; line-height: 1.5;"> Multi-level reward claim processing with comprehensive security features and audit trails. Handles reward distribution with
 - [POST /campaigns/claims](https://docs.pers.ninja/swagger/campaign-claims/campaignclaimscontroller_createcampaignclaim.md): Process campaign reward claims using role-based detection. **Understanding Campaign Claim Flow:** 1. **WHO can claim (campaign.trigger.triggerType):** - `CLAIM_BY_USER`: End users initiate claims (s
 - [GET /campaigns/claims](https://docs.pers.ninja/swagger/campaign-claims/campaignclaimscontroller_getcampaignclaims.md): Get campaign claims with comprehensive filtering options. Use pagination parameters (page & limit) for optimal performance - critical for high-volume campaigns. Legacy support: returns array without p
 - [GET /campaigns/claims/me](https://docs.pers.ninja/swagger/campaign-claims/campaignclaimscontroller_getmycampaignclaims.md): Convenience endpoint for authenticated users to retrieve their own campaign claims. Equivalent to GET /campaign-claims but with required authentication and automatic filtering to current user context.
 - [GET /campaigns/claims/export/csv](https://docs.pers.ninja/swagger/campaign-claims/campaignclaimscontroller_exportclaimsascsv.md): Export all campaign claims to CSV format with optional filtering.
## Redemptions

 - [Token Exchange System](https://docs.pers.ninja/swagger/redemptions/token-exchange-system.md): ## Token Exchange System <div style="font-size: 14px; line-height: 1.5;"> Token exchange system facilitating conversion between different token types and redemption for rewards. Provides flexible rewa
 - [GET /redemptions/{id}](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_getredemptionbyid.md): Get specific redemption details by ID. Requires valid project API key. Include missingUserFields to check which required fields the authenticated user is missing.
 - [PUT /redemptions/{id}](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_updateredemption.md): Update existing redemption. Business can only update their own redemptions.
 - [DELETE /redemptions/{id}](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_deleteredemption.md): Permanently delete a redemption. Business can only delete their own redemptions.
 - [GET /redemptions/{id}/supply](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_getavailablesupply.md): Get the available supply count for a specific redemption. Used for inventory display.
 - [GET /redemptions](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_getredemptions.md): Intelligent endpoint that adapts based on authentication: Public users get active redemptions only, Admin users get all redemptions with optional filtering. Consolidates GET /redemption and GET /redem
 - [POST /redemptions](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_createredemption.md): Create a new redemption with administrative privileges. Replaces POST /redemption/admin
 - [PUT /redemptions/{id}/status](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_toggleredemptionstatus.md): Toggle redemption between active and inactive status. Business can only toggle their own redemptions.
 - [GET /redemptions/export/csv](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_exportredemptionscsv.md): Export all redemptions as a CSV file. Supports date filtering.
 - [PATCH /redemptions/{id}/approval](https://docs.pers.ninja/swagger/redemptions/redemptionscontroller_approveorrejectredemption.md): Sets approval status to approved or rejected. Rejected requires a reason.
## Purchases

 - [Payment Processing System](https://docs.pers.ninja/swagger/purchases/payment-processing-system.md): ## Payment Processing System <div style="font-size: 14px; line-height: 1.5;"> Secure payment processing for account balance top-ups through credit card payments. Provides secure financial transactions
 - [POST /purchases/webhooks/stripe](https://docs.pers.ninja/swagger/purchases/purchasescontroller_handlestripewebhook.md): Handles Stripe payment events for financial reconciliation. CRITICAL: Do not modify without extensive testing. Replaces POST /purchase/stripe-webhook
 - [GET /purchases/tokens](https://docs.pers.ninja/swagger/purchases/purchasescontroller_getpurchasetokens.md): Intelligent endpoint that adapts based on authentication. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed i
 - [POST /purchases/tokens](https://docs.pers.ninja/swagger/purchases/purchasescontroller_createpurchasetoken.md): Create a new purchase token for the product catalog. Admin-only operation. Replaces POST /purchase/admin/token
 - [GET /purchases/donation-types](https://docs.pers.ninja/swagger/purchases/purchasescontroller_getdonationtypes.md): Get all available donation types for public catalog browsing. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be remov
 - [POST /purchases/donation-types](https://docs.pers.ninja/swagger/purchases/purchasescontroller_createdonationtype.md): Create a new donation type for system configuration. Admin-only operation. Replaces POST /purchase/admin/donation/type
 - [POST /purchases/payment-intents](https://docs.pers.ninja/swagger/purchases/purchasescontroller_createpaymentintent.md): Create a new Stripe payment intent for purchase processing. Requires tenant context for Stripe API key. FINANCIAL OPERATION - handle with care. Replaces POST /purchase/payment-intent
 - [PUT /purchases/payment-intents/{paymentIntentId}](https://docs.pers.ninja/swagger/purchases/purchasescontroller_updatepaymentintent.md): Update an existing Stripe payment intent. Requires tenant context for Stripe API key. FINANCIAL OPERATION - handle with care. Replaces PUT /purchase/payment-intent/{paymentIntentId}
 - [DELETE /purchases/payment-intents/{paymentIntentId}](https://docs.pers.ninja/swagger/purchases/purchasescontroller_cancelpaymentintent.md): Cancel an existing Stripe payment intent. Requires tenant context for Stripe API key. FINANCIAL OPERATION - handle with care. Replaces DELETE /purchase/payment-intent/{paymentIntentId}
 - [POST /purchases](https://docs.pers.ninja/swagger/purchases/purchasescontroller_createuserpurchase.md): Create a new purchase for the authenticated user. BUSINESS CRITICAL - handles real financial transactions with Stripe integration. Requires user and tenant context. Replaces POST /purchase/auth
 - [GET /purchases/me](https://docs.pers.ninja/swagger/purchases/purchasescontroller_getuserpurchasehistory.md): Get all purchases made by the authenticated user. Use pagination parameters (page & limit) for optimal performance - recommended for users with many purchases. Legacy support: returns array without pa
 - [GET /purchases/export/csv](https://docs.pers.ninja/swagger/purchases/purchasescontroller_exporttocsv.md): Export all purchases as a CSV file. Supports date filtering.
 - [PUT /purchases/tokens/{id}](https://docs.pers.ninja/swagger/purchases/purchasescontroller_updatepurchasetoken.md): Update an existing purchase token in the product catalog. Admin-only operation. Replaces PUT /purchase/admin/token/{id}
 - [DELETE /purchases/tokens/{id}](https://docs.pers.ninja/swagger/purchases/purchasescontroller_deletepurchasetoken.md): Delete an existing purchase token from the product catalog. Admin-only operation. Replaces DELETE /purchase/admin/token/{id}
 - [POST /purchases/types](https://docs.pers.ninja/swagger/purchases/purchasescontroller_createpurchasetype.md): Create a new purchase type for system configuration. Admin-only operation. Replaces POST /purchase/admin/type
## Businesses

 - [Partner Ecosystem Management](https://docs.pers.ninja/swagger/businesses/partner-ecosystem-management.md): ## Partner Ecosystem Management <div style="font-size: 14px; line-height: 1.5;"> Business partner management for multi-stakeholder loyalty programs. Handles partner onboarding, collaboration framework
 - [GET /businesses/me](https://docs.pers.ninja/swagger/businesses/businessescontroller_getcurrentbusiness.md): Get business info with current token balances and virtual counterfactual wallet addresses for all active chains (business authentication required)
 - [GET /businesses](https://docs.pers.ninja/swagger/businesses/businessescontroller_getallbusinesses.md): Get all businesses. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in future). Project API key users get a
 - [POST /businesses](https://docs.pers.ninja/swagger/businesses/businessescontroller_createbusiness.md): Create a new business account, will be inactive until activated by admin
 - [GET /businesses/account/{accountAddress}](https://docs.pers.ninja/swagger/businesses/businessescontroller_getbyaccountaddress.md): Get business info by account address
 - [GET /businesses/{id}](https://docs.pers.ninja/swagger/businesses/businessescontroller_getbyid.md): Get business info by ID
 - [PUT /businesses/{id}](https://docs.pers.ninja/swagger/businesses/businessescontroller_updatebusiness.md): Update a business account. Business tokens may only update their own business.
 - [POST /businesses/bulk](https://docs.pers.ninja/swagger/businesses/businessescontroller_createbusinessesbulk.md): Create multiple business accounts from a JSON array in the request body.
 - [POST /businesses/bulk/url](https://docs.pers.ninja/swagger/businesses/businessescontroller_createbusinessesfromurl.md): Create multiple business accounts by fetching a JSON file from the provided URL. The file at the URL is expected to be a JSON object conforming to the BusinessBulkCreateRequestDTO structure, containin
 - [PUT /businesses/{id}/status](https://docs.pers.ninja/swagger/businesses/businessescontroller_togglebusinessstatus.md): Toggle business active status. Business owners can toggle isActive only; capability flags (canMintToken etc) require tenant admin.
 - [POST /businesses/stamp-tokens/{tokenId}/provision](https://docs.pers.ninja/swagger/businesses/businessescontroller_provisionstamptoken.md): ADMIN: Backfill stamp token metadata for a specific token across all existing businesses. Optional — metadata is otherwise provisioned lazily on first real usage. Use this to eagerly pre-provision ins
 - [GET /businesses/{businessId}/members](https://docs.pers.ninja/swagger/businesses/businessescontroller_getbusinessmembers.md): Get all members of a business. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in future). Requires BUSINES
 - [POST /businesses/{businessId}/members](https://docs.pers.ninja/swagger/businesses/businessescontroller_addbusinessmember.md): Add a user as a member of the business. Requires BUSINESS auth (min role: ADMIN) or TENANT admin.
 - [PUT /businesses/{businessId}/members/{userId}](https://docs.pers.ninja/swagger/businesses/businessescontroller_updatememberrole.md): Update the role of an existing business member. Requires BUSINESS auth (min role: ADMIN) or TENANT admin.
 - [DELETE /businesses/{businessId}/members/{userId}](https://docs.pers.ninja/swagger/businesses/businessescontroller_removebusinessmember.md): Remove a user from business membership. Requires BUSINESS auth (min role: ADMIN) or TENANT admin.
 - [GET /businesses/export/csv](https://docs.pers.ninja/swagger/businesses/businessescontroller_exportbusinessesascsv.md): Export all businesses to CSV format with optional date filtering.
 - [PATCH /businesses/{id}/approval](https://docs.pers.ninja/swagger/businesses/businessescontroller_approveorrejectbusiness.md): Sets approval status to approved or rejected. Rejected requires a reason.
## Transactions

 - [Transaction Management System](https://docs.pers.ninja/swagger/transactions/transaction-management-system.md): ## Transaction Management System <div style="font-size: 14px; line-height: 1.5;"> Comprehensive transaction management for credits and tokens with secure processing and real-time balance updates. Hand
 - [GET /transactions/me](https://docs.pers.ninja/swagger/transactions/transactionscontroller_getcurrentusertransactions.md): Consolidated endpoint for user/business transactions. Use role parameter to filter: SENDER (sent), RECIPIENT (received), or omit for all transactions. Use include parameter to enrich with full entity
 - [GET /transactions](https://docs.pers.ninja/swagger/transactions/transactionscontroller_getalltransactions.md): Get transactions with comprehensive filtering options: - include: Enrich with full entity data (sender, recipient, business) - search: Wildcard search for ID, address or transaction ha
 - [POST /transactions](https://docs.pers.ninja/swagger/transactions/transactionscontroller_createsystemtransaction.md): Create any type of transaction (MINT/TRANSFER/BURN) using role-based trigger detection. **Sender resolution — `sender` field is optional:** If `sender` is omitted, it defaults to the **authenticated c
 - [GET /transactions/{id}](https://docs.pers.ninja/swagger/transactions/transactionscontroller_gettransactionbyid.md): Get single transaction by ID with optional entity inclusion. Use include parameter to enrich with full entity data. Requires valid project API key.
 - [GET /transactions/{id}/prepare](https://docs.pers.ninja/swagger/transactions/transactionscontroller_preparetransactionbyid.md): Prepares transaction data for client-side execution from existing transaction ID. Returns the data needed for the client to sign and submit the transaction.
 - [POST /transactions/{id}/sign](https://docs.pers.ninja/swagger/transactions/transactionscontroller_signtransactiononly.md): Signs a custodial EIP-712 transaction and returns the signature without submitting to the blockchain. Use this for business interface flows where the signature is displayed/scanned and submitted separ
 - [POST /transactions/submit](https://docs.pers.ninja/swagger/transactions/transactionscontroller_submittransaction.md): Submits a signed transaction from the client. This method is used to finalize the transaction after the client has signed it.
 - [GET /transactions/export/csv](https://docs.pers.ninja/swagger/transactions/transactionscontroller_exporttransactionsascsv.md): Downloads transactions as CSV with business names resolved. Supports filtering by date range and status. Includes engagedBusinessName column for easy analysis. RLS ensures tenant isolation automatical
## Users

 - [User Account Management](https://docs.pers.ninja/swagger/users/user-account-management.md): ## User Account Management <div style="font-size: 14px; line-height: 1.5;"> User account management and profile operations for loyalty platform participants. Handles user registration, authentication,
 - [GET /users/me](https://docs.pers.ninja/swagger/users/userscontroller_getcurrentuser.md): Get authenticated user account info. Use include=status,balances to include related data. Note: Including status/balances adds latency - consider separate calls for performance-critical scenarios. Wal
 - [PUT /users/me](https://docs.pers.ninja/swagger/users/userscontroller_updatecurrentuser.md): Update authenticated user account
 - [GET /users/me/status](https://docs.pers.ninja/swagger/users/userscontroller_getcurrentuserstatus.md): Get authenticated user status types. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in future).
 - [GET /users/exists](https://docs.pers.ninja/swagger/users/userscontroller_checkuserexists.md): Check if a user exists using any identifier field (id, email, etc.)
 - [GET /users/public](https://docs.pers.ninja/swagger/users/userscontroller_getallpublicprofiles.md): Get all public user profiles. Use pagination parameters (page & limit) for optimal performance - essential for large user bases. Legacy support: returns array without params (deprecated - will be remo
 - [GET /users/public/{id}](https://docs.pers.ninja/swagger/users/userscontroller_getpublicprofile.md): Get a public profile by user ID
 - [GET /users/status-types](https://docs.pers.ninja/swagger/users/userscontroller_getalluserstatustypes.md): Get all available user status types. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in future).
 - [POST /users/status-types](https://docs.pers.ninja/swagger/users/userscontroller_createuserstatustype.md): Create user status type as admin
 - [GET /users/status-types/{id}](https://docs.pers.ninja/swagger/users/userscontroller_getuserstatustype.md): Get a user status type by ID
 - [PUT /users/status-types/{id}](https://docs.pers.ninja/swagger/users/userscontroller_updateuserstatustype.md): Update user status type as admin
 - [DELETE /users/status-types/{id}](https://docs.pers.ninja/swagger/users/userscontroller_deleteuserstatustype.md): Delete user status type as admin
 - [PUT /users/status-types/{id}/eligible-tokens/{tokenAddress}](https://docs.pers.ninja/swagger/users/userscontroller_updateuserstatustypeeligibletoken.md): Add or remove eligible token for user status type as admin
 - [POST /users/info](https://docs.pers.ninja/swagger/users/userscontroller_getuserinfo.md): Get user account info (business with user management permission OR admin authentication required). Identifier is passed in the request body (safe for PII such as email). Use include parameter for rela
 - [POST /users](https://docs.pers.ninja/swagger/users/userscontroller_createorupdateuser.md): Create or update user account(s). Supports single user (business/admin) or bulk operations (admin only)
 - [GET /users](https://docs.pers.ninja/swagger/users/userscontroller_getallusers.md): Get all users with role-based access. Use pagination parameters (page & limit) for optimal performance. With merge param, only checks duplicates for users on current page (smart merge). Project API ke
 - [GET /users/{identifier}](https://docs.pers.ninja/swagger/users/userscontroller_getuserbyidentifier.md): Get user by any unique identifier field (id, email, externalId, accountAddress, etc.). Business (with user management permission) or admin. ⚠️ The identifier travels in the URL - for PII such as email
 - [PUT /users/{identifier}](https://docs.pers.ninja/swagger/users/userscontroller_updateuserbyidentifier.md): Update user account by any unique identifier field (id, email, externalId, accountAddress, etc.). Admin only.
 - [DELETE /users/{identifier}](https://docs.pers.ninja/swagger/users/userscontroller_deleteuserbyidentifier.md): Soft delete user by any unique identifier field (id, email, externalId, accountAddress, etc.). Admin only. ⚠️ This operation is irreversible via API - consider using PUT /users/{identifier}/status for
 - [POST /users/bulk/url](https://docs.pers.ninja/swagger/users/userscontroller_createusersfromurl.md): Create user accounts from external URL as admin
 - [PUT /users/{identifier}/status](https://docs.pers.ninja/swagger/users/userscontroller_toggleuserstatusbyidentifier.md): Set or toggle user active status by any unique identifier field (id, email, externalId, accountAddress, etc.). If body contains { isActive: true/false }, sets explicitly. If no body, toggles. Admin on
 - [POST /users/{identifier}/restore](https://docs.pers.ninja/swagger/users/userscontroller_restoreuserbyidentifier.md): Restore a soft-deleted user within the 30-day grace period. After GDPR anonymization, restoration is not possible.
 - [GET /users/export/csv](https://docs.pers.ninja/swagger/users/userscontroller_exportusersascsv.md): Export all users to CSV format. Optional date filtering by createdAt.
 - [GET /users/me/balance](https://docs.pers.ninja/swagger/users/userscontroller_getcurrentuserbalance.md): Get authenticated user account with current token balances
 - [POST /users/balance](https://docs.pers.ninja/swagger/users/userscontroller_getuserbalance.md): DEPRECATED: Use POST /users/info?include=balances instead. Get user account with current token balances (business with user management permission OR admin authentication required).
## Balances

 - [Account Balance Management](https://docs.pers.ninja/swagger/balances/account-balance-management.md): ## Account Balance Management <div style="font-size: 14px; line-height: 1.5;"> Real-time balance tracking and management across all token types and user accounts. Provides comprehensive balance querie
 - [GET /balances/accounts/{accountAddress}](https://docs.pers.ninja/swagger/balances/balancescontroller_getaccountbalance.md): Get detailed balance information including token metadata for any account address. Requires tenant admin privileges. Replaces GET /balance/admin/account/{accountAddress}
 - [GET /balances/tokens/credit/holders](https://docs.pers.ninja/swagger/balances/balancescontroller_getactivecredittokenholders.md): Convenience endpoint: automatically resolves the tenant's active ERC20 credit token and returns paginated holders enriched with PERS wallet and optional user data.
 - [GET /balances/tokens/{contractAddress}/holders](https://docs.pers.ninja/swagger/balances/balancescontroller_gettokenholders.md): Returns all addresses holding the specified token, enriched with PERS ownerId and ownerType where the address is a tracked wallet. Uses Blockscout for on-chain data.
## Files

 - [File Management System](https://docs.pers.ninja/swagger/files/file-management-system.md): ## File Management System <div style="font-size: 14px; line-height: 1.5;"> File upload and management system for platform assets including campaign images, user avatars, and document attachments with
 - [POST /files/entity-storage-url](https://docs.pers.ninja/swagger/files/filescontroller_getentitystorageurl.md): Creates S3 signed URLs for uploading or downloading entity files. Supports both business and admin authentication flows.
## Web3 Chains

 - [Blockchain Network Management](https://docs.pers.ninja/swagger/web3-chains/blockchain-network-management.md): ## Blockchain Network Management <div style="font-size: 14px; line-height: 1.5;"> Blockchain network configuration and management for multi-chain token operations. Handles network connections, chain s
 - [GET /chains/{chainId}](https://docs.pers.ninja/swagger/web3-chains/web3chainscontroller_getchaindata.md): Retrieve comprehensive chain data including authentication JWT token valid for 30 days. Supports both mainnet and testnet chains.
## Contracts

 - [Smart Contract Management](https://docs.pers.ninja/swagger/contracts/smart-contract-management.md): ## Smart Contract Management <div style="font-size: 14px; line-height: 1.5;"> Smart contract deployment and interaction management for blockchain-based loyalty operations. Handles contract lifecycle a
 - [POST /contracts](https://docs.pers.ninja/swagger/contracts/web3contractscontroller_createcontract.md): Create a new Web3 contract with administrative privileges. Requires tenant admin access. Replaces POST /contract
## Auth

 - [Authentication & Authorization](https://docs.pers.ninja/swagger/auth/authentication-and-authorization.md): ## Authentication & Authorization <div style="font-size: 14px; line-height: 1.5;"> Comprehensive authentication and authorization system supporting multiple access levels including users, businesses,
 - [POST /auth/token](https://docs.pers.ninja/swagger/auth/authcontroller_createtoken.md): Universal token creation with consistent token-in-body pattern. ## Authentication Flows ### USER AUTHENTICATION - **Header**: `x-project-key` (tenant identification) - **Body**: `{ authToken: "jwt_fro
 - [POST /auth/refresh](https://docs.pers.ninja/swagger/auth/authcontroller_refresh.md): Refresh access tokens using valid refresh token
 - [POST /auth/verify](https://docs.pers.ninja/swagger/auth/authcontroller_verifytoken.md): Verify JWT tokens with automatic issuer detection: - Decodes JWT to extract issuer claim - PERS tokens: Verified internally - External tokens: Future support planned
 - [POST /auth/magic-link/send](https://docs.pers.ninja/swagger/auth/authcontroller_sendmagiclink.md): Send a magic link email for passwordless authentication. Rate limited to 3 requests per email per 10 minutes.
## Root

 - [Platform Infrastructure](https://docs.pers.ninja/swagger/root/platform-infrastructure.md): ## Platform Infrastructure <div style="font-size: 14px; line-height: 1.5;"> Core platform infrastructure endpoints including health checks, system status, and platform configuration. Provides essentia
 - [GET /](https://docs.pers.ninja/swagger/root/rootcontroller_get.md)
 - [GET /healthcheck](https://docs.pers.ninja/swagger/root/rootcontroller_getcurrenttime.md)
 - [GET /system](https://docs.pers.ninja/swagger/root/rootcontroller_getsystem.md): Check if tenant system api key is valid
 - [GET /admin](https://docs.pers.ninja/swagger/root/rootcontroller_getadmin.md): Get if admin
 - [GET /geolocation](https://docs.pers.ninja/swagger/root/rootcontroller_testgeo.md)
## Well-known

 - [Security Infrastructure](https://docs.pers.ninja/swagger/well-known/security-infrastructure.md): ## Security Infrastructure <div style="font-size: 14px; line-height: 1.5;"> JSON Web Key Set (JWKS) endpoints for JWT token verification. Provides public keys for secure authentication token validatio
 - [GET /jwks.json](https://docs.pers.ninja/swagger/well-known/jwkscontroller_getjwks.md)
 - [GET /openid-configuration](https://docs.pers.ninja/swagger/well-known/jwkscontroller_getopenidconfiguration.md)
## Webhooks

 - [Webhook Integration System](https://docs.pers.ninja/swagger/webhooks/webhook-integration-system.md): ## Webhook Integration System <div style="font-size: 14px; line-height: 1.5;"> Webhook proxy and integration system for external service notifications. Handles incoming webhook events and integrates w
 - [POST /hooks](https://docs.pers.ninja/swagger/webhooks/webhookcontroller_create.md)
 - [GET /hooks](https://docs.pers.ninja/swagger/webhooks/webhookcontroller_list.md)
 - [GET /hooks/executions](https://docs.pers.ninja/swagger/webhooks/webhookcontroller_getexecutions.md): Get webhook execution history with filtering options. Filters: - hookId: Filter by specific webhook (optional - omit for all webhooks) - status: Filter by execution status (success, failed, pending) -
 - [GET /hooks/{hookId}](https://docs.pers.ninja/swagger/webhooks/webhookcontroller_get.md)
 - [PUT /hooks/{hookId}](https://docs.pers.ninja/swagger/webhooks/webhookcontroller_update.md)
 - [DELETE /hooks/{hookId}](https://docs.pers.ninja/swagger/webhooks/webhookcontroller_delete.md)
## Trigger Sources

 - [POST /trigger-sources](https://docs.pers.ninja/swagger/trigger-sources/triggersourcescontroller_createtriggersource.md): Create a new trigger source (QR code, NFC tag, webhook, geofence, etc.). Businesses create trigger sources owned by themselves; tenant admins can create shared (tenant-level) trigger sources.
 - [GET /trigger-sources](https://docs.pers.ninja/swagger/trigger-sources/triggersourcescontroller_getalltriggersources.md): Retrieve all trigger sources with optional filtering and pagination. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will b
 - [GET /trigger-sources/{id}](https://docs.pers.ninja/swagger/trigger-sources/triggersourcescontroller_gettriggersource.md): Retrieve a specific trigger source with its configuration
 - [PUT /trigger-sources/{id}](https://docs.pers.ninja/swagger/trigger-sources/triggersourcescontroller_updatetriggersource.md): Update an existing trigger source configuration. Businesses may only update trigger sources they own.
 - [DELETE /trigger-sources/{id}](https://docs.pers.ninja/swagger/trigger-sources/triggersourcescontroller_deletetriggersource.md): Soft delete a trigger source. Businesses may only delete trigger sources they own.
## Business Types

 - [POST /businesses/types](https://docs.pers.ninja/swagger/business-types/businesstypescontroller_createbusinesstype.md): Create a new business type
 - [PUT /businesses/types](https://docs.pers.ninja/swagger/business-types/businesstypescontroller_updatebusinesstype.md): Update a business type
 - [GET /businesses/types](https://docs.pers.ninja/swagger/business-types/businesstypescontroller_getallbusinesstypes.md): Get all business types. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params (deprecated - will be removed in future).
 - [DELETE /businesses/types/{id}](https://docs.pers.ninja/swagger/business-types/businesstypescontroller_deletebusinesstype.md): Delete a business type
## Redemption Types

 - [GET /redemptions/types](https://docs.pers.ninja/swagger/redemption-types/redemptiontypescontroller_getredemptiontypes.md): Get all available redemption types for client reference. Requires valid project API key. Use pagination parameters (page & limit) for optimal performance. Legacy support: returns array without params
 - [POST /redemptions/types](https://docs.pers.ninja/swagger/redemption-types/redemptiontypescontroller_createredemptiontype.md): Create a new redemption type for system configuration. Replaces POST /redemption/admin/type
 - [PUT /redemptions/types/{id}](https://docs.pers.ninja/swagger/redemption-types/redemptiontypescontroller_updateredemptiontype.md): Update an existing redemption type configuration
 - [DELETE /redemptions/types/{id}](https://docs.pers.ninja/swagger/redemption-types/redemptiontypescontroller_deleteredemptiontype.md): Delete a redemption type. Will fail if any redemptions are using this type.
## Redemption Redeems

 - [POST /redemptions/redeems](https://docs.pers.ninja/swagger/redemption-redeems/redemptionredeemscontroller_executeredemption.md): Process redemption execution using role-based detection. Supports user, business, and admin redemption processing. **ERC721 Dynamic Context & Template Interpolation:** For ERC721 tokens, you can provi
 - [GET /redemptions/redeems](https://docs.pers.ninja/swagger/redemption-redeems/redemptionredeemscontroller_getredemptionredeems.md): Get redemption redeems with comprehensive filtering options: - redemptionId: Filter by specific redemption (optional) - userId: Filter by specific user ID (admin only) - businessId: Filter by specific
 - [GET /redemptions/redeems/me](https://docs.pers.ninja/swagger/redemption-redeems/redemptionredeemscontroller_getmyredemptionredeems.md): Convenience endpoint for authenticated users to retrieve their own redemption redeems. Equivalent to GET /redemption-redeems but with required authentication and automatic filtering to current user co
 - [GET /redemptions/redeems/{redeemId}](https://docs.pers.ninja/swagger/redemption-redeems/redemptionredeemscontroller_getredemptionredeembyid.md): Get current status of a specific redemption redeem with automatic access control based on authentication context. Optionally include related entities (redemption, user, business, transactions).
 - [GET /redemptions/redeems/export/csv](https://docs.pers.ninja/swagger/redemption-redeems/redemptionredeemscontroller_exportredeemscsv.md): Export all redeems as a CSV file. Supports date filtering and including related entities.
## Redemption Tokens

 - [POST /redemptions/{redemptionId}/tokens](https://docs.pers.ninja/swagger/redemption-tokens/redemptiontokenscontroller_addtokenunittoredemption.md): Add a new token unit to an existing redemption. Available to Admin and Business accounts.
 - [PUT /redemptions/{redemptionId}/tokens/{tokenUnitId}](https://docs.pers.ninja/swagger/redemption-tokens/redemptiontokenscontroller_updatetokenunit.md): Update an existing token unit within a redemption. Available to Admin and Business accounts.
 - [DELETE /redemptions/{redemptionId}/tokens/{tokenUnitId}](https://docs.pers.ninja/swagger/redemption-tokens/redemptiontokenscontroller_removetokenunit.md): Remove an existing token unit from a redemption. Available to Admin and Business accounts.
## API Keys

 - [GET /api-keys](https://docs.pers.ninja/swagger/api-keys/apikeyscontroller_gettenantapikeys.md): Admin: returns all integration keys for the tenant, optionally filtered by type. Business: returns only keys scoped to their own business entity. Use pagination parameters (page & limit) for optimal p
 - [POST /api-keys](https://docs.pers.ninja/swagger/api-keys/apikeyscontroller_createapikey.md): Create a new long-lived system JWT for app integration (M2M). Provide `businessId` to create a business-scoped token (BUSINESS_SYSTEM_JWT) for server-to-server integrations. Omit `businessId` to creat
 - [DELETE /api-keys/{id}](https://docs.pers.ninja/swagger/api-keys/apikeyscontroller_revokeapikey.md): Permanently revoke an API key. This operation cannot be undone. The key will be marked as revoked and will no longer be valid for authentication.
## Webhook Proxy

 - [POST /hooks/{projectKey}/executions/{executionId}/callback](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_processcallback.md): Receive workflow completion callback from external systems (e.g., n8n). URL format: /hooks/{projectKey}/executions/{executionId}/callback Security: - Project key identifies tenant (RLS enforces isolat
 - [GET /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_get.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [POST /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_post.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [PUT /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_put.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [DELETE /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_delete.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [PATCH /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_patch.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [OPTIONS /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_options.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [HEAD /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_head.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
 - [SEARCH /hooks/{projectKey}/{hookId}](https://docs.pers.ninja/swagger/webhook-proxy/webhookproxycontroller_receivewebhook_search.md): Project key in URL path identifies the tenant. Configure webhook URL as: /hooks/{projectKey}/{hookId}. Returns wrapped response with execution metadata.
## Event Subscriptions

 - [POST /events](https://docs.pers.ninja/swagger/event-subscriptions/eventsubscriptioncontroller_create.md)
 - [GET /events](https://docs.pers.ninja/swagger/event-subscriptions/eventsubscriptioncontroller_list.md)
 - [GET /events/{id}](https://docs.pers.ninja/swagger/event-subscriptions/eventsubscriptioncontroller_getbyid.md)
 - [PUT /events/{id}](https://docs.pers.ninja/swagger/event-subscriptions/eventsubscriptioncontroller_update.md)
 - [DELETE /events/{id}](https://docs.pers.ninja/swagger/event-subscriptions/eventsubscriptioncontroller_delete.md)
## Custom Field Definitions

 - [GET /custom-field-definitions](https://docs.pers.ninja/swagger/custom-field-definitions/customfielddefinitionscontroller_listdefinitions.md): Get all custom field definitions for the tenant. Filter by entityType to get fields for a specific entity.
 - [POST /custom-field-definitions](https://docs.pers.ninja/swagger/custom-field-definitions/customfielddefinitionscontroller_create.md): Create a new custom field for the tenant. Key must be unique within tenant+entityType.
 - [GET /custom-field-definitions/{id}](https://docs.pers.ninja/swagger/custom-field-definitions/customfielddefinitionscontroller_getbyid.md): Get a single custom field definition by ID.
 - [PUT /custom-field-definitions/{id}](https://docs.pers.ninja/swagger/custom-field-definitions/customfielddefinitionscontroller_update.md): Update field properties. Key and entityType cannot be changed.
 - [DELETE /custom-field-definitions/{id}](https://docs.pers.ninja/swagger/custom-field-definitions/customfielddefinitionscontroller_delete.md): Delete a field. Fails if field is referenced in any redemption baseRequiredUserFields/specificRequiredUserFields or campaign.
 - [GET /custom-field-definitions/{id}/usages](https://docs.pers.ninja/swagger/custom-field-definitions/customfielddefinitionscontroller_getusages.md): Check if a field is referenced in any redemption or campaign. Useful before deletion.
## Redirects

 - [POST /redirects](https://docs.pers.ninja/swagger/redirects/redirectcontroller_create.md)
 - [GET /redirects](https://docs.pers.ninja/swagger/redirects/redirectcontroller_findall.md)
 - [GET /redirects/go/{code}](https://docs.pers.ninja/swagger/redirects/redirectcontroller_redirect.md)
 - [GET /redirects/{id}/analytics](https://docs.pers.ninja/swagger/redirects/redirectcontroller_getanalytics.md)
 - [GET /redirects/{id}](https://docs.pers.ninja/swagger/redirects/redirectcontroller_findone.md)
 - [PATCH /redirects/{id}](https://docs.pers.ninja/swagger/redirects/redirectcontroller_update.md)
 - [DELETE /redirects/{id}](https://docs.pers.ninja/swagger/redirects/redirectcontroller_remove.md)
## Analytics

 - [POST /analytics/transactions](https://docs.pers.ninja/swagger/analytics/analyticscontroller_gettransactionanalytics.md): Returns aggregated transaction data with flexible grouping and metrics. Supports complex filtering by date range, business, token, status, and more. Requires admin authentication.
 - [POST /analytics/campaign-claims](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getcampaignclaimanalytics.md): Returns aggregated campaign claim data with flexible grouping and metrics. Business users are auto-filtered to their own campaigns (ownerBusinessId). Admin users see all data.
 - [POST /analytics/redemption-redeems](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getredemptionredeemanalytics.md): Returns aggregated redemption redeem data with flexible grouping and metrics. Business users are auto-filtered to their own redemptions (ownerBusinessId). Admin users see all data.
 - [POST /analytics/users](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getuseranalytics.md): Returns aggregated user statistics including total users, active users, new users, transaction metrics, campaign claims, redemptions, and engagement rate. Supports date range filtering. Requires admin
 - [POST /analytics/users/ranking](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getuserranking.md): Returns ranked list of users with full user details and transaction metrics. Data enrichment via efficient SQL JOINs + UNION (handles legacy transactions). Supports filtering by business, token type,
 - [POST /analytics/businesses/ranking](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getbusinessranking.md): Returns ranked list of businesses with full business details and transaction metrics. Data enrichment via efficient SQL JOINs + UNION (handles legacy transactions). Supports filtering by token type, d
 - [POST /analytics/users/retention](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getretentionanalytics.md): Returns cohort retention data showing how user cohorts perform over time. Each cohort represents users who joined in a specific month, tracked across subsequent months. Replaces 13 separate API calls
 - [GET /analytics/tags](https://docs.pers.ninja/swagger/analytics/analyticscontroller_gettaganalytics.md): Returns aggregated tag usage data across Campaign, Redemption, Business, TokenMetadata, and UserStatusType entities. Useful for tag filtering in apps and autocomplete suggestions.
 - [POST /analytics/ai/usage](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getaiusagesummary.md): Returns aggregated AI usage metrics with breakdown by model and operation type. Perfect for billing reports and cost monitoring. Requires admin authentication.
 - [POST /analytics/ai](https://docs.pers.ninja/swagger/analytics/analyticscontroller_getaianalytics.md): Returns aggregated AI generation data with flexible grouping and metrics. Supports filtering by model, operation type, user, and success status. Requires admin authentication.
 - [POST /analytics/nl-query](https://docs.pers.ninja/swagger/analytics/analyticscontroller_processnlquery.md): Converts a free-text question into structured analytics filters, classifies the domain, and returns results.
