MarzbanSDK
Utilities

Template Variables

Work with Marzban host-settings template variables — extract, validate, and interpolate.

Marzban allows using template variables (like {USERNAME}, {DATA_LEFT}) in host-settings remark and address fields. The SDK provides typed utilities to work with these variables safely.

Import

import {
  Variable,
  VariableBraced,
  varAs,
  varExtract,
  varValidate,
  interpolateTemplateVariables,
} from 'marzban-sdk'

Variable enum

All supported variable names:

ConstantTokenDescription
Variable.SERVER_IP{SERVER_IP}Master server IPv4 address
Variable.USERNAME{USERNAME}User's username
Variable.DATA_USAGE{DATA_USAGE}Data consumed by the user
Variable.DATA_LEFT{DATA_LEFT}Remaining data
Variable.DATA_LIMIT{DATA_LIMIT}Total data limit
Variable.DAYS_LEFT{DAYS_LEFT}Remaining days (integer)
Variable.TIME_LEFT{TIME_LEFT}Human-friendly remaining time
Variable.EXPIRE_DATE{EXPIRE_DATE}Expiry in Gregorian calendar
Variable.JALALI_EXPIRE_DATE{JALALI_EXPIRE_DATE}Expiry in Jalali calendar
Variable.STATUS_EMOJI{STATUS_EMOJI}Status as emoji (✅ ⌛️ 🪫 ❌ 🔌)
Variable.PROTOCOL{PROTOCOL}Protocol name (vless, vmess, …)
Variable.TRANSPORT{TRANSPORT}Transport type (tcp, ws, grpc, …)

varAs(variable)

Convert a Variable enum member to its braced string token. The return type is a precise literal, e.g. "{USERNAME}" — not plain string.

varAs(Variable.USERNAME)   // "{USERNAME}"
varAs(Variable.DATA_LEFT)  // "{DATA_LEFT}"

VariableBraced

A frozen map of all pre-braced tokens, keyed by variable name. Useful for building template strings with autocomplete:

const remark = `User: ${VariableBraced.USERNAME} | Left: ${VariableBraced.DATA_LEFT}`
// "User: {USERNAME} | Left: {DATA_LEFT}"

varExtract(template)

Extract all variable names from a template string (without braces, preserving order and duplicates):

varExtract('Hello {USERNAME}, you have {DATA_LEFT} left')
// ["USERNAME", "DATA_LEFT"]

varExtract('{USERNAME} - {USERNAME}')
// ["USERNAME", "USERNAME"]  (duplicates preserved)

varExtract('')         // []
varExtract('no vars')  // []

varValidate(template)

Validate that a template contains only known Marzban variables:

const result = varValidate('Hi {USERNAME}, ip: {SERVER_IP}')
// { isValid: true, unknownVariables: [] }

const bad = varValidate('Hi {USERNAME} and {UNKNOWN_VAR}')
// { isValid: false, unknownVariables: ["UNKNOWN_VAR"] }

interpolateTemplateVariables(template, values)

Substitute variable tokens with actual values. Unknown or unmapped tokens are left intact:

import { interpolateTemplateVariables, Variable } from 'marzban-sdk'

const remark = 'Hello {USERNAME}, {DATA_LEFT} remaining until {EXPIRE_DATE}'

const filled = interpolateTemplateVariables(remark, {
  [Variable.USERNAME]: 'alice',
  [Variable.DATA_LEFT]: '4.50 GB',
  [Variable.EXPIRE_DATE]: '2024-02-15',
})

// "Hello alice, 4.50 GB remaining until 2024-02-15"

Tokens not present in values are left as-is:

interpolateTemplateVariables('{USERNAME} — {STATUS_EMOJI}', {
  [Variable.USERNAME]: 'alice',
  // STATUS_EMOJI not provided
})
// "alice — {STATUS_EMOJI}"

Common usage patterns

Build a host remark template

import { VariableBraced } from 'marzban-sdk'

const remark = `${VariableBraced.USERNAME} | ${VariableBraced.DATA_LEFT} | ${VariableBraced.TIME_LEFT}`
// "{USERNAME} | {DATA_LEFT} | {TIME_LEFT}"

// Pass to Marzban host settings
await sdk.system.modifyHosts({
  'VLESS TCP REALITY': [{
    remark,
    address: '203.0.113.10',
    port: 443,
  }],
})

Validate a user-submitted template

function validateHostRemark(remark: string) {
  const { isValid, unknownVariables } = varValidate(remark)
  if (!isValid) {
    throw new Error(`Unknown template variables: ${unknownVariables.join(', ')}`)
  }
}

validateHostRemark('{USERNAME} - {DATA_LIMIT}') // OK
validateHostRemark('{USERNAME} - {TYPO}')        // throws

On this page