Convert Revit Coordinates with Revit API [Internal, Project, Survey]
Coordinate Systems in Revit

Revit Coordinate Systems is a tricky topic!
Especially if you want to automate coordinates with Revit API…
In Revit API you need to be careful with units that you use.
Because It's so easy to use the wrong units
and then spend hours looking for an issue….
(Yeah… I've been there multiple times)
But don't worry,
I already did the hard work for you!
It took me couple of days,
but now I have my own Coordinate Converter
than anyone can use in in 3 lines of code.
Yeah… It's that simple.
And the best part?
I'm going to share it with you in a moment for FREE.
It will literally save you days of headache
All you'll have to do:
Copy my code
Understand 3 lines on how to use it
And enjoy the simplicity of working with coordinates
But before I share my grand solution…
Let's have a quick overview of coordinate systems in Revit.
Coordinate Systems Overview
There are 3 Coordinate Systems in Revit:
Internal (Used as the internal system of Revit, used in Revit API)
Project (Based on Project Base Point)
Survey (Based on Survey Point)
Also keep in mind that in Revit we can set True North rotation, which will not affect all systems similar.
Internal - True North Rotation is not applied
Project - True North Rotation is not applied
Survey - All coordinates will be affected by True North Rotation.

💡Pro Tip
Before you begin…
I really recommend creating proper tags to easily read correct values.,

It can easily help you avoid using the wrong units or data as you create your custom tools.
You can also push it a step further
and create tags for both:
Metric Units
Internal Units
This way you'll instantly notice if you're exporting the wrong data.
(Trust me, it happens way too often with coordinates when we use API…)
Alright and now - let's look into API
Revit Coordinates in Revit API
First of all you need to know that Revit API always uses Internal Coordinate System in feet.
That means that when you read XYZ values, you'll get them in Internal System in Feet.
And it also means that you need to prepare your XYZ values in Internal System in Feet.
And if you forget this, don't be surprised when your
elements are flying in the sky above your project.
Now let's look at how to convert coordinates with Code.
My Coordinate Converter Class
I've prepared a custom class that can convert XYZ points from any
coorindate system into any other with just a few lines.
🚨ANd Spoiler alert: you're about to see code that might scare many of you.
But you don't even have to understand anything about it.
👉 You just copy the code below.
👉 Paste in your script
👉 Scroll to next example to undrstand how to use it
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝
#==================================================
from Autodesk.Revit.DB import *
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type:Document
# ╔═╗╦ ╔═╗╔═╗╔═╗
# ║ ║ ╠═╣╚═╗╚═╗
# ╚═╝╩═╝╩ ╩╚═╝╚═╝
#==================================================
class CoordSys:
Internal = 'Internal'
Project = 'Project'
Survey = 'Survey'
class PointConverter:
pt_internal = None
pt_survey = None
pt_project = None
def __init__(self, input_pt, coord_sys=CoordSys.Internal):
"""Converte 2.0 for converting XYZ points between any Coordinate Systems.
Args:
:param input_pt: The XYZ point in Internal Coordinate System. Adjust coord_sys argument if you want to use other Cooridnate Systems.
:param coord_sys: The coordinate system chosen from CoordSys helper class (Internal, Project, Survey)
Example:
pt = elem.Location.Point
converter = PointConverter(pt, CoordSys.Internal)
pt_survey = pt_converter.pt_survey # XYZ in FEET
pt_survey_m = pt_converter.pt_survey_m # XYZ in Meters
pt_converter.print_in_metric(coord_sys=CoordSys.Survey)
"""
# type: float, float, float, CoordSys
# Get Systems Transform
srvTrans = self._GetSurveyTransform()
projTrans = self._GetProjectTransform()
#1️⃣ INPUT - INTERNAL COORDINATE SYSTEM
if coord_sys == CoordSys.Internal:
self.pt_internal = input_pt
self.pt_survey = self._ApplyInverseTransformation(srvTrans, self.pt_internal)
self.pt_project = self._ApplyInverseTransformation(projTrans, self.pt_internal)
#2️⃣ INPUT - PROJECT COORDINATE SYSTEM
elif coord_sys == CoordSys.Project:
self.pt_project = input_pt
self.pt_internal = self._ApplyTransformation(projTrans, self.pt_project)
self.pt_survey = self._ApplyInverseTransformation(srvTrans, self.pt_internal)
#3️⃣ - SURVEY COORDINATE SYSTEM
elif coord_sys == CoordSys.Survey:
self.pt_survey = input_pt
self.pt_internal = self._ApplyTransformation(srvTrans, self.pt_survey)
self.pt_project = self._ApplyInverseTransformation(projTrans, self.pt_internal)
else:
raise Exception("Wrong argument value for 'coord_sys' in PointConverter class.")
#🧮 Create Metric Points
self.pt_internal_m = self._get_metric_XYZ(CoordSys.Internal)
self.pt_project_m = self._get_metric_XYZ(CoordSys.Project)
self.pt_survey_m = self._get_metric_XYZ(CoordSys.Survey)
def print_in_metric(self, coord_sys, units=UnitTypeId.Meters):
""" Helper function to display coordinates in Metric System."""
pt_m = self._get_metric_XYZ(coord_sys, units)
print('[{}] XYZ: ({}m, {}m, {}m)'.format(coord_sys, pt_m.X, pt_m.Y, pt_m.Z))
#🚧 INTERNAL HELPING METHODS
def _get_metric_XYZ(self, coord_sys, units=UnitTypeId.Meters):
"""Convert the point into Metric XYZ System.
NB! Do not use it with Revit API as it needs internal units."""
# Get Point With Correct Coordinate System
if coord_sys == CoordSys.Internal: pt = self.pt_internal
elif coord_sys == CoordSys.Project: pt = self.pt_project
elif coord_sys == CoordSys.Survey: pt = self.pt_survey
# Convert Values to Metric
X_m = UnitUtils.ConvertFromInternalUnits(pt.X, units)
Y_m = UnitUtils.ConvertFromInternalUnits(pt.Y, units)
Z_m = UnitUtils.ConvertFromInternalUnits(pt.Z, units)
return (XYZ(X_m, Y_m, Z_m))
def _GetSurveyTransform(self):
"""Gets the Active Project Locations Transform (Survey)."""
return doc.ActiveProjectLocation.GetTotalTransform()
def _GetProjectTransform(self):
"""Get the Project Base Points Transform."""
basePtLoc = next((l for l in FilteredElementCollector(doc) \
.OfClass(ProjectLocation) \
.WhereElementIsNotElementType() \
.ToElements() if l.Name == "Project"), None)
return basePtLoc.GetTotalTransform()
def _ApplyInverseTransformation(self, t, pt):
"""Applies the inverse transformation of
the given Transform to the given point."""
return t.Inverse.OfPoint(pt)
def _ApplyTransformation(self, t, pt):
"""Applies the transformation of
the given Transform to the given point."""
return t.OfPoint(pt)
🤔How to use it?
And now, here's the gravy for your fries.
As I mentioned:
You don't even need to understand the class I provided.
You just need to use a few methods.
💡And please pay attention to units that you use !
And here's an example:
Where I'll take a list of generic models ('EF_Box')
And I'm going to convert internal coordinates into Project and Survey Systems.
# Get Elements
elems = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsNotElementType().ToElements()
boxes = [e for e in elems if 'EF_Box' in e.Name] # ⚠️ I use specific Type Name to filter...
# Get Coordinates
for box in boxes:
# Get Location
pt = box.Location.Point # Internal Coordinate System (defualt)
# 👉 Convert XYZ Point
pt_converter = PointConverter(pt, CoordSys.Internal)
pt_survey = pt_converter.pt_survey # XYZ - SURVEY WITH VALUES IN FEET
pt_survey_m = pt_converter.pt_survey_m # XYZ - SURVEY WITH VALUES IN METERS
pt_project = pt_converter.pt_project # XYZ - PROJECT WITH VALUES IN FEET
pt_project_m = pt_converter.pt_project_m # XYZ - PROJECT WITH VALUES IN METERS
# Extra Function To Print Correct Data Display Results
pt_converter.print_in_metric(coord_sys=CoordSys.Survey)Simple right?
As you can see I've used XYZ with internal coordinates to create Survey and Project coordinates.
But I could also import some excel data of Survey coordinates, and convert it back into internal…
You get the point.
Enjoy working with Revit API Coordinates like a Pro.
Feel free to mention this article to others coders!
They'll love you for that.
Happy Coding.
The Ultimate Python Course For Beginners (Learn How To Code in 2026)
Revit API Course For Beginners (The Best Way To Get Started)