Skip to content
PyPath

Read and set Revit parameters with Python (with a Transaction)

Parameters are the data of your model. How to read them, how to fill them in bulk, and the pitfalls that make Set do nothing or raise an error.

5 min readUpdated October 10, 2026Checked against the Revit API 2025 documentation

Short answer: get a parameter with element.get_Parameter(BuiltInParameter...) (or LookupParameter("name") for your own parameters), read it with AsString(), AsDouble(), AsInteger() or AsValueString(), and change it with Set(value). Changing is only allowed inside a Transaction; in pyRevit you write with revit.Transaction("name"):.

Getting a parameter

There are two ways:

  • get_Parameter(BuiltInParameter.X) for parameters Revit itself has, such as length, diameter, mark, comments or system name. The names are in the BuiltInParameter enum, for example CURVE_ELEM_LENGTH, RBS_PIPE_DIAMETER_PARAM, ALL_MODEL_MARK and ALL_MODEL_INSTANCE_COMMENTS.
  • LookupParameter("name") for parameters you added yourselves: project parameters and shared parameters.

Not sure what a parameter is called in the API? Select the element with the free RevitLookup add-in and look at its parameters.

Why LookupParameter breaks in a localised Revit

LookupParameter searches by the name you see in Revit. That depends on Revit's language: what is called "Length" in an English Revit is "Lengte" in a Dutch one. A script with LookupParameter("Length") then works for one colleague and not for another. So for built-in parameters always use get_Parameter with a BuiltInParameter: that name is the same in every language.

Reading a value

A parameter has a storage type (StorageType): text, decimal number, whole number or a reference to another element. The read function follows from it:

ReadParameters.pushbutton/script.py
from Autodesk.Revit.DB import *

doc = __revit__.ActiveUIDocument.Document

pipe = (FilteredElementCollector(doc)
        .OfCategory(BuiltInCategory.OST_PipeCurves)
        .WhereElementIsNotElementType()
        .FirstElement())

diameter = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM)
print(diameter.StorageType)        # Double
print(diameter.AsDouble())         # in feet
print(diameter.AsValueString())    # as Revit displays it
system = pipe.get_Parameter(BuiltInParameter.RBS_SYSTEM_NAME_PARAM)
print(system.AsString())
print(pipe.get_Parameter(BuiltInParameter.ELEM_TYPE_PARAM).AsValueString())
Output on the simulated greenhouse model (Dutch names)
Double
0.13123359580052493
40 mm
CV Aanvoer
Staal gelast
  • AsDouble() returns the number in Revit's internal unit: feet. 0.131 feet is 40 mm.
  • AsValueString() returns the text as Revit shows it, with the project units. Handy for a list, not for calculations.
  • AsString() is for text parameters, AsInteger() for whole numbers and yes/no, AsElementId() for references.

Changing a value: always in a Transaction

Anything that changes the model must happen inside a transaction. With pyRevit's helper module that is one line. This script puts a comment on every pipe and counts how often it worked:

Comment.pushbutton/script.py
from pyrevit import revit, DB

pipes = (DB.FilteredElementCollector(revit.doc)
         .OfCategory(DB.BuiltInCategory.OST_PipeCurves)
         .WhereElementIsNotElementType()
         .ToElements())

changed = 0
with revit.Transaction("Fill in comment"):
    for pipe in pipes:
        p = pipe.get_Parameter(DB.BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)
        if p and not p.IsReadOnly:
            if p.Set("checked"):
                changed += 1

print("Comment set on {} pipes".format(changed))
Output on the simulated greenhouse model
Comment set on 45 pipes

In Revit the whole with block is one step you can undo with Ctrl+Z. If something goes wrong halfway, pyRevit rolls everything back.

Without pyRevit's helper: a plain Transaction

Outside pyRevit, or if you prefer to handle it yourself, use the Transaction class from the Revit API. Do not forget to roll back on an error:

script.py
from Autodesk.Revit.DB import *

doc = __revit__.ActiveUIDocument.Document
pipe = (FilteredElementCollector(doc)
        .OfCategory(BuiltInCategory.OST_PipeCurves)
        .WhereElementIsNotElementType()
        .FirstElement())
p = pipe.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)

t = Transaction(doc, "Fill in comment")
t.Start()
try:
    p.Set("checked")
    t.Commit()
except Exception:
    t.RollBack()
    raise
print(t.GetStatus())
Output on the simulated greenhouse model
Committed

Pitfalls

Set returns False instead of raising an error

Pass a value of the wrong type and Set does nothing and returns False. A classic: a whole number on a parameter that stores decimals.

script.py
from Autodesk.Revit.DB import *

doc = __revit__.ActiveUIDocument.Document
pipe = (FilteredElementCollector(doc)
        .OfCategory(BuiltInCategory.OST_PipeCurves)
        .WhereElementIsNotElementType()
        .FirstElement())
d = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM)

t = Transaction(doc, "Diameter")
t.Start()
print(d.Set(5))                     # whole number on a Double parameter
new = UnitUtils.ConvertToInternalUnits(50, UnitTypeId.Millimeters)
print(d.Set(new))                   # Double: in feet
print(d.AsValueString())
t.RollBack()
Output on the simulated greenhouse model
False
True
50 mm

So check the result of Set, as in the comments example above.

Read-only parameters

Some parameters are calculated by Revit itself, such as the system name of a pipe. IsReadOnly is then True, and Set raises an error: The parameter is read-only. So check IsReadOnly first.

Type parameters

Part of the data is not on the element but on its type. You get the type with doc.GetElement(element.GetTypeId()). If you change a type parameter, it changes for all elements of that type. So do it on purpose.

Units

Lengths and diameters are stored in feet internally. Convert with UnitUtils.ConvertToInternalUnits and UnitUtils.ConvertFromInternalUnits, using for example UnitTypeId.Millimeters.

What exactly happens when you forget the transaction is covered in "Attempt to modify the model outside of transaction".