diff --git a/packages/desktop-client/src/components/budget/report/components.tsx b/packages/desktop-client/src/components/budget/report/components.tsx
index 484d640136acb9b239350e5eee14e97affcc475e..78496230c138fbfb6f30f718d60c2e07d21ee156 100644
--- a/packages/desktop-client/src/components/budget/report/components.tsx
+++ b/packages/desktop-client/src/components/budget/report/components.tsx
@@ -1,11 +1,13 @@
-import React, { memo } from 'react';
+import React, { memo, useState } from 'react';
 
 import { reportBudget } from 'loot-core/src/client/queries';
 import evalArithmetic from 'loot-core/src/shared/arithmetic';
 import { integerToCurrency, amountToInteger } from 'loot-core/src/shared/util';
 
+import useFeatureFlag from '../../../hooks/useFeatureFlag';
+import CheveronDown from '../../../icons/v1/CheveronDown';
 import { styles, colors } from '../../../style';
-import { View, Text, Tooltip, Menu, useTooltip } from '../../common';
+import { Button, View, Text, Tooltip, Menu, useTooltip } from '../../common';
 import CellValue from '../../spreadsheet/CellValue';
 import format from '../../spreadsheet/format';
 import useSheetValue from '../../spreadsheet/useSheetValue';
@@ -195,56 +197,150 @@ export const CategoryMonth = memo(function CategoryMonth({
 }: CategoryMonthProps) {
   let borderColor = colors.border;
   let balanceTooltip = useTooltip();
+  const [menuOpen, setMenuOpen] = useState(false);
+  const [hover, setHover] = useState(false);
+  const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled');
 
   return (
-    <View style={{ flex: 1, flexDirection: 'row' }}>
-      <SheetCell
-        name="budget"
-        exposed={editing}
-        focused={editing}
-        width="flex"
-        borderColor={borderColor}
-        onExpose={() => onEdit(category.id, monthIndex)}
-        style={[editing && { zIndex: 100 }, styles.tnum]}
-        textAlign="right"
-        valueStyle={[
-          {
-            cursor: 'default',
-            margin: 1,
-            padding: '0 4px',
-            borderRadius: 4,
-          },
-          {
-            ':hover': {
-              boxShadow: 'inset 0 0 0 1px ' + colors.n7,
-              backgroundColor: 'white',
-            },
-          },
-        ]}
-        valueProps={{
-          binding: reportBudget.catBudgeted(category.id),
-          type: 'financial',
-          getValueStyle: makeAmountGrey,
-          formatExpr: expr => {
-            return integerToCurrency(expr);
-          },
-          unformatExpr: expr => {
-            return amountToInteger(evalArithmetic(expr, 0));
-          },
-        }}
-        inputProps={{
-          onBlur: () => {
-            onEdit(null);
-          },
+    <View
+      style={{
+        flex: 1,
+        flexDirection: 'row',
+        '& .hover-visible': {
+          opacity: 0,
+          transition: 'opacity .25s',
+        },
+        '&:hover .hover-visible': {
+          opacity: 1,
+        },
+      }}
+    >
+      <View
+        style={{
+          flex: 1,
+          flexDirection: 'row',
+          borderTopWidth: 1,
+          borderBottomWidth: 1,
+          borderColor,
+          backgroundColor: 'white',
         }}
-        onSave={amount => {
-          onBudgetAction(monthIndex, 'budget-amount', {
-            category: category.id,
-            amount,
-          });
+        onMouseOverCapture={() => setHover(true)}
+        onMouseLeave={() => {
+          setHover(false);
         }}
-      />
-
+      >
+        {!editing && (hover || menuOpen) && (
+          <View
+            style={{
+              flexShrink: 0,
+              marginRight: 0,
+              marginLeft: 3,
+              justifyContent: 'center',
+            }}
+          >
+            <Button
+              type="bare"
+              onClick={e => {
+                e.stopPropagation();
+                setMenuOpen(true);
+              }}
+              style={{
+                padding: 3,
+              }}
+            >
+              <CheveronDown
+                width={14}
+                height={14}
+                className="hover-visible"
+                style={menuOpen && { opacity: 1 }}
+              />
+            </Button>
+            {menuOpen && (
+              <Tooltip
+                position="bottom-left"
+                width={200}
+                style={{ padding: 0 }}
+                onClose={() => setMenuOpen(false)}
+              >
+                <Menu
+                  onMenuSelect={type => {
+                    onBudgetAction(monthIndex, type, { category: category.id });
+                    setMenuOpen(false);
+                  }}
+                  items={[
+                    {
+                      name: 'copy-single-last',
+                      text: 'Copy last month’s budget',
+                    },
+                    {
+                      name: 'set-single-3-avg',
+                      text: 'Set to 3 month average',
+                    },
+                    {
+                      name: 'set-single-6-avg',
+                      text: 'Set to 6 month average',
+                    },
+                    {
+                      name: 'set-single-12-avg',
+                      text: 'Set to yearly average',
+                    },
+                    isGoalTemplatesEnabled && {
+                      name: 'apply-single-category-template',
+                      text: 'Apply budget template',
+                    },
+                  ]}
+                />
+              </Tooltip>
+            )}
+          </View>
+        )}
+        <SheetCell
+          name="budget"
+          exposed={editing}
+          focused={editing}
+          width="flex"
+          borderColor="white"
+          onExpose={() => onEdit(category.id, monthIndex)}
+          style={[editing && { zIndex: 100 }, styles.tnum]}
+          textAlign="right"
+          valueStyle={[
+            {
+              cursor: 'default',
+              margin: 1,
+              padding: '0 4px',
+              borderRadius: 4,
+            },
+            {
+              ':hover': {
+                boxShadow: 'inset 0 0 0 1px ' + colors.n7,
+                backgroundColor: 'white',
+              },
+            },
+          ]}
+          valueProps={{
+            binding: reportBudget.catBudgeted(category.id),
+            type: 'financial',
+            getValueStyle: makeAmountGrey,
+            formatExpr: expr => {
+              return integerToCurrency(expr);
+            },
+            unformatExpr: expr => {
+              return amountToInteger(evalArithmetic(expr, 0));
+            },
+          }}
+          inputProps={{
+            onBlur: () => {
+              onEdit(null);
+            },
+          }}
+          onSave={amount => {
+            onBudgetAction(monthIndex, 'budget-amount', {
+              category: category.id,
+              amount,
+            });
+          }}
+        />
+      </View>
       <Field
         name="spent"
         width="flex"
diff --git a/packages/desktop-client/src/components/budget/rollover/rollover-components.tsx b/packages/desktop-client/src/components/budget/rollover/rollover-components.tsx
index 6b33a8a224e38da51a525e293f7db5d2543c5c1a..7f9c192f9a172f27eb7ad494b5506c2c6e3938b3 100644
--- a/packages/desktop-client/src/components/budget/rollover/rollover-components.tsx
+++ b/packages/desktop-client/src/components/budget/rollover/rollover-components.tsx
@@ -4,6 +4,8 @@ import { rolloverBudget } from 'loot-core/src/client/queries';
 import evalArithmetic from 'loot-core/src/shared/arithmetic';
 import { integerToCurrency, amountToInteger } from 'loot-core/src/shared/util';
 
+import useFeatureFlag from '../../../hooks/useFeatureFlag';
+import CheveronDown from '../../../icons/v1/CheveronDown';
 import { styles, colors } from '../../../style';
 import CategoryAutocomplete from '../../autocomplete/CategorySelect';
 import {
@@ -320,56 +322,150 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
 }: ExpenseCategoryMonthProps) {
   let borderColor = colors.border;
   let balanceTooltip = useTooltip();
+  const [menuOpen, setMenuOpen] = useState(false);
+  const [hover, setHover] = useState(false);
+  const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled');
 
   return (
-    <View style={{ flex: 1, flexDirection: 'row' }}>
-      <SheetCell
-        name="budget"
-        exposed={editing}
-        focused={editing}
-        width="flex"
-        borderColor={borderColor}
-        onExpose={() => onEdit(category.id, monthIndex)}
-        style={[editing && { zIndex: 100 }, styles.tnum]}
-        textAlign="right"
-        valueStyle={[
-          {
-            cursor: 'default',
-            margin: 1,
-            padding: '0 4px',
-            borderRadius: 4,
-          },
-          {
-            ':hover': {
-              boxShadow: 'inset 0 0 0 1px ' + colors.n7,
-              backgroundColor: 'white',
-            },
-          },
-        ]}
-        valueProps={{
-          binding: rolloverBudget.catBudgeted(category.id),
-          type: 'financial',
-          getValueStyle: makeAmountGrey,
-          formatExpr: expr => {
-            return integerToCurrency(expr);
-          },
-          unformatExpr: expr => {
-            return amountToInteger(evalArithmetic(expr, 0));
-          },
-        }}
-        inputProps={{
-          onBlur: () => {
-            onEdit(null);
-          },
+    <View
+      style={{
+        flex: 1,
+        flexDirection: 'row',
+        '& .hover-visible': {
+          opacity: 0,
+          transition: 'opacity .25s',
+        },
+        '&:hover .hover-visible': {
+          opacity: 1,
+        },
+      }}
+    >
+      <View
+        style={{
+          flex: 1,
+          flexDirection: 'row',
+          borderTopWidth: 1,
+          borderBottomWidth: 1,
+          borderColor,
+          backgroundColor: 'white',
         }}
-        onSave={amount => {
-          onBudgetAction(monthIndex, 'budget-amount', {
-            category: category.id,
-            amount,
-          });
+        onMouseOverCapture={() => setHover(true)}
+        onMouseLeave={() => {
+          setHover(false);
         }}
-      />
-
+      >
+        {!editing && (hover || menuOpen) ? (
+          <View
+            style={{
+              flexShrink: 1,
+              marginRight: 0,
+              marginLeft: 3,
+              justifyContent: 'center',
+            }}
+          >
+            <Button
+              type="bare"
+              onClick={e => {
+                e.stopPropagation();
+                setMenuOpen(true);
+              }}
+              style={{
+                padding: 3,
+              }}
+            >
+              <CheveronDown
+                width={14}
+                height={14}
+                className="hover-visible"
+                style={menuOpen && { opacity: 1 }}
+              />
+            </Button>
+            {menuOpen && (
+              <Tooltip
+                position="bottom-left"
+                width={200}
+                style={{ padding: 0 }}
+                onClose={() => setMenuOpen(false)}
+              >
+                <Menu
+                  onMenuSelect={type => {
+                    onBudgetAction(monthIndex, type, { category: category.id });
+                    setMenuOpen(false);
+                  }}
+                  items={[
+                    {
+                      name: 'copy-single-last',
+                      text: 'Copy last month’s budget',
+                    },
+                    {
+                      name: 'set-single-3-avg',
+                      text: 'Set to 3 month average',
+                    },
+                    {
+                      name: 'set-single-6-avg',
+                      text: 'Set to 6 month average',
+                    },
+                    {
+                      name: 'set-single-12-avg',
+                      text: 'Set to yearly average',
+                    },
+                    isGoalTemplatesEnabled && {
+                      name: 'apply-single-category-template',
+                      text: 'Apply budget template',
+                    },
+                  ]}
+                />
+              </Tooltip>
+            )}
+          </View>
+        ) : null}
+        <SheetCell
+          name="budget"
+          exposed={editing}
+          focused={editing}
+          width="flex"
+          borderColor="white"
+          onExpose={() => onEdit(category.id, monthIndex)}
+          style={[editing && { zIndex: 100 }, styles.tnum]}
+          textAlign="right"
+          valueStyle={[
+            {
+              cursor: 'default',
+              margin: 1,
+              padding: '0 4px',
+              borderRadius: 4,
+            },
+            {
+              ':hover': {
+                boxShadow: 'inset 0 0 0 1px ' + colors.n7,
+                backgroundColor: 'white',
+              },
+            },
+          ]}
+          valueProps={{
+            binding: rolloverBudget.catBudgeted(category.id),
+            type: 'financial',
+            getValueStyle: makeAmountGrey,
+            formatExpr: expr => {
+              return integerToCurrency(expr);
+            },
+            unformatExpr: expr => {
+              return amountToInteger(evalArithmetic(expr, 0));
+            },
+          }}
+          inputProps={{
+            onBlur: () => {
+              onEdit(null);
+            },
+          }}
+          onSave={amount => {
+            onBudgetAction(monthIndex, 'budget-amount', {
+              category: category.id,
+              amount,
+            });
+          }}
+        />
+      </View>
       <Field
         name="spent"
         width="flex"
@@ -391,7 +487,6 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
           />
         </span>
       </Field>
-
       <Field
         name="balance"
         width="flex"
diff --git a/packages/loot-core/src/client/actions/queries.ts b/packages/loot-core/src/client/actions/queries.ts
index 63524f60e25f5da1aa955ab7c35362ebf79e9886..1b9b18cc35d9fad51117614cba3d77eaf206c98d 100644
--- a/packages/loot-core/src/client/actions/queries.ts
+++ b/packages/loot-core/src/client/actions/queries.ts
@@ -30,16 +30,10 @@ export function applyBudgetAction(month, type, args) {
         dispatch(addNotification(await send('budget/check-templates')));
         break;
       case 'apply-goal-template':
-        dispatch(
-          addNotification(await send('budget/apply-goal-template', { month })),
-        );
+        await send('budget/apply-goal-template', { month });
         break;
       case 'overwrite-goal-template':
-        dispatch(
-          addNotification(
-            await send('budget/overwrite-goal-template', { month }),
-          ),
-        );
+        await send('budget/overwrite-goal-template', { month });
         break;
       case 'cleanup-goal-template':
         dispatch(
@@ -87,6 +81,39 @@ export function applyBudgetAction(month, type, args) {
         });
         break;
       }
+      case 'apply-single-category-template':
+        await send('budget/apply-single-template', {
+          month,
+          category: args.category,
+        });
+        break;
+      case 'set-single-3-avg':
+        await send('budget/set-n-month-avg', {
+          month,
+          N: 3,
+          category: args.category,
+        });
+        break;
+      case 'set-single-6-avg':
+        await send('budget/set-n-month-avg', {
+          month,
+          N: 6,
+          category: args.category,
+        });
+        break;
+      case 'set-single-12-avg':
+        await send('budget/set-n-month-avg', {
+          month,
+          N: 12,
+          category: args.category,
+        });
+        break;
+      case 'copy-single-last':
+        await send('budget/copy-single-month', {
+          month,
+          category: args.category,
+        });
+        break;
       default:
     }
   };
diff --git a/packages/loot-core/src/server/budget/actions.ts b/packages/loot-core/src/server/budget/actions.ts
index 23e68fee3aaead398c74effb45b073aac59a640f..0dd5a735b9419363d1bc65f199e0dceb8745c430 100644
--- a/packages/loot-core/src/server/budget/actions.ts
+++ b/packages/loot-core/src/server/budget/actions.ts
@@ -136,6 +136,17 @@ export async function copyPreviousMonth({ month }) {
   });
 }
 
+export async function copySinglePreviousMonth({ month, category }) {
+  let prevMonth = monthUtils.prevMonth(month);
+  let newAmount = await getSheetValue(
+    monthUtils.sheetForMonth(prevMonth),
+    'budget-' + category,
+  );
+  await batchMessages(async () => {
+    setBudget({ category: category, month, amount: newAmount });
+  });
+}
+
 export async function setZero({ month }) {
   let categories = await db.all(
     'SELECT * FROM v_categories WHERE tombstone = 0',
@@ -185,6 +196,22 @@ export async function set3MonthAvg({ month }) {
   });
 }
 
+export async function setNMonthAvg({ month, N, category }) {
+  let prevMonth = monthUtils.prevMonth(month);
+  let sumAmount = 0;
+  for (let l = 0; l < N; l++) {
+    sumAmount += await getSheetValue(
+      monthUtils.sheetForMonth(prevMonth),
+      'sum-amount-' + category,
+    );
+    prevMonth = monthUtils.prevMonth(prevMonth);
+  }
+  await batchMessages(async () => {
+    const avg = Math.round(sumAmount / N);
+    setBudget({ category: category, month, amount: -avg });
+  });
+}
+
 export async function holdForNextMonth({ month, amount }) {
   let row = await db.first(
     'SELECT buffered FROM zero_budget_months WHERE id = ?',
diff --git a/packages/loot-core/src/server/budget/app.ts b/packages/loot-core/src/server/budget/app.ts
index db683c5df9ab646da89e398098f38485610c2115..b9faad04a926c9c35bf65b9eef6c6bf24924d868 100644
--- a/packages/loot-core/src/server/budget/app.ts
+++ b/packages/loot-core/src/server/budget/app.ts
@@ -14,8 +14,13 @@ app.method(
   'budget/copy-previous-month',
   mutator(undoable(actions.copyPreviousMonth)),
 );
+app.method(
+  'budget/copy-single-month',
+  mutator(undoable(actions.copySinglePreviousMonth)),
+);
 app.method('budget/set-zero', mutator(undoable(actions.setZero)));
 app.method('budget/set-3month-avg', mutator(undoable(actions.set3MonthAvg)));
+app.method('budget/set-n-month-avg', mutator(undoable(actions.setNMonthAvg)));
 app.method(
   'budget/check-templates',
   mutator(undoable(goalActions.runCheckTemplates)),
@@ -28,6 +33,10 @@ app.method(
   'budget/overwrite-goal-template',
   mutator(undoable(goalActions.overwriteTemplate)),
 );
+app.method(
+  'budget/apply-single-template',
+  mutator(undoable(goalActions.applySingleCategoryTemplate)),
+);
 app.method(
   'budget/cleanup-goal-template',
   mutator(undoable(cleanupActions.cleanupTemplate)),
diff --git a/packages/loot-core/src/server/budget/goaltemplates.ts b/packages/loot-core/src/server/budget/goaltemplates.ts
index cdfe1b48c5a8b953b5c75681ac1ea234d8d16fec..7c3c033bfbeb1ebecef7ce606674cacd0e8c7265 100644
--- a/packages/loot-core/src/server/budget/goaltemplates.ts
+++ b/packages/loot-core/src/server/budget/goaltemplates.ts
@@ -7,16 +7,32 @@ import {
 import { amountToInteger, integerToAmount } from '../../shared/util';
 import * as db from '../db';
 import { getRuleForSchedule, getNextDate } from '../schedules/app';
+import { batchMessages } from '../sync';
 
 import { setBudget, setZero, getSheetValue, isReflectBudget } from './actions';
 import { parse } from './goal-template.pegjs';
 
-export function applyTemplate({ month }) {
-  return processTemplate(month, false);
+export async function applyTemplate({ month }) {
+  let category_templates = await getCategoryTemplates(null);
+  return processTemplate(month, false, category_templates);
 }
 
-export function overwriteTemplate({ month }) {
-  return processTemplate(month, true);
+export async function overwriteTemplate({ month }) {
+  let category_templates = await getCategoryTemplates(null);
+  return processTemplate(month, true, category_templates);
+}
+
+export async function applySingleCategoryTemplate({ month, category }) {
+  let categories = await db.all(`SELECT * FROM v_categories WHERE id = ?`, [
+    category,
+  ]);
+  let category_templates = await getCategoryTemplates(categories[0]);
+  await setBudget({
+    category: category,
+    month,
+    amount: 0,
+  });
+  return processTemplate(month, false, category_templates);
 }
 
 export function runCheckTemplates() {
@@ -35,13 +51,22 @@ function checkScheduleTemplates(template) {
   return { lowPriority, errorNotice };
 }
 
-async function processTemplate(
-  month: string,
-  force: boolean,
-): Promise<Notification> {
+async function setGoalBudget({ month, templateBudget }) {
+  await batchMessages(async () => {
+    templateBudget.forEach(element => {
+      setBudget({
+        category: element.category,
+        month,
+        amount: element.amount,
+      });
+    });
+  });
+}
+
+async function processTemplate(month, force, category_templates) {
+  let templateBudget = [];
   let num_applied = 0;
   let errors = [];
-  let category_templates = await getCategoryTemplates();
   let lowestPriority = 0;
   let originalCategoryBalance = [];
 
@@ -57,7 +82,11 @@ async function processTemplate(
       `budget-${category.id}`,
     );
     if (budgeted) {
-      originalCategoryBalance.push({ cat: category, amount: budgeted });
+      originalCategoryBalance.push({
+        cat: category,
+        amount: budgeted,
+        isIncome: category.is_income,
+      });
     }
     let template = category_templates[category.id];
     if (template) {
@@ -69,7 +98,22 @@ async function processTemplate(
       }
     }
   }
-  setZero({ month });
+
+  await setZero({ month });
+
+  //setZero() sets budgeted Income to 0. Reset income categories before continuing.
+  if (isReflectBudget()) {
+    for (let l = 0; l < originalCategoryBalance.length; l++) {
+      if (originalCategoryBalance[l].isIncome) {
+        await setBudget({
+          category: originalCategoryBalance[l].cat.id,
+          month,
+          amount: originalCategoryBalance[l].amount,
+        });
+      }
+    }
+  }
+
   // find all remainder templates, place them after all other templates
   let remainder_found;
   let remainder_priority = lowestPriority + 1;
@@ -87,11 +131,14 @@ async function processTemplate(
       }
     }
   }
-  // so the remainders don't get skiped
+  // so the remainders don't get skipped
   if (remainder_found) lowestPriority = remainder_priority;
 
   let sheetName = monthUtils.sheetForMonth(month);
   let available_start = await getSheetValue(sheetName, `to-budget`);
+  let available_remaining = isReflectBudget()
+    ? await getSheetValue(sheetName, `total-saved`)
+    : await getSheetValue(sheetName, `to-budget`);
   for (let priority = 0; priority <= lowestPriority; priority++) {
     // setup scaling for remainder
     let remainder_scale = 1;
@@ -152,15 +199,16 @@ async function processTemplate(
                 priority,
                 remainder_scale,
                 available_start,
+                available_remaining,
                 force,
               );
             if (to_budget != null) {
               num_applied++;
-              await setBudget({
+              templateBudget.push({
                 category: category.id,
-                month,
                 amount: to_budget,
               });
+              available_remaining -= to_budget;
             }
             if (applyErrors != null) {
               errors = errors.concat(
@@ -171,7 +219,9 @@ async function processTemplate(
         }
       }
     }
+    await setGoalBudget({ month, templateBudget });
   }
+
   if (!force) {
     //if overwrite is not preferred, set cell to original value
     for (let l = 0; l < originalCategoryBalance.length; l++) {
@@ -220,12 +270,13 @@ async function processTemplate(
 }
 
 const TEMPLATE_PREFIX = '#template';
-async function getCategoryTemplates() {
+async function getCategoryTemplates(category) {
   let templates = {};
 
   let notes = await db.all(
     `SELECT * FROM notes WHERE lower(note) like '%${TEMPLATE_PREFIX}%'`,
   );
+  if (category) notes = notes.filter(n => n.id === category.id);
 
   for (let n = 0; n < notes.length; n++) {
     let lines = notes[n].note.split('\n');
@@ -255,6 +306,7 @@ async function applyCategoryTemplate(
   priority,
   remainder_scale,
   available_start,
+  budgetAvailable,
   force,
 ) {
   let current_month = `${month}-01`;
@@ -328,9 +380,6 @@ async function applyCategoryTemplate(
   let budgeted = await getSheetValue(sheetName, `budget-${category.id}`);
   let spent = await getSheetValue(sheetName, `sum-amount-${category.id}`);
   let balance = await getSheetValue(sheetName, `leftover-${category.id}`);
-  let budgetAvailable = isReflectBudget()
-    ? await getSheetValue(sheetName, `total-saved`)
-    : await getSheetValue(sheetName, `to-budget`);
   let to_budget = budgeted;
   let limit;
   let hold;
@@ -661,7 +710,7 @@ async function applyCategoryTemplate(
 }
 
 async function checkTemplates(): Promise<Notification> {
-  let category_templates = await getCategoryTemplates();
+  let category_templates = await getCategoryTemplates(null);
   let errors = [];
 
   let categories = await db.all(
diff --git a/packages/loot-core/src/server/budget/types/handlers.d.ts b/packages/loot-core/src/server/budget/types/handlers.d.ts
index 8def30dd25903e0746599b1bde87e181f2f1ea44..3c44a0a4ba3d51b344545ba51e207550002f9465 100644
--- a/packages/loot-core/src/server/budget/types/handlers.d.ts
+++ b/packages/loot-core/src/server/budget/types/handlers.d.ts
@@ -15,13 +15,11 @@ export interface BudgetHandlers {
 
   'budget/check-templates': () => Promise<Notification>;
 
-  'budget/apply-goal-template': (arg: {
-    month: string;
-  }) => Promise<Notification>;
+  'budget/apply-goal-template': (arg: { month: string }) => Promise<unknown>;
 
   'budget/overwrite-goal-template': (arg: {
     month: string;
-  }) => Promise<Notification>;
+  }) => Promise<unknown>;
 
   'budget/cleanup-goal-template': (arg: {
     month: string;
@@ -38,4 +36,20 @@ export interface BudgetHandlers {
   'budget/transfer-category': (...args: unknown[]) => Promise<unknown>;
 
   'budget/set-carryover': (...args: unknown[]) => Promise<unknown>;
+
+  'budget/apply-single-template': (arg: {
+    month: string;
+    category: string; //category id
+  }) => Promise<unknown>;
+
+  'budget/set-n-month-avg': (arg: {
+    month: string;
+    N: number;
+    category: string; //category id
+  }) => Promise<unknown>;
+
+  'budget/copy-single-month': (arg: {
+    month: string;
+    category: string; //category id
+  }) => Promise<unknown>;
 }
diff --git a/upcoming-release-notes/1350.md b/upcoming-release-notes/1350.md
new file mode 100644
index 0000000000000000000000000000000000000000..0dea3c99feda988d184a94f921ba9a9e8726650f
--- /dev/null
+++ b/upcoming-release-notes/1350.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [shall0pass, kyrias]
+---
+
+Add ability to apply budget prefill calculations to a single category. Includes Goal template support.