diff --git a/markdown/dev/guides/v3/en.md b/markdown/dev/guides/v3/en.md
index ddd273a56d2..96c178d50e3 100644
--- a/markdown/dev/guides/v3/en.md
+++ b/markdown/dev/guides/v3/en.md
@@ -4,3 +4,11 @@ title: Migration guide
- named exports
- ESM only
+
+
+new:
+- point.addCircle
+- point.addText
+- point.setCircle
+- point.setText
+
diff --git a/markdown/dev/howtos/code/adding-text/en.md b/markdown/dev/howtos/code/adding-text/en.md
index d5dddcba509..cee40a90a52 100644
--- a/markdown/dev/howtos/code/adding-text/en.md
+++ b/markdown/dev/howtos/code/adding-text/en.md
@@ -16,9 +16,7 @@ points.anchor = new Point(100, 25)
.attr("data-text-class", "center");
```
-
-Text inserted in a FreeSewing pattern
-
+Text inserted in a FreeSewing pattern
diff --git a/markdown/dev/howtos/code/drawing-circles/en.md b/markdown/dev/howtos/code/drawing-circles/en.md
index 9fad26af7e2..f75b14cc1c2 100644
--- a/markdown/dev/howtos/code/drawing-circles/en.md
+++ b/markdown/dev/howtos/code/drawing-circles/en.md
@@ -1,7 +1,5 @@
---
title: Drawing circles
-for: developers
-about: Shows how you can add circles to your pattern
---
Real circles are rarely used in pattern design, and they are not part of the SVG path specification,
@@ -12,6 +10,38 @@ to the radius of the circle you want to draw.
In addition, all attributes that have a `data-circle-` prefix will apply to the circle, rather than the point.
-
-Circles
+Practically, you will probably want to use
+the [Point.addCircle()](/reference/api/point/adcircle) which does all of this for you behind the scenes:
+
+
+Examples of circles drawn on a pattern
+
+
+##### How multiple circles are implemented
+
+When you add the same attribute multiple times, they are typically joined together
+when rendering. For example multiple calls to add a `class` attribute will end up being
+rendered as `class="class1 class2 class3` which makes a lot of sense.
+
+But when we're placing multiple circles on the same point, that raises a bit of a problem.
+For example in this code:
+
+```js
+point.a = new Point(0,0)
+ .addCircle(10, 'lining')
+ .addCircle(20, 'fabric')
+```
+
+Based on the rules of attributes, this would render a single circle with `r="10 20"
+class="lining fabric"`. Which does not make a lot of sense and is invalid SVG
+as `r` only takes one value.
+
+So the render engine will do some extra work here to check that there are multiple
+circles added, and will render a circle element for each, with the `r` and `class`
+values of their respective calls.
+
+While this is probably what you'd intuitively expect, it is somewhat inconsistent with how
+other attributes are rendered, so I felt it was best to point it out explicitly.
+
+
diff --git a/markdown/dev/reference/api/point/addcircle/en.md b/markdown/dev/reference/api/point/addcircle/en.md
new file mode 100644
index 00000000000..c6c5626a6b0
--- /dev/null
+++ b/markdown/dev/reference/api/point/addcircle/en.md
@@ -0,0 +1,44 @@
+---
+title: Point.addCircle()
+---
+
+Adds a circle to a Point. Under the hood, this will call `Point.attr()` as circles
+are added by setting attributes. Refer to [Drawing circles](/howtos/code/drawing-circles) for
+more details.
+
+## Point.addCircle() signature
+
+```js
+Point point.addCircle(
+ string text,
+ string className
+)
+```
+
+## Point.addCircle() example
+
+
+Examples of Point.addCircle(), compare this to [Point.setCircle](/reference/api/point/setcircle)
+
+
+```js
+({ Point, points, part }) => {
+ points.a = new Point(30, 10)
+ .addCircle(3, 'lining dashed')
+ .addCircle(7, 'mark dashed')
+
+ points.b = new Point(50, 10)
+ .addCircle(1, 'interfacing')
+ .addCircle(3, 'fabric')
+ .addCircle(5, 'lining')
+ .addCircle(7, 'mark')
+ .addCircle(9, 'note')
+
+ points.c = new Point(70, 10)
+ .addCircle(3, 'interfacing')
+ .addCircle(7, 'mark lashed')
+
+ return part
+}
+```
+
diff --git a/markdown/dev/reference/api/point/addtext/en.md b/markdown/dev/reference/api/point/addtext/en.md
new file mode 100644
index 00000000000..887c4242e2a
--- /dev/null
+++ b/markdown/dev/reference/api/point/addtext/en.md
@@ -0,0 +1,35 @@
+---
+title: Point.addText()
+---
+
+Adds text on a Point. Under the hood, this will call `Point.attr()` as text
+is added by setting attributes. Refer to [Adding text](/howtos/code/adding-text) for
+more details.
+
+## Point.addText() signature
+
+```js
+Point point.addText(
+ string text,
+ string className
+)
+```
+
+## Point.addText() example
+
+
+Examples of Point.addText(), compare this to [Point.setText](/reference/api/point/settext)
+
+
+```js
+({ Point, points, part }) => {
+ points.anchor = new Point(100, 25)
+ .addText('supportFreesewingBecomeAPatron', 'center')
+ .addText('please?')
+
+ return part
+}
+```
+
+Remember to [use translation keys, not text](/guides/best-practices/use-translation-keys)
+
diff --git a/markdown/dev/reference/api/point/setcircle/en.md b/markdown/dev/reference/api/point/setcircle/en.md
new file mode 100644
index 00000000000..778e9601912
--- /dev/null
+++ b/markdown/dev/reference/api/point/setcircle/en.md
@@ -0,0 +1,47 @@
+---
+title: Point.setCircle()
+---
+
+Sets a circle to a Point. Behaves the same as [addCircle](/reference/api/points/addcircle) but
+the different is that it will overwrite any previous circle set.
+
+Essentially, it mimics the difference between adding vs setting an attribute.
+
+Refer to [Drawing circles](/howtos/code/drawing-circles) for more details on how circles are handled.
+
+## Point.setCircle() signature
+
+```js
+Point point.setCircle(
+ string text,
+ string className
+)
+```
+
+## Point.setCircle() example
+
+
+Examples of Point.setCircle(), compare this to [Point.addCircle](/reference/api/point/addcircle)
+
+
+```js
+({ Point, points, part }) => {
+ points.a = new Point(30, 10)
+ .setCircle(3, 'lining dashed')
+ .setCircle(7, 'mark dashed')
+
+ points.b = new Point(50, 10)
+ .setCircle(1, 'interfacing')
+ .setCircle(3, 'fabric')
+ .setCircle(5, 'lining')
+ .setCircle(7, 'mark')
+ .setCircle(9, 'note')
+
+ points.c = new Point(70, 10)
+ .setCircle(3, 'interfacing')
+ .setCircle(7, 'mark lashed')
+
+ return part
+}
+```
+
diff --git a/markdown/dev/reference/api/point/settext/en.md b/markdown/dev/reference/api/point/settext/en.md
new file mode 100644
index 00000000000..eadefbd06e7
--- /dev/null
+++ b/markdown/dev/reference/api/point/settext/en.md
@@ -0,0 +1,35 @@
+---
+title: Point.setText()
+---
+
+Sets text on a Point. Under the hood, this will call `Point.attr()` as text
+is set via attributes. Refer to [Adding text](/howtos/code/adding-text) for
+more details.
+
+## Point.setText() signature
+
+```js
+Point point.setText(
+ string text,
+ string className
+)
+```
+
+## Point.setText() example
+
+
+Examples of Point.setText(), compare this to [Point.setText](/reference/api/point/settext)
+
+
+```js
+({ Point, points, part }) => {
+ points.anchor = new Point(100, 25)
+ .setText('supportFreesewingBecomeAPatron', 'center')
+ .setText('please?')
+
+ return part
+}
+```
+
+Remember to [use translation keys, not text](/guides/best-practices/use-translation-keys)
+