diff --git a/assets/docs/custom-templates/custom-form-simple.png b/assets/docs/custom-templates/custom-form-simple.png
new file mode 100644
index 0000000..3b38be4
Binary files /dev/null and b/assets/docs/custom-templates/custom-form-simple.png differ
diff --git a/assets/docs/custom-templates/custom-form-standard.png b/assets/docs/custom-templates/custom-form-standard.png
new file mode 100644
index 0000000..2768c2b
Binary files /dev/null and b/assets/docs/custom-templates/custom-form-standard.png differ
diff --git a/assets/docs/custom-templates/developer-settings.png b/assets/docs/custom-templates/developer-settings.png
new file mode 100644
index 0000000..291179f
Binary files /dev/null and b/assets/docs/custom-templates/developer-settings.png differ
diff --git a/assets/docs/custom-templates/visual-editor.png b/assets/docs/custom-templates/visual-editor.png
new file mode 100644
index 0000000..f734d58
Binary files /dev/null and b/assets/docs/custom-templates/visual-editor.png differ
diff --git a/custom-requests/manifest-dsl.mdx b/custom-requests/manifest-dsl.mdx
new file mode 100644
index 0000000..16f15f8
--- /dev/null
+++ b/custom-requests/manifest-dsl.mdx
@@ -0,0 +1,158 @@
+---
+title: "Manifest DSL Reference"
+description: "The JSON shape that defines a custom request template: the call, the form, and the arguments"
+---
+
+A template is a JSON object called a **manifest**. It defines the on-chain call to make, the form a member fills, and how the filled values map into the call's arguments. This page is the full reference for that shape, useful when you hand-author a template in the **`Code`** tab or check a manifest an AI assistant produced.
+
+For what the feature is and how to enable it, see [Custom Requests](/custom-requests/overview).
+
+
+ You do not have to write this by hand. An AI assistant can produce a manifest from a plain-English description. Install the [`trezu-custom-proposal-template` skill](https://github.com/NEAR-DevHub/trezu/tree/main/docs/trezu-custom-proposal-template) and paste its output into the **`Code`** tab, then use this page to check the result.
+
+
+***
+
+## The Manifest
+
+A manifest is a JSON object. `version` is `1`, the only shape this schema describes.
+
+| Key | Required | Notes |
+|-----|----------|-------|
+| `version` | yes | The literal `1`. |
+| `id` | yes | A slug using `[A-Za-z0-9_-]`, unique within your treasury. It is both the template's page address and the marker stamped on every request it files. Reserved: `create`, `new`, `about`. |
+| `title` | yes | A human title for the template. |
+| `description` | no | A longer explanation, shown to the member filling the form. |
+| `icon` | no | An optional icon name. |
+| `summary` | no | A one-line human summary shown while filing. It may use `{{placeholders}}`. |
+| `binding` | yes | The fixed on-chain call. See below. |
+| `fields` | yes | The form inputs. See below. |
+| `args` | yes | The call's arguments. See below. |
+
+***
+
+## `binding` - The Call
+
+`binding` is the part of the call the author fixes. A member can never change it.
+
+```json
+"binding": {
+ "receiver_id": "guestbook.near",
+ "method_name": "add_message",
+ "deposit": "1",
+ "gas": "30000000000000"
+}
+```
+
+| Key | Notes |
+|-----|-------|
+| `receiver_id` | The contract to call. |
+| `method_name` | The method to call on it. |
+| `deposit` | The attached deposit in yoctoNEAR, as a whole-number string. |
+| `gas` | The gas to attach, as a whole-number string. |
+
+
+ `deposit` and `gas` are whole-number strings in base units, never decimals and never JSON numbers. NEAR amounts are larger than a normal number can hold without losing precision, so they stay as strings. For example, 1.1 NEAR is written `"1100000000000000000000000"` yoctoNEAR.
+
+
+***
+
+## `fields` - The Form Inputs
+
+`fields` is an array. Each field describes one input on the form.
+
+```json
+{ "name": "amount", "label": "Tip amount", "type": "amount", "required": true }
+```
+
+| Key | Notes |
+|-----|-------|
+| `name` | The input's key, using `[A-Za-z0-9_]`, unique within the manifest. This is what `{{placeholders}}` reference. |
+| `label` | The text shown above the input. |
+| `type` | One of the types below. |
+| `required` | Optional flag. Not allowed on `bool`, since a toggle always submits a value. |
+| `default` | Optional starting value. Must match the field's `type`. |
+| `help` | Optional hint shown under the input. |
+| `options` | Required for `select`, not allowed otherwise. An array of strings. |
+| `validation` | Optional rules. See below. |
+
+### Field Types
+
+| `type` | Renders and validates as |
+|--------|--------------------------|
+| `account` | A NEAR account id, with its shape checked. |
+| `token` | An omni token id such as `base-0x...`, as free text. |
+| `uint` | A whole-number string, safe for large values. |
+| `amount` | A whole-number string in base units, safe for large values. No decimals. |
+| `number` | A plain numeric value, for counts and ratios, not for token amounts. |
+| `text` | Free text. |
+| `select` | A dropdown of `options`. |
+| `bool` | A toggle. |
+| `json` | Raw JSON text. |
+
+### `validation`
+
+| Rule | Notes |
+|------|-------|
+| `min` / `max` | Whole-number strings. Only on the numeric types (`uint`, `amount`, `number`). |
+| `pattern` | A regular expression that must compile. Only on `text` and `number`. |
+
+
+ Use `amount` or `uint` (not `number`) for anything that becomes a token amount or other large on-chain value. These stay as digit strings the whole way through, so a value larger than a normal number can hold survives without being rounded.
+
+
+***
+
+## `args` - The Call's Arguments
+
+`args` is a JSON object, the literal arguments passed to the method. Any string value can contain `{{name}}` placeholders that reference a field by its `name`. When a member files the request, each placeholder is replaced with the value they entered.
+
+```json
+"args": {
+ "app": "trezu",
+ "text": "{{message}}",
+ "amount": "{{tip}}",
+ "meta": "{\"by\":\"{{author}}\"}"
+}
+```
+
+In this example `app` is a fixed value, `text` and `amount` are taken straight from member inputs, and `meta` composes a member input into a larger string.
+
+A value does not have to be a string. `args` can hold any JSON, including numbers, booleans, `null`, nested objects, and arrays. Non-string values are sent to the contract exactly as written, because placeholders are only ever resolved inside strings.
+
+Rules:
+
+- Every `{{placeholder}}` must reference a declared field. A reference to a name that does not exist is an error.
+- To write a literal `{{message}}` without it being treated as a placeholder, double the braces as `{{{{message}}}}`. It collapses to `{{message}}` in the output.
+- Composing values is just putting more than one placeholder in a string. `"{{first}}.{{last}}"` becomes `"alice.near"`.
+
+***
+
+## A Complete Example
+
+A template that sets a greeting on a guestbook contract:
+
+```json
+{
+ "version": 1,
+ "id": "set-greeting",
+ "title": "Set Greeting",
+ "binding": {
+ "receiver_id": "guestbook.near",
+ "method_name": "set_greeting",
+ "deposit": "0",
+ "gas": "30000000000000"
+ },
+ "fields": [
+ { "name": "greeting", "label": "Greeting", "type": "text", "required": true }
+ ],
+ "args": { "greeting": "{{greeting}}" },
+ "summary": "Set greeting to {{greeting}}"
+}
+```
+
+***
+
+## What a Filled Template Produces
+
+Filling and submitting the form above creates one treasury request: a `FunctionCall` to `guestbook.near` running `set_greeting`, with the member's greeting as the argument, the fixed `deposit` and `gas` from the binding, and a description carrying the template's title and an automatic marker that records which template filed it. From there it is an ordinary request that the team approves and the treasury executes.
diff --git a/custom-requests/overview.mdx b/custom-requests/overview.mdx
new file mode 100644
index 0000000..4bc85e8
--- /dev/null
+++ b/custom-requests/overview.mdx
@@ -0,0 +1,115 @@
+---
+title: "Custom Requests"
+description: "Author reusable forms that let your treasury file any on-chain call as a proposal, with no developer needed"
+---
+
+Trezu builds your everyday treasury proposals for you - payments, transfers, swaps, and staking. But your treasury is a SputnikDAO, and a SputnikDAO can call **any method on any contract**. Until now Trezu could show you those calls when someone else created them, it just had no way for you to create them yourself.
+
+**Custom Requests** close that gap. A member authors a reusable form once, and from then on anyone on the team can fill that form to file an arbitrary on-chain call as a normal request - with no hand-written arguments and no developer needed. Because it travels through your treasury's usual approvals and execution, a template never grants any authority on its own.
+
+
+ Enabling Custom Requests and authoring templates are reserved for members with the [Governance](/governance/members-and-roles#governance) role - the same permission that governs changes to your treasury policy. Once a template exists, any team member can fill and file it.
+
+
+***
+
+## How It Works
+
+A custom request moves through three stages, each gated by its usual permission.
+
+
+
+ A Governance member describes the call - the contract and method to invoke - and lays out the form members will fill. The template is saved to your treasury and reused as often as you like.
+
+
+ Any team member opens the template, fills in the inputs such as an amount, an account, or a message, and submits. Trezu assembles the on-chain call for them.
+
+
+ The submission lands in the **`Requests`** section as a `Pending` request, where the team reviews and votes on it just like any other. Once it reaches the voting threshold, the treasury executes the call.
+
+
+
+The author fixes the parts that must never change - the contract, the method, the attached deposit, and the gas. Members only ever supply the **arguments** to the call, so a filled request can never be redirected to a different contract or method.
+
+***
+
+## Turning It On
+
+Custom Requests ship disabled. A Governance member turns the feature on from **`Settings`** → **`Developer`**, and a **`Request Templates`** section appears in the left sidebar for everyone on the team.
+
+
+
+
+ The whole team can see and fill templates as soon as the feature is on. Only authoring stays with Governance.
+
+
+***
+
+## Authoring a Template
+
+A template is defined by a **manifest**, a small JSON document that captures the call and the form together. The editor gives you two ways to build one, and you can switch between them at any time.
+
+
+
+ A form builder that is arguments-first. Each argument is either **static**, a fixed value the author sets, or a **member input** that is filled in at request time. Reference an input and it becomes a form field automatically. This is the default, and it covers most templates.
+
+
+ A live-validated JSON editor over the same manifest, handy for pasting one in or making power edits.
+
+
+
+
+
+
+ Would rather not touch JSON? Hand the [Manifest DSL reference](/custom-requests/manifest-dsl) to any AI assistant, describe your proposal in plain English, and paste the manifest it returns into the **`Code`** tab. There is also a self-contained [`trezu-custom-proposal-template` skill](https://github.com/NEAR-DevHub/trezu/tree/main/docs/trezu-custom-proposal-template) for Claude Code, Claude.ai, and Codex.
+
+
+***
+
+## What Members Fill
+
+Once a template exists, filling it is as easy as any other request. A member opens it, completes the generated form, and clicks **`File Proposal`**. A one-field template is about as simple as it gets.
+
+
+
+The same mechanism scales all the way up to serious operations. Here a recovery-mint template gathers six inputs and files an omni-FT `ft_deposit` call, with every field validated before the request can be submitted.
+
+
+
+***
+
+## Who Can Do What
+
+| Action | Required |
+|--------|----------|
+| Enable the feature, or author, edit, or delete a template | Governance role |
+| See and fill a template | Team membership |
+| Approve the resulting request | Your treasury's normal voting rules |
+
+***
+
+## Frequently Asked Questions
+
+
+ Yes. A Governance member can edit or delete any template at any time from the **`Request Templates`** section. Requests that members already filed are unaffected, and continue through their normal review and execution.
+
+
+
+ No. The author fixes the contract, method, deposit, and gas when they build the template. Members can only fill in the arguments, so a filled request can never be pointed somewhere else.
+
+
+
+ Not at all. The Visual editor lets you build the whole call and its form without touching JSON. If you would rather describe what you want in plain English, hand the [Manifest DSL reference](/custom-requests/manifest-dsl) to an AI assistant and paste the result into the **`Code`** tab.
+
+
+
+ Exactly like any other request. It appears in **`Requests`** as `Pending`, shows the call it will make, and follows your treasury's normal voting rules before it executes.
+
+
+***
+
+## What's Next?
+
+
+ Ready to build one? Head to the [Manifest DSL reference](/custom-requests/manifest-dsl) for the full shape of a manifest, useful whether you are hand-authoring a template or checking what an assistant produced.
+
diff --git a/docs.json b/docs.json
index 4eeee14..659e0cc 100644
--- a/docs.json
+++ b/docs.json
@@ -49,6 +49,13 @@
"governance/handling-requests"
]
},
+ {
+ "group": "Custom Requests",
+ "pages": [
+ "custom-requests/overview",
+ "custom-requests/manifest-dsl"
+ ]
+ },
{
"group": "Finance",
"pages": [