diff --git a/Oqtane.Shared/Documentation/InternalApi.cs b/Oqtane.Shared/Documentation/InternalApi.cs
new file mode 100644
index 00000000..be660f77
--- /dev/null
+++ b/Oqtane.Shared/Documentation/InternalApi.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Oqtane.Documentation
+{
+ ///
+ /// This attribute serves as metadata for other things to mark them as internal APIs.
+ /// Use this on stuff you want to document publicly, but mark as internal so people are warned
+ ///
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
+ [PublicApi]
+ // ReSharper disable once InconsistentNaming
+ public class InternalApi_DoNotUse_MayChangeWithoutNotice: Attribute
+ {
+ ///
+ /// The `[InternalApi_DoNotUse_MayChangeWithoutNotice]` attribute can be used without additional comment.
+ ///
+ // Important note - this constructor looks unnecessary, because comment is optional in the other constructor
+ // but we need it because of a minor issue in docfx
+ public InternalApi_DoNotUse_MayChangeWithoutNotice() { }
+
+ ///
+ /// Constructor with optional comment `[InternalApi_DoNotUse_MayChangeWithoutNotice(some-comment)]`.
+ ///
+ /// Reason why it's internal, optional
+ public InternalApi_DoNotUse_MayChangeWithoutNotice(string comment) { }
+
+ }
+}
diff --git a/Oqtane.Shared/Documentation/PrivateApi.cs b/Oqtane.Shared/Documentation/PrivateApi.cs
new file mode 100644
index 00000000..decd0c24
--- /dev/null
+++ b/Oqtane.Shared/Documentation/PrivateApi.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Oqtane.Documentation
+{
+ ///
+ /// This attribute marks classes, methods, etc. as private APIs
+ /// So they should _not_ be publicly documented.
+ /// By default, all APIs are private, so you only need this attribute on children of classes marked with `[PublicApi]`.
+ ///
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
+ [PublicApi]
+ public class PrivateApi: Attribute
+ {
+ ///
+ /// The `[PrivateApi]` attribute can be used without additional comment.
+ ///
+ // Important note - this constructor looks unnecessary, because comment could be optional in the other constructor
+ // but we need it because of a minor issue in docfx
+ public PrivateApi() { }
+
+ ///
+ /// Constructor with optional comment `[PrivateApi(some-comment)]`.
+ ///
+ /// Reason why it's private, optional
+ public PrivateApi(string comment) { }
+ }
+}
diff --git a/Oqtane.Shared/Documentation/PublicApi.cs b/Oqtane.Shared/Documentation/PublicApi.cs
new file mode 100644
index 00000000..0c84a785
--- /dev/null
+++ b/Oqtane.Shared/Documentation/PublicApi.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Oqtane.Documentation
+{
+ ///
+ /// This attribute marks classes, properties etc. as public APIs.
+ /// Any API / code with this attribute will be published in the docs.
+ /// You can apply it to anything, but usually you will only need it on classes.
+ ///
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
+ [PublicApi]
+ public class PublicApi: Attribute
+ {
+ ///
+ /// The `[PublicApi]` attribute can usually be used without additional comment.
+ ///
+ // Important note - this constructor looks unnecessary, because comment could be optional in the other constructor
+ // but we need it because of a minor issue in docfx
+ public PublicApi() { }
+
+ ///
+ /// Constructor with optional comment `[PublicApi(some-comment)]`
+ ///
+ /// Reason why it's public, optional
+ public PublicApi(string comment) { }
+ }
+}
diff --git a/Oqtane.Shared/Documentation/WorkInProgressApi.cs b/Oqtane.Shared/Documentation/WorkInProgressApi.cs
new file mode 100644
index 00000000..c4ed0d88
--- /dev/null
+++ b/Oqtane.Shared/Documentation/WorkInProgressApi.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Oqtane.Documentation
+{
+ ///
+ /// This attribute marks APIs to be publicly documented with a clear warning that it's work in progress.
+ ///
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
+ [PublicApi]
+ public class WorkInProgressApi: Attribute
+ {
+ ///
+ /// The `[WorkInProgressApi(some-comment)]` attributes must always have a comment why they are WIP.
+ ///
+ /// Reason why it's WIP, required
+ public WorkInProgressApi(string comment) { }
+ }
+}
diff --git a/Oqtane.Shared/Documentation/readme.md b/Oqtane.Shared/Documentation/readme.md
new file mode 100644
index 00000000..cd55726a
--- /dev/null
+++ b/Oqtane.Shared/Documentation/readme.md
@@ -0,0 +1,7 @@
+# Oqtane API Decorator Attributes
+
+This folder contains special attributes for the API Code Generator.
+
+The idea is that only items marked with special attributes are valide public APIs, and only these will be documented in the public docs
+
+As of 2020, all APIs are documented, and only these marked as `[PrivateApi]` will be excluded. In future, we may reverse this to only document things marked as `[PublicApi]`.
\ No newline at end of file