Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.23.0"
".": "1.24.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 27
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/moderation-api/moderation-api-cbf656f40e43acf60d9596f78204f031dc8c7205626df8f05ce8e88bcf49b597.yml
openapi_spec_hash: 23be5a56248a1a575b34833eb7e7fe49
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/moderation-api/moderation-api-9c5291067ec36cba0c9ef772c5c8eb10238fb332f1f25d0e31f3f2ad87c24e5e.yml
openapi_spec_hash: 790cc0a36d6ed693c06a285c441ab977
config_hash: 9d144cc6c49d3fd53e5b4472c1e22165
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 1.24.0 (2026-06-02)

Full Changelog: [v1.23.0...v1.24.0](https://github.com/moderation-api/sdk-python/compare/v1.23.0...v1.24.0)

### Features

* **api:** api update ([45d1814](https://github.com/moderation-api/sdk-python/commit/45d18143451c84ec01a86e55178901674b5bb5e3))

## 1.23.0 (2026-06-01)

Full Changelog: [v1.22.0...v1.23.0](https://github.com/moderation-api/sdk-python/compare/v1.22.0...v1.23.0)
Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,14 @@ from moderation_api import ModerationAPI

client = ModerationAPI()

author = client.authors.create(
external_id="external_id",
metadata={},
response = client.content.submit(
content={
"text": "text",
"type": "text",
},
client_action={"action": "review"},
)
print(author.metadata)
print(response.client_action)
```

## Handling errors
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "moderation_api"
version = "1.23.0"
version = "1.24.0"
description = "The official Python library for the moderation-api API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/moderation_api/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "moderation_api"
__version__ = "1.23.0" # x-release-please-version
__version__ = "1.24.0" # x-release-please-version
12 changes: 12 additions & 0 deletions src/moderation_api/resources/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def submit(
content: content_submit_params.Content,
author_id: str | Omit = omit,
channel: str | Omit = omit,
client_action: content_submit_params.ClientAction | Omit = omit,
content_id: str | Omit = omit,
conversation_id: str | Omit = omit,
do_not_store: bool | Omit = omit,
Expand All @@ -74,6 +75,10 @@ def submit(
channel: Provide a channel ID or key. Will use the project's default channel if not
provided.

client_action: A recommendation from your own client-side flagging (e.g. a banned-IP list or a
third-party tool). Feeds the rules engine and can escalate or override the
recommended action. Does not change whether our analysis flagged the content.

content_id: The unique ID of the content in your database.

conversation_id: For example the ID of a chat room or a post
Expand Down Expand Up @@ -104,6 +109,7 @@ def submit(
"content": content,
"author_id": author_id,
"channel": channel,
"client_action": client_action,
"content_id": content_id,
"conversation_id": conversation_id,
"do_not_store": do_not_store,
Expand Down Expand Up @@ -147,6 +153,7 @@ async def submit(
content: content_submit_params.Content,
author_id: str | Omit = omit,
channel: str | Omit = omit,
client_action: content_submit_params.ClientAction | Omit = omit,
content_id: str | Omit = omit,
conversation_id: str | Omit = omit,
do_not_store: bool | Omit = omit,
Expand All @@ -171,6 +178,10 @@ async def submit(
channel: Provide a channel ID or key. Will use the project's default channel if not
provided.

client_action: A recommendation from your own client-side flagging (e.g. a banned-IP list or a
third-party tool). Feeds the rules engine and can escalate or override the
recommended action. Does not change whether our analysis flagged the content.

content_id: The unique ID of the content in your database.

conversation_id: For example the ID of a chat room or a post
Expand Down Expand Up @@ -201,6 +212,7 @@ async def submit(
"content": content,
"author_id": author_id,
"channel": channel,
"client_action": client_action,
"content_id": content_id,
"conversation_id": conversation_id,
"do_not_store": do_not_store,
Expand Down
32 changes: 32 additions & 0 deletions src/moderation_api/types/content_submit_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"ContentObjectDataImage",
"ContentObjectDataVideo",
"ContentObjectDataAudio",
"ClientAction",
"Policy",
"PolicyToxicity",
"PolicyPersonalInformation",
Expand Down Expand Up @@ -69,6 +70,14 @@ class ContentSubmitParams(TypedDict, total=False):
Will use the project's default channel if not provided.
"""

client_action: Annotated[ClientAction, PropertyInfo(alias="clientAction")]
"""A recommendation from your own client-side flagging (e.g.

a banned-IP list or a third-party tool). Feeds the rules engine and can escalate
or override the recommended action. Does not change whether our analysis flagged
the content.
"""

content_id: Annotated[str, PropertyInfo(alias="contentId")]
"""The unique ID of the content in your database."""

Expand Down Expand Up @@ -200,6 +209,29 @@ class ContentObject(TypedDict, total=False):
Content: TypeAlias = Union[ContentText, ContentImage, ContentVideo, ContentAudio, ContentObject]


class ClientAction(TypedDict, total=False):
"""A recommendation from your own client-side flagging (e.g.

a banned-IP list or a third-party tool). Feeds the rules engine and can escalate or override the recommended action. Does not change whether our analysis flagged the content.
"""

action: Required[Literal["review", "allow", "reject"]]
"""Your recommendation for the content: allow, review, or reject."""

behavior: Literal["override", "escalate"]
"""How your recommendation combines with ours.

Defaults to 'escalate', which only applies it when stricter than ours;
'override' replaces ours outright.
"""

reason: str
"""A human-readable explanation for your recommendation."""

source: str
"""Where your recommendation came from, e.g. "banned-ip"."""


class PolicyToxicity(TypedDict, total=False):
id: Required[Literal["toxicity"]]

Expand Down
1 change: 1 addition & 0 deletions src/moderation_api/types/content_submit_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ class Recommendation(BaseModel):
"rule_match",
"rule_default",
"rule_fallback",
"client_override",
]
]
"""The reason code for the recommendation.
Expand Down
12 changes: 12 additions & 0 deletions tests/api_resources/test_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ def test_method_submit_with_all_params(self, client: ModerationAPI) -> None:
},
author_id="authorId",
channel="channel",
client_action={
"action": "review",
"behavior": "override",
"reason": "reason",
"source": "source",
},
content_id="contentId",
conversation_id="conversationId",
do_not_store=True,
Expand Down Expand Up @@ -113,6 +119,12 @@ async def test_method_submit_with_all_params(self, async_client: AsyncModeration
},
author_id="authorId",
channel="channel",
client_action={
"action": "review",
"behavior": "override",
"reason": "reason",
"source": "source",
},
content_id="contentId",
conversation_id="conversationId",
do_not_store=True,
Expand Down
Loading