Understanding Inputs in CoPilot Commands
Every CoPilot command can receive information from the user.
This information is collected through inputs—small parameters that appear in the command UI when the user runs your command.
Inputs allow you to:
Ask the user for names, numbers, and text
Let the user select Revit categories, types, and elements
Enable or disable behaviors
Pick files or configure options before execution
Build flexible commands that adapt to each project’s needs
In other words, inputs are the bridge between the user and your command logic.
By defining inputs correctly, you control what information the user must provide, what is optional, and what controls are shown in the UI.
Defining inputs is extremely simple:
you only need to write small annotation blocks above each variable, and CoPilot automatically turns them into UI components for the user.
This section explains:
What types of inputs you can define
How each type appears in the UI
How to make inputs optional or multi-select
How to use editors (category selector, element selector, file picker, etc.)
Where to place the input definitions inside your command
After reading this section, you will know exactly how to design inputs that make your commands clear, flexible, and user-friendly.
Definition of Inputs
Commands in CoPilot can have one or more inputs.
Each input has a type, which defines what kind of value the user can provide and how it is shown in the UI.
Inputs in a command can be one of the following types:
Input type | Description | C# Type | Examples |
String | Text value entered by the user. | string | Name, code, note, parameter value |
Integer | Whole number value. | int | Count, index, quantity |
Double | Floating-point number. | double | Length, ratio, scale factor |
Boolean | True/false flag shown as a checkbox. | bool | Enable/disable options, switches |
List of IDs (elements, categories, types) | Multiple IDs representing Revit objects. | long | Multi-selection of sheets, views, categories, etc. |
Forms of Each Input Type
Every input type can appear in one of the following forms:
Type of input | Description | Syntax |
Mandatory single value | User must provide a value. | T VALUE; |
Optional single value | User can leave empty. | T? VALUE_OPTIONAL; |
Mandatory multi-select | User must select at least one item. | T[] VALUES; |
Optional multi-select | User may select zero, one, or many. | T[]? VALUES_OPTIONAL; |
How to Define an Input
To define an input, you must place a structured annotation block directly above the variable declaration:
Meaning of the fields
T — The data type (e.g.,
string,int,bool,long,string[], etc.)PARAMETER_NAME — The variable name you will use inside your command code
@editor — Used only when selecting elements, categories, classes, or files
@editorConfig — Provides filters and additional settings for special editors
Where to Place Inputs
All inputs must be declared at the beginning of your command code, inside a dedicated block:
This ensures CoPilot can detect and expose your parameters properly in the UI.
Example: Complete Input Definition
Here is a simple example showing two inputs — one string and one integer — placed correctly inside the vars block:
CoPilot will display these inputs as two fields in the UI:
A text box labeled Sheet Name
A numeric box labeled Starting Sheet Number
And your command code can then use SHEET_NAME and STARTING_NUMBER normally.
Using Inputs Inside Your Command Code
All inputs are declared inside the // vars start and // vars end block.
After this block, your command logic begins. The variables you defined above become regular C# variables you can read, validate, and convert.
For many selectors (category, class, element, picker, etc.), the input type is long.
This long value is the Revit element ID of the selected item.
Before you can use it, you usually need to:
Validate that a value was actually provided (not a default like
-1).Convert the
longtoElementId.Get the actual
Element(or a specific type likeRoom,View,FamilyInstance, etc.) from the document.Use that element in your logic.
Example of usage:
String Input
Here are the details for defining string inputs.
String inputs allow the user to enter a text value, which can then be used in the code for different purposes.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
String | string | - | Names, keys, parameters | |
Editor Config | - | |||
Examples:
String Dropdown Input
String dropdown inputs allow the user to choose one or more values from a predefined list of text options.
These inputs are useful when the valid values are limited, such as colors, modes, types, labels, or configuration presets.
You can define dropdowns in three forms:
Single-selection dropdown — the user must select exactly one option.
Multi-selection dropdown — the user can select multiple options.
Dropdown with default value — a predefined option is selected automatically.
The available options are defined inside the @editorConfig annotation using the options list.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
String | string | - | Predefined Names | |
Editor Config | { "options": [{ "title": "Red", "value": "Red" }, { "title": "Blue", "value": "Blue" }]} | |||
Examples:
Integer Inputs
Integer inputs allow the user to provide whole-number values that your command can use for calculations, indexing, counts, and many other numeric operations.
They are one of the simplest and most common input types.
You can define integer inputs in several forms depending on whether the value is required, optional, or part of a list.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Integer Number | int | - | Counts, sizes, indices | |
Editor Config | - | |||
Examples:
Double Inputs
Double inputs allow the user to provide floating-point numbers (values that may contain decimals).
They are typically used for measurements, ratios, offsets, scales, tolerances, and any operation that requires numeric precision.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Double Number | double | - | Dimensions, scale values | |
Editor Config | - | |||
Examples:
Boolean Inputs
Boolean inputs allow the user to enable or disable a feature through a simple checkbox.
These inputs are used when a command needs a true/false decision — such as toggles, switches, options, or conditional behaviors.
You can define boolean inputs in several forms: mandatory, optional, or with a default value.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Checkbox | bool | - | Dimensions, scale values | |
Editor Config | - | |||
Examples:
Category Selector Inputs
Category selector inputs allow the user to choose one or more Revit categories directly from the UI.
These inputs are useful when your command requires the user to specify which types of elements it should work with — for example, walls, doors, sheets, title blocks, ducts, or any other BuiltInCategory.
All category selections use the categorySelector editor, which displays a list of available categories inside Revit.
Category selectors come in four forms: single selection, optional single selection, multi-selection, and optional multi-selection.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Category | long | ![]() | categorySelector | Revit categories |
Editor Config | - | |||
Examples:
Type Selector Inputs (By Category)
Element Type of Category selectors allow the user to choose one or more Revit element types filtered by a specific BuiltInCategory. These inputs are designed for situations where your command must work with types rather than instances, such as selecting Title Block Types, Wall Types, Door Types, or any other element type defined under a category.
Behind the scenes, this selector works the same way as using a FilteredElementCollector with two filters:
Filter by Category – Only elements from the specified
BuiltInCategoryare included.Filter by Element Type – Only types (not instances) are shown in the selection UI.
In Revit API terms, this is equivalent to:
The selector UI performs these filters internally and displays the resulting element types for the user to choose from. You can define this input as single-selection, optional, multi-selection, or optional multi-selection depending on your command’s needs.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Element Types in document | long | ![]() | categorySelector | Choose Revit Types from a Category |
Editor Config | {"providerName": "Element", "filterByBuiltInCategory": ["OST_TitleBlocks"], "filterByIsType": true} | |||
Examples:
Element Selector Inputs (By Category)
Element of Category selectors allow the user to choose one or more Revit element instances filtered by a specific BuiltInCategory.
These inputs are used when your command needs to work directly with placed elements in the model, such as Sheets, Views, Rooms, Grids, Title Blocks on sheets, or any other instance-type elements inside a category.
This selector behaves the same way as a FilteredElementCollector in Revit with two filters applied:
Filter by Category – Only elements that belong to the specified
BuiltInCategoryare considered.Filter by Element Instance – Only instances (not types) are included in the results.
In terms of Revit API logic, this is equivalent to:
The selector UI applies these filters behind the scenes and displays the resulting list of elements for the user to choose from.
You can define this input as single-selection, optional, multi-selection, or optional multi-selection depending on the requirements of your command.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Elements in document | long | ![]() | categorySelector | Choose Revit Elements from a Category |
Editor Config | { providerName: "Element" , filterByBuiltInCategory: ["OST_Views"], filterByIsType: false} | |||
Examples:
Type Selector Inputs (By Class)
Element Type of Class selectors allow the user to choose one or more Revit element types filtered by a specific .NET class.
This input is used when your command must work with types that belong to a particular Revit API class, such as ViewType, FamilySymbol, PlanView, RebarBarType, etc.
These selectors do not rely on categories—they filter based on the .NET type of the Revit element.
This gives you more control when you want only the element types that derive from or match a specific API class.
Internally, the selector works the same way as using a FilteredElementCollector with:
Filter by .NET Class – Only elements whose .NET type matches the desired Revit class are included.
Filter by Element Type – Only types (not instances) are allowed.
In Revit API terms, this is equivalent to:
The selector UI performs these filters behind the scenes and displays a list of element types that match the specified class.
You may define this input as single-selection, optional, multi-selection, or optional multi-selection based on your command’s requirements.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Element types in document | long | ![]() | categorySelector | Choose Revit Types from a Class |
Editor Config | {"providerName": "Element", "filterByNetType": ["Autodesk.Revit.DB.ViewFamilyType"], "filterByIsType": true} | |||
Examples:
Element Selector Inputs (By Class)
Element of Class selectors allow the user to choose one or more Revit element instances filtered by a specific .NET class.
These inputs are ideal when your command needs to work with actual placed elements—such as Plan Views, 3D Views, Family Instances, Schedules, or any other instance that belongs to a particular API class.
Unlike category-based selectors, this filter works on the element’s .NET type, meaning you can precisely target elements that belong to a class like PlanView, View, FamilyInstance, or any custom or specific Revit API element class.
This selector behaves similarly to a FilteredElementCollector using:
.NET Class Filter – Only elements whose .NET type matches the specified class are included.
Instance Filter – Only element instances are shown (not element types).
In Revit API terms, this corresponds to:
The selector UI applies these filters automatically and presents the user with a list of matching instance elements.
You can define this input as single-selection, optional, multi-selection, or optional multi-selection depending on your command’s requirements.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Elements in document | long | ![]() | categorySelector | Choose Revit Elements from a Class |
Editor Config | {"providerName": "Element", "filterByNetType": ["Autodesk.Revit.DB.ViewPlan"], "filterByIsType": false} | |||
Examples:
Element of Class Selector (Including Derived Classes)
In some scenarios, you may want the selector to include not only elements of a specific class but also all elements derived from that class.
For example, when filtering by Autodesk.Revit.DB.View, you may want to include Plan Views, 3D Views, Section Views, Elevation Views, Drafting Views, and other subclasses.
This behavior can be enabled by setting:
This mode extends the class matching logic so it works the same as checking:
And in API terms, the equivalent FilteredElementCollector logic is:
This selector gathers all element instances that belong to the chosen class or any subclass, making it extremely flexible when the command targets a broad group of related element types.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Elements in document | long | ![]() | categorySelector | Choose Revit Elements from a Class |
Editor Config | {"providerName": "Element", "filterByNetType": ["Autodesk.Revit.DB.View, RevitAPI"], "filterNetTypeMatchMode": "InheritorTypes", "filterByIsType": false} | |||
Examples:
Element Picker Inputs (Interactive Selection in View)
Element picker inputs allow the user to select elements directly in the Revit view, instead of choosing from a list. When a command uses an element picker, CoPilot activates Revit’s selection mode, shows a status prompt (for example: “Select a duct in the chosen view”), and waits for the user to click one or more elements.
These inputs behave very similarly to calling UIDocument.Selection.PickObject or PickObjects in the Revit API, combined with an element selection filter:
When filtered by category (
builtInCategories), only elements whose category matches one of the specified BuiltInCategories can be picked. This is like usingPickObject(s)with anISelectionFilterthat checkselement.Category.Id.When filtered by class (
netTypes), only elements whose .NET type matches the given Revit API class (for exampleAutodesk.Revit.DB.FamilyInstance) can be picked. This is like usingPickObject(s)with anISelectionFilterthat checkselement is FamilyInstance.
Conceptually, the behavior is equivalent to something like:
The selected elements are stored as element IDs in your inputs:
Single element →
longorlong?Multiple elements →
long[]orlong[]?
You can define element picker inputs as:
Single vs multi-select
Mandatory vs optional
Filtered by category (
builtInCategories) or by class (netTypes)
All of this is controlled via the elementSelector editor and its @editorConfig settings.
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
Elements in UI | long | elementSelector | Pick Revit Elements from Revit View | |
Editor Config | {"statusPrompt": "Select a duct in the chosen view", "builtInCategories": ["OST_DuctCurves"]} {"statusPrompt": "Select your family instance.", "netTypes": ["Autodesk.Revit.DB.FamilyInstance, RevitAPI"]} | |||
Examples:
File Picker Input
A File Picker input allows the user to select a file from their computer.
This input is typically used when your command requires external data—such as Excel spreadsheets, configuration files, text files, or other supported formats.
When the command runs, the File Picker opens a dialog window and lets the user browse to a file that matches the filter rules defined in the @editorConfig.
The selected file path is then stored as a string and can be used within your code to read or process the file.
The file picker can be configured to accept specific file types using the filters option, where you can define one or more extension groups (for example: Excel files, CSV files, images, etc.).
Input | C# Type | UI Element | Editor | Typical use |
|---|---|---|---|---|
File picker | long | filePicker | Choose a file from drive | |
Editor Config | {"filters": [{"name": "Excel Files", "extensions": ["xlsx", "xls"]}]} | |||
Examples:
Global Context Variables
When you write or edit a CoPilot command, certain objects and helper utilities are automatically provided for you.
You do not need to define or initialize these.
They are already available anywhere in your command code after the // vars end block.
These global variables give you access to the Revit API, the active document, logging utilities, and progress updates.
Below is a list of all provided global context objects:
Revit API Context
UIApp
The global UIApplication instance.
Use it to access application-level features such as:
Application settings
Active add-ins
UI-level information
UIDoc
The active UIDocument for the current project.
You’ll use this constantly to:
Access the active document
Pick elements
Retrieve selections
Modify the model (inside a transaction)
For convenience, many examples use:
Logging Utility
Logger
Use this to record messages during execution In Markdown format.
Everything you append here will appear in the CoPilot output panel.
Example:
Progress and Cancellation Helpers
These methods help you report progress or handle cancellation in long operations.
Check Cancellation
Call this inside loops to allow CoPilot to cancel gracefully.
Progress Updates
Examples:
Important Note:
These variables are automatically injected by CoPilot:
You do not define them
You do not initialize them
You do not need any using statements beyond the standard Revit namespaces
You can use them immediately after the
// vars endblock
This ensures a consistent environment for every CoPilot command and allows you to focus entirely on your command logic.







