PremiumPlans: {
    addonMetadata: {
        addonId: string;
        availableOn: ("guild" | "user")[];
        isActive: boolean;
        isBoolean: boolean;
        name: string;
        priceCents: number;
        quantityStep?: number;
    }[];
    addons: {
        addonId: string;
        currency: string;
        isActive: boolean;
        name: string;
        priceCents: number;
        type: "guild" | "user";
    }[];
    capabilities?: (PremiumCapability | string & {})[];
    featureCategories: {
        description: string;
        name: string;
    }[];
    features: PremiumFeature[];
    tiers: PremiumPlanType[];
}

Type declaration

  • addonMetadata: {
        addonId: string;
        availableOn: ("guild" | "user")[];
        isActive: boolean;
        isBoolean: boolean;
        name: string;
        priceCents: number;
        quantityStep?: number;
    }[]
  • addons: {
        addonId: string;
        currency: string;
        isActive: boolean;
        name: string;
        priceCents: number;
        type: "guild" | "user";
    }[]
  • Optionalcapabilities?: (PremiumCapability | string & {})[]

    What the API build serving this response can do. Presence is the signal - there is no false.

    ── WHY THIS EXISTS ───────────────────────────────────────────────────── The dashboard used to gate its add-on Apply button on the presence of addonMetadata.availableOn, as a proxy for "does this deployment also have the fix that makes applying safe". The two shipped a day apart, so for that day the proxy said yes while the fix was absent - and Apply on a user subscription charged the customer immediately and delivered nothing.

    Each string is declared in the same commit as the behaviour it names, so it cannot drift from it: if the string is absent, the deployment predates the change. Never infer one capability from another; ask for the one you need.

    ── ABSENT ON OLD BUILDS ──────────────────────────────────────────────── The whole field is missing from any API that predates it, which is itself the "very old build" answer. Read it as plans.capabilities?.includes(...) ?? false.

  • featureCategories: {
        description: string;
        name: string;
    }[]

    Categories in the order the page should render them, each with a blurb.

  • features: PremiumFeature[]

    The comparison table, resolved server-side.

    Previously the page had to decode each tier's raw bitfield through this package's hand-copied GuildFeatures, so it could only ever render features this copy happened to list - 17 shipped bits were invisible that way, with nothing failing. These rows arrive already decoded: title, description, category, launch status and the per-tier value. No bitfield work needed.

    Filtered to released, visible rows unless the request passes all.

  • tiers: PremiumPlanType[]