Exynix
GUIDE2024-12-15

Revit API Automation Guide

Comprehensive guide to automating Revit workflows using the Revit API with C# and Python examples.

Best Practices für Revit-Automatisierung

Introduction to Revit Automation

Revit automation through the API (Application Programming Interface) allows AEC professionals to streamline repetitive tasks, enforce standards, #00E0FF]">and create custom workflows that extend Revit's native capabilities. This guide provides a comprehensive introduction to Revit API programming with practical examples class=class="text-[#FFA500]">"text-[#00E0FF]">in both C# and Python.

Getting Started with the Revit API

Before diving into specific automation examples, it's important to understand the structure #00E0FF]">and capabilities of the Revit API:

  • API Documentation: Accessing #00E0FF]">and navigating the Revit API documentation
  • Development Environment Setup: Configuring Visual Studio #00E0FF]">and Python environments
  • Basic Concepts: Understanding the Revit API #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">object model, transactions, and event handling
  • Add-#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">in Development: Creating external commands and applications

C# Examples for Revit Automation

C# is the primary language for Revit API development. Here are key examples covered class=class="text-[#FFA500]">"text-[#00E0FF]">in this guide:

1. #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Element Selection and Filtering

#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"my-8 rounded-lg overflow-hidden shadow-xl">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-gradient-to-r from-[#1A1D22] to-[#2B2F36] px-4 py-3 flex justify-between items-center border-b border-[#363A43]">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex items-center"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"h-3 w-3 rounded-full bg-[#00E0FF] mr-2"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"text-white font-medium">C# Example
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-[#1A1D22] p-0 overflow-x-auto"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"w-full">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"py-0 pl-0">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex">
                                        
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"min-w-[40px] text-right pr-3 select-none bg-[#2B2F36] text-[#666] font-mono text-xs py-4">1 2 3 4 5 6 7 8 9 10 11 12
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"language-csharp text-[#B0B3B8] font-mono text-sm py-4 flex-1">class=class="text-[#FFA500]">"text-[#666]">// Get all walls class=class="text-[#FFA500]">"text-[#00E0FF]">in the current document #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">FilteredElementCollector collector = class=class="text-[#FFA500]">"text-[#00E0FF]">new class=class="text-[#FFA500]">"text-[#A4FF00]">FilteredElementCollector(doc); ICollection<#00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Element> walls = collector.OfClass(typeof(Wall)).ToElements(); #00E0FF]">class=class="text-[#FFA500]">"text-[#666]">// Filter walls by parameter value List<#00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Element> filteredWalls = class=class="text-[#FFA500]">"text-[#00E0FF]">new List<class=class="text-[#FFA500]">"text-[#A4FF00]">Element>(); #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">foreach (class=class="text-[#FFA500]">"text-[#A4FF00]">Element wall class=class="text-[#FFA500]">"text-[#00E0FF]">in walls) { #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Parameter param = wall.LookupParameter(class="text-[#FFA500]">"Comments"); #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">if (param != class=class="text-[#FFA500]">"text-[#00E0FF]">null && param.AsString() == class="text-[#FFA500]">"Exterior") { filteredWalls.Add(wall); } }

2. #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Parameter Management

#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"my-8 rounded-lg overflow-hidden shadow-xl">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-gradient-to-r from-[#1A1D22] to-[#2B2F36] px-4 py-3 flex justify-between items-center border-b border-[#363A43]">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex items-center"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"h-3 w-3 rounded-full bg-[#00E0FF] mr-2"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"text-white font-medium">C# Example
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-[#1A1D22] p-0 overflow-x-auto"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"w-full">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"py-0 pl-0">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex">
                                        
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"min-w-[40px] text-right pr-3 select-none bg-[#2B2F36] text-[#666] font-mono text-xs py-4">1 2 3 4 5 6 7 8 9 10 11 12
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"language-csharp text-[#B0B3B8] font-mono text-sm py-4 flex-1">class=class="text-[#FFA500]">"text-[#666]">// Set parameter value for multiple elements #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">using (class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction tx = class=class="text-[#FFA500]">"text-[#00E0FF]">new class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction(doc, class="text-[#FFA500]">"Set Parameters")) { tx.Start(); #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">foreach (class=class="text-[#FFA500]">"text-[#A4FF00]">Element element class=class="text-[#FFA500]">"text-[#00E0FF]">in elements) { #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Parameter param = element.LookupParameter(class="text-[#FFA500]">"Mark"); #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">if (param != class=class="text-[#FFA500]">"text-[#00E0FF]">null && !param.IsReadOnly) { param.Set(#00E0FF]">class="text-[#FFA500]">"New Value"); } } tx.Commit(); }

3. Geometry Creation

#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"my-8 rounded-lg overflow-hidden shadow-xl">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-gradient-to-r from-[#1A1D22] to-[#2B2F36] px-4 py-3 flex justify-between items-center border-b border-[#363A43]">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex items-center"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"h-3 w-3 rounded-full bg-[#00E0FF] mr-2"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"text-white font-medium">C# Example
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-[#1A1D22] p-0 overflow-x-auto"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"w-full">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"py-0 pl-0">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex">
                                        
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"min-w-[40px] text-right pr-3 select-none bg-[#2B2F36] text-[#666] font-mono text-xs py-4">1 2 3 4 5 6 7 8 9 10 11 12
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"language-csharp text-[#B0B3B8] font-mono text-sm py-4 flex-1">class=class="text-[#FFA500]">"text-[#666]">// Create a wall by curve #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">using (class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction tx = class=class="text-[#FFA500]">"text-[#00E0FF]">new class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction(doc, class="text-[#FFA500]">"Create Wall")) { tx.Start(); #00E0FF]">class=class="text-[#FFA500]">"text-[#666]">// Create a line for the wall path XYZ start = #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">new XYZ(0, 0, 0); XYZ end = #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">new XYZ(20, 0, 0); Line line = Line.CreateBound(start, end); #00E0FF]">class=class="text-[#FFA500]">"text-[#666]">// Get wall type and level WallType wallType = #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">new class=class="text-[#FFA500]">"text-[#A4FF00]">FilteredElementCollector(doc) .OfClass(typeof(WallType)).FirstElement() as WallType; Level level = #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">new class=class="text-[#FFA500]">"text-[#A4FF00]">FilteredElementCollector(doc) .OfClass(typeof(Level)).FirstElement() as Level; #00E0FF]">class=class="text-[#FFA500]">"text-[#666]">// Create the wall Wall.Create(doc, line, wallType.Id, level.Id, 10, 0, #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">false, class=class="text-[#FFA500]">"text-[#00E0FF]">false); tx.Commit(); }

Python Examples #00E0FF]">for Revit Automation

Python offers a more accessible entry point #00E0FF]">for many users. This guide covers Python scripting through pyRevit and the RevitPythonShell:

1. #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Element Selection with Python

#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"my-8 rounded-lg overflow-hidden shadow-xl">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-gradient-to-r from-[#1A1D22] to-[#2B2F36] px-4 py-3 flex justify-between items-center border-b border-[#363A43]">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex items-center"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"h-3 w-3 rounded-full bg-[#A4FF00] mr-2"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"text-white font-medium">Python Example
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-[#1A1D22] p-0 overflow-x-auto"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"w-full">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"py-0 pl-0">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex">
                                        
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"min-w-[40px] text-right pr-3 select-none bg-[#2B2F36] text-[#666] font-mono text-xs py-4">1 2 3 4 5 6 7 8 9 10 11 12
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"language-python text-[#B0B3B8] font-mono text-sm py-4 flex-1"># Get all doors class=class="text-[#FFA500]">"text-[#00E0FF]">in the current document #00E0FF]">from Autodesk.Revit.DB import class=class="text-[#FFA500]">"text-[#A4FF00]">FilteredElementCollector, FamilyInstance, class=class="text-[#FFA500]">"text-[#8E44AD]">BuiltInCategory #00E0FF]">from Autodesk.Revit.UI import TaskDialog doc = __revit__.ActiveUIDocument.#00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Document doors = #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">FilteredElementCollector(doc).OfCategory(class=class="text-[#FFA500]">"text-[#8E44AD]">BuiltInCategory.OST_Doors).WhereElementIsNotElementType().ToElements() # Display count of doors TaskDialog.Show(#00E0FF]">class="text-[#FFA500]">"Door Count", class="text-[#FFA500]">"Number of doors: {}".format(len(doors)))

2. Working with Parameters #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">in Python

#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"my-8 rounded-lg overflow-hidden shadow-xl">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-gradient-to-r from-[#1A1D22] to-[#2B2F36] px-4 py-3 flex justify-between items-center border-b border-[#363A43]">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex items-center"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"h-3 w-3 rounded-full bg-[#A4FF00] mr-2"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"text-white font-medium">Python Example
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"bg-[#1A1D22] p-0 overflow-x-auto"> #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"w-full">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"py-0 pl-0">
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"flex">
                                        
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"min-w-[40px] text-right pr-3 select-none bg-[#2B2F36] text-[#666] font-mono text-xs py-4">1 2 3 4 5 6 7 8 9 10 11 12
#00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">class=class="text-[#FFA500]">"language-python text-[#B0B3B8] font-mono text-sm py-4 flex-1"># Get and modify parameters #00E0FF]">from Autodesk.Revit.DB import class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction doc = __revit__.ActiveUIDocument.#00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Document uidoc = __revit__.ActiveUIDocument # Start a transaction t = #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction(doc, class="text-[#FFA500]">"Modify Parameters") t.Start() # Get selected elements selection = [doc.GetElement(id) #00E0FF]">for id class=class="text-[#FFA500]">"text-[#00E0FF]">in uidoc.Selection.GetElementIds()] #00E0FF]">for element class=class="text-[#FFA500]">"text-[#00E0FF]">in selection: # Try to get the Comments parameter param = element.LookupParameter(#00E0FF]">class="text-[#FFA500]">"Comments") #00E0FF]">class=class="text-[#FFA500]">"text-[#00E0FF]">if param and not param.IsReadOnly: param.Set(#00E0FF]">class="text-[#FFA500]">"Modified by Python script") t.Commit()

Advanced Automation Techniques

Beyond basic API usage, this guide covers advanced automation techniques:

  • Dynamo Integration: Combining visual programming with API scripts
  • Batch Processing: Processing multiple files #00E0FF]">and elements
  • Database Integration: Connecting Revit to external databases
  • UI Development: Creating custom interfaces #00E0FF]">for your tools
  • Deployment: Distributing tools to team members

Practical Automation Workflows

The guide includes complete workflows #00E0FF]">for common automation scenarios:

  • Drawing Sheet Setup: Automating the creation of drawing sheets #00E0FF]">and views
  • Model Auditing: Checking models against standards #00E0FF]">and generating reports
  • Data Exchange: Exporting #00E0FF]">and importing data between Revit and other platforms
  • Documentation: Automating annotation #00E0FF]">and dimensioning
  • Design Automation: Generating design options based on parameters

Best Practices #00E0FF]">and Performance Optimization

Successful Revit automation requires attention to performance #00E0FF]">and reliability:

  • #00E0FF]">class=class="text-[#FFA500]">"text-[#A4FF00]">Transaction Management: Optimizing transaction usage for performance
  • Error Handling: Implementing robust error handling #00E0FF]">and logging
  • Performance Techniques: Methods to improve execution speed
  • Version Compatibility: Ensuring add-ins work across Revit versions
  • Testing Strategies: Approaches #00E0FF]">for testing automation tools
CODE EXAMPLES

Revit Automation Code Examples

Explore these practical code examples to implement Revit automation in your AEC projects. These snippets demonstrate key techniques for automating repetitive tasks in Revit.

RevitElementCollector.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
C# code for collecting and filtering Revit elements using FilteredElementCollector

Notes

  • These code examples are designed to work with Revit 2024 and later versions.
  • The C# examples can be used in Revit add-ins, while the Python script is intended for use with Dynamo or pyRevit.
  • Always test automation scripts on a copy of your project before running them on production models.

Tips

  • When creating Revit automation tools, focus on solving specific, repetitive tasks that consume significant time.
  • Use Revit's transaction system properly to ensure model integrity and enable undo operations.
  • Consider creating a user interface for your automation tools to make them accessible to team members.
  • Document your automation code thoroughly, especially parameter names and expected inputs/outputs.

Warnings

  • Automation scripts that modify model data should always be tested on backup copies first.
  • Be aware of Revit API changes between versions that might affect your automation code.
  • Large-scale automation operations may impact Revit performance; consider breaking them into smaller batches.

Request resource

The downloadable package is not published yet. Contact Exynix to request this resource or ask about the workflow.

Request resource

Try It Yourself

Experiment with the code examples in our interactive playground. Modify parameters, test different inputs, and see the results in real-time.

Revit Automation Best Practices | BIM Ressource fuer AEC Teams