# Toggle token metadata status

ADMIN/BUSINESS: Toggle token metadata active status. Business can only toggle their own metadata.

Endpoint: PUT /tokens/metadata/{metadataId}/status
Version: 2.0.53
Security: authJWT

## Path parameters:

  - `metadataId` (string, required)

## Response 200 fields (application/json):

  - `ownerBusinessId` (string)
    Optional owner business ID. If set, this token metadata belongs to a specific business. If null, the token metadata is tenant-owned (system-level).

  - `isActive` (boolean)
    Whether this template is active and can be used for minting

  - `imageUrl` (string)
    This is the URL to the image of the item. Can be just about any type of image (including SVGs, which will be cached into PNGs by OpenSea), IPFS or Arweave URLs or paths. We recommend using a minimum 3000 x 3000 image.

  - `externalUrl` (string)
    This is the URL that will appear below the asset's image

  - `description` (string)
    A human-readable description of the item. Markdown is supported.
**ERC721 Template Interpolation:** Supports `{{placeholder}}` syntax for dynamic personalization at mint time (without AI costs).
**Available placeholders:**
- `{{user.firstName}}`, `{{user.lastName}}` - User data
- `{{campaign.name}}`, `{{business.displayName}}` - Campaign/business
- `{{context.xxx}}` - Dynamic context values (TriggerSource.context or claim request)
- `{{defaults.xxx}}` - Default values from defaultPromptContext

**Example:** `"Thank you {{user.firstName}} for visiting {{business.displayName}}! Your exclusive reward for {{context.eventName}}."`
**Processing order:** Template interpolation runs first, then AI processing (if configured) can further enhance the result.

  - `name` (string)
    Name of the item.
**ERC721 Template Interpolation:** Supports `{{placeholder}}` syntax for dynamic personalization at mint time (without AI costs).
**Available placeholders:**
- `{{user.firstName}}`, `{{user.lastName}}` - User data
- `{{campaign.name}}`, `{{business.displayName}}` - Campaign/business
- `{{context.xxx}}` - Dynamic context values (TriggerSource.context or claim request)
- `{{defaults.xxx}}` - Default values from defaultPromptContext

**Example:** `"Welcome {{context.guestName}} - VIP Pass"` or `"{{user.firstName}}'s {{campaign.name}} Reward"`
**Processing order:** Template interpolation runs first, then AI processing (if configured) can further enhance the result.

  - `validityType` (string)
    **ERC721 only** - Validity type defines how token expiry is calculated. Use with validityDuration for relative types. Ignored for ERC1155 tokens.
    Enum: "fixed_date", "days_from_issuance", "hours_from_issuance", "months_from_issuance", "end_of_month", "end_of_year", "trigger_date", "trigger_date_range", "days_from_trigger", "hours_from_trigger"

  - `validityDuration` (number)
    **ERC721 only** - Duration in days or hours (used with days_from_issuance, hours_from_issuance validity types). Ignored for ERC1155 tokens.
    Example: 30

  - `expiryDate` (string)
    Fixed expiry date (used with fixed_date validity type). For other validity types, this is computed at issuance time.

  - `animationUrl` (string)
    A URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, and OGG are supported, along with the audio-only extensions MP3, WAV, and OGA. Animation_url also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvas, WebGL, and more. Scripts and relative paths within the HTML page are now supported. However, access to browser extensions is not supported.

  - `youtubeUrl` (string)
    A URL to a YouTube video (only used if animation_url is not provide

  - `creatorAccountAddress` (string)
    Creator Address

  - `previewUrl` (string)
    Preview Url

  - `tags` (array)
    Tags for categorization and filtering
    Example: ["summer","vip","limited-edition"]

  - `aiPromptConfigs` (array)
    **ERC721 only** - AI prompt configurations for dynamic content generation at mint time.
AI processing runs AFTER template interpolation, so prompts can reference already-interpolated values.
Results are mapped by key to override static fields (name, description, imageUrl). Ignored for ERC1155 tokens.
**Note:** For simple personalization without AI costs, use `{{placeholder}}` syntax directly in name/description fields instead.
    Example: [{"type":"TEXT_GENERATION","key":"name","prompt":"Generate a unique reward name for {{user.firstName}} at {{business.displayName}}"},{"type":"IMAGE_GENERATION","key":"imageUrl","prompt":"A {{defaults.…

  - `aiPromptConfigs.type` (string, required)
    Type of AI operation to perform
    Enum: "TEXT_GENERATION", "IMAGE_GENERATION"

  - `aiPromptConfigs.key` (string, required)
    Key to store the generated result under
    Example: name

  - `aiPromptConfigs.prompt` (string, required)
    The prompt to send to the AI model. Supports dynamic placeholders that are replaced with context values.
**Available Placeholders:**
- `{{user.firstName}}`, `{{user.lastName}}`, `{{user.email}}` - User profile data
- `{{campaign.name}}`, `{{campaign.description}}` - Campaign data
- `{{tenant.projectName}}`, `{{tenant.projectDescription}}` - Tenant/project data
- `{{business.displayName}}`, `{{business.name}}` - Business data
- `{{triggerSource.name}}`, `{{triggerSource.type}}` - Trigger source data
- `{{redemption.name}}`, `{{redemption.description}}` - Redemption data
- `{{context.xxx}}` - Dynamic context from TriggerSource.context or CampaignClaimRequest.context
- `{{defaults.xxx}}` - Default values from TokenMetadata.defaultPromptContext

**Context Sources:**
1. TriggerSource.context (admin QR/NFC) - Always applied
2. CampaignClaimRequest.context (user API) - Only if allowExternalContextOverwrite=true
3. TokenMetadata.defaultPromptContext - Always applied as fallback

**Examples:**
- `"Generate a welcome message for {{user.firstName}} at {{business.displayName}}"`
- `"Create a VIP badge for guest {{context.guestName}} in room {{context.roomNumber}}"`
- `"Design a {{defaults.style}} reward image for {{campaign.name}}"`
    Example: Generate a unique reward name for {{user.firstName}} visiting {{business.displayName}}

  - `allowExternalContextOverwrite` (boolean)
    **ERC721 only** - Allow USER-PROVIDED external context from claim/redeem requests to be used in template interpolation and AI prompts.
**Security model:**
- `false` (default): Only admin-controlled context (TriggerSource.context, Redemption.context, defaultPromptContext) is available
- `true`: User-provided context from API requests is also merged and available as `{{context.xxx}}`

**Note:** Admin-controlled context (QR/NFC data) is ALWAYS applied regardless of this flag.
    Example: true

  - `defaultPromptContext` (object)
    **ERC721 only** - Default context values for template interpolation and AI prompts. Available as `{{defaults.xxx}}` placeholders.
Always applied regardless of allowExternalContextOverwrite. Use for brand defaults, styling preferences, or fallback values.
**Example usage in name:** `"{{defaults.brand}} - {{user.firstName}}'s Reward"`
    Example: {"brand":"PERS Rewards","style":"minimal","defaultLocation":"Online"}

  - `businessIds` (array)
    Business IDs where this token can be redeemed/spent. Empty array means any business in the tenant.
    Example: ["business-uuid-1","business-uuid-2"]

  - `webhookId` (string)
    **ERC721 only** - Webhook ID for dynamic data fetch at mint time.
If set, the webhook is executed before metadata generation and response data is merged into the NFT.
**Use cases:**
- Fetch guest data from PMS/CRM systems
- Get real-time pricing or availability
- Retrieve user-specific content from external APIs

**Processing order:** Webhook fetch runs AFTER template interpolation but BEFORE AI processing.
    Example: webhook-uuid-for-pms-lookup

  - `webhookPayloadTemplate` (object)
    **ERC721 only** - Payload template for webhook request.
Supports `{{placeholder}}` interpolation with same context as AI prompts.
**Example:**

```json
{
  "userId": "{{user.id}}",
  "campaignId": "{{campaign.id}}",
  "bookingId": "{{context.bookingId}}"
}
```
    Example: {"userId":"{{user.id}}","bookingId":"{{context.bookingId}}"}

  - `webhookFieldMapping` (object)
    **ERC721 only** - Field mapping from webhook response to metadata fields.
Keys are webhook response paths (dot notation for nested), values are target field names.
**Mapping rules:**
- Explicit mapping: `"response.path": "targetField"`
- Known fields (name, description, imageUrl): auto-mapped if present
- Unknown fields or `"attributes"` target: become NFT attributes

**Example:**

```json
{
  "guestName": "name",
  "data.guest.image": "imageUrl",
  "roomNumber": "attributes",
  "checkInDate": "attributes"
}
```
If null/undefined, uses auto-mapping.
    Example: {"guestName":"name","roomNumber":"attributes","data.image":"imageUrl"}

  - `consumable` (boolean)
    Whether this token template is consumable (burned on redemption) or collectible (transferred). Applies to ERC1155 and ERC721 only — ERC20 is always transferred. When true, the token is destroyed (burn) when used as payment in a redemption. Defaults to true — most token templates are consumable. Set to false for collectible/non-burning use cases. Mirrored as a consumable attribute in the on-chain IPFS metadata.

  - `id` (string, required)
    Database UUID for this token metadata template

  - `animationWeb3StorageUrl` (string)
    IPFS/Arweave URL for animation file - immutable web3 storage

  - `imageWeb3StorageUrl` (string)
    IPFS/Arweave URL for image - immutable web3 storage

  - `web3StorageUrl` (string)
    IPFS/Arweave URL for complete metadata JSON - this URL is stored on-chain and links to off-chain metadata

  - `tokenMetadataIncrementalId` (number, required)
    Incremental ID within the token contract. For ERC1155: becomes the on-chain tokenId. For ERC721: lookup key for template to generate unique metadata.

  - `approval` (object, required)
    Approval metadata for this token metadata.

  - `approval.status` (string, required)
    Approval state: pending_approval = awaiting admin review, approved = active, rejected = denied.
    Enum: "pending_approval", "approved", "rejected"

  - `approval.approvedAt` (string)
    Timestamp when the entity was approved or rejected by an admin.

  - `approval.approvedBy` (string)
    Admin user ID who approved or rejected this entity.

  - `approval.rejectionReason` (string)
    Reason provided when the entity was rejected.

  - `mintCount` (number)
    Total number of mints for this token metadata (via ?include=mintCount). Counts SUCCEEDED MINT transactions using tokenMetadataIncrementalId. Accurate for both ERC1155 and ERC721 (post v2.3.49). Historical ERC721 transactions before v2.3.49 are not counted.

  - `burnCount` (number)
    Total number of burns for this token metadata (via ?include=burnCount). Counts SUCCEEDED BURN transactions using tokenMetadataIncrementalId. Accurate for both ERC1155 and ERC721 (post v2.3.49). Historical ERC721 transactions before v2.3.49 are not counted.

  - `included` (object)
    Included related entities. Only populated when include parameter is specified.

  - `included.ownerBusiness` (object)

  - `included.ownerBusiness.id` (string, required)
    The id of the business, this is unique and will be used to identify the business.

  - `included.ownerBusiness.email` (string, required)
    The email of the business, this is unique and will be used to identify the business.

  - `included.ownerBusiness.accountAddress` (string, required)
    The address of the business, this is the address that will be shown to the public.

  - `included.ownerBusiness.currentSigningAccountId` (string, required)
    Current active signing account ID for external wallet operations

  - `included.ownerBusiness.wallets` (array, required)
    Business-owned counterfactual smart contract wallets that can receive tokens

  - `included.ownerBusiness.wallets.id` (string, required)
    Unique identifier for the internal wallet

  - `included.ownerBusiness.wallets.ownerType` (string, required)
    Owner type for polymorphic ownership
    Enum: "user", "business", "tenant", "system", "external"

  - `included.ownerBusiness.wallets.ownerId` (string, required)
    Owner ID for polymorphic ownership
    Example: user_123

  - `included.ownerBusiness.wallets.walletManagementType` (string, required)
    Type of internal wallet
    Enum: "custodial", "non-custodial"

  - `included.ownerBusiness.wallets.address` (string, required)
    CREATE2 generated address that can receive tokens

  - `included.ownerBusiness.wallets.chainId` (number, required)
    Blockchain network chain identifier

  - `included.ownerBusiness.wallets.status` (string, required)
    Current status of the wallet
    Enum: "pending", "active", "suspended", "archived"

  - `included.ownerBusiness.wallets.ownerSigningAccountId` (string)
    ID of signing account that owns this internal wallet

  - `included.ownerBusiness.wallets.tags` (array, required)
    Tags associated with the wallet for categorization

  - `included.ownerBusiness.wallets.createdAt` (string, required)
    Timestamp when the wallet was created

  - `included.ownerBusiness.wallets.updatedAt` (string, required)
    Timestamp when the wallet was last updated

  - `included.ownerBusiness.businessLegalName` (string, required)
    The legal name of the business, this is the name that will be used for legal purposes.

  - `included.ownerBusiness.registrationNumber` (string, required)
    The business registration number (e.g., company registration, VAT number, EIN)

  - `included.ownerBusiness.displayName` (string, required)
    The display name of the business, this is the name that will be shown to the public.

  - `included.ownerBusiness.description` (string, required)
    The description of the business, this is the description that will be shown to the public.

  - `included.ownerBusiness.shortDescription` (string, required)
    The short description of the business, this is the description that will be shown to the public.

  - `included.ownerBusiness.websiteUrl` (string, required)
    The website of the business, this is the website that will be shown to the public.

  - `included.ownerBusiness.imageUrl` (string, required)
    The image of the business, this is the image that will be shown to the public.

  - `included.ownerBusiness.logoUrl` (string, required)
    Logo URL for the business

  - `included.ownerBusiness.streetAddress` (string, required)
    The address of the business, this is the address that will be shown to the public.

  - `included.ownerBusiness.phoneNumber` (string, required)
    The phone number of the business.

  - `included.ownerBusiness.neighborhood` (string, required)
    Neighborhood/area name (e.g., "West Bay", "Pearl Qatar", "Lusail") - auto-populated from geocoding

  - `included.ownerBusiness.district` (string, required)
    District/administrative area - auto-populated from geocoding

  - `included.ownerBusiness.city` (string, required)
    The city of the business, this is the city that will be shown to the public.

  - `included.ownerBusiness.postalCode` (string, required)
    The postal code of the business, this is the postal code that will be shown to the public.

  - `included.ownerBusiness.country` (string, required)
    The country of the business (auto-populated from geocoding if coordinates provided)

  - `included.ownerBusiness.countryCode` (string, required)
    ISO 3166-1 alpha-2 country code (e.g., QA, US, AE) - auto-populated from geocoding
    Example: QA

  - `included.ownerBusiness.coordsLatitude` (number, required)
    The latitude of the business, this is the latitude that will be shown to the public.

  - `included.ownerBusiness.coordsLongitude` (number, required)
    The longitude of the business, this is the longitude that will be shown to the public.

  - `included.ownerBusiness.businessType` (object, required)
    The business type of the business, this is the business type that will be shown to the public.

  - `included.ownerBusiness.businessType.id` (string)
    Business type id

  - `included.ownerBusiness.businessType.name` (string, required)
    Business type name

  - `included.ownerBusiness.businessType.description` (string, required)
    Business type description

  - `included.ownerBusiness.businessType.code` (string, required)
    Business type code

  - `included.ownerBusiness.businessType.iconUrl` (string, required)
    Business type icon url

  - `included.ownerBusiness.isActive` (boolean, required)
    The status of the business, this is the status that will be shown to the public.

  - `included.ownerBusiness.approval` (object, required)
    Approval metadata for this business.

  - `included.ownerBusiness.canMintToken` (boolean, required)
    The ability to mint token for the business, this is the ability that will be shown to the public.

  - `included.ownerBusiness.canChargeToken` (boolean, required)
    The ability to charge token for the business, this is the ability that will be shown to the public.

  - `included.ownerBusiness.canManageUsers` (boolean, required)
    The ability to manage users for the business, this is the ability that will be shown to the public.

  - `included.ownerBusiness.canReceiveDonation` (boolean, required)
    The ability to receive donation for the business, this is the ability that will be shown to the public.

  - `included.ownerBusiness.tags` (array, required)
    Tags for categorization and filtering

  - `included.ownerBusiness.customData` (object, required)
    Custom business data including Google Places information (placeID, currentOpeningHours)
    Example: {"placeID":"ChIJN1t_tDeuEmsRUsoyG83frY4","currentOpeningHours":{"open_now":true,"weekday_text":["Monday: 9:00 AM – 5:00 PM","Tuesday: 9:00 AM – 5:00 PM"]}}

  - `included.token` (object)
    Parent token contract info (via ?include=token)

  - `included.token.chainId` (number)
    Blockchain chain ID (mainnet or testnet)

  - `included.token.contractAddress` (string)
    Smart contract address

  - `included.token.type` (string)
    Token type (ERC721, ERC1155)

