archastro.platform.v1.resources.notifications

  1# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License.
  2# This file is auto-generated by @archastro/sdk-generator. Do not edit.
  3# Content hash: 253a531b0f1b
  4
  5from __future__ import annotations
  6
  7from datetime import datetime
  8from typing import Any, Required, TypedDict
  9
 10from pydantic import BaseModel, Field
 11
 12from ...runtime.http_client import HttpClient, SyncHttpClient
 13from ...types.notifications import Notification
 14
 15
 16class NotificationSendInput(TypedDict, total=False):
 17    "Send a custom notification to a user"
 18
 19    data: dict[str, Any] | None
 20    "Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted."
 21    idempotency_key: str | None
 22    "Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app."
 23    message: str | None
 24    "Source message (`msg_...`) that the sender and the recipient must both be able to read."
 25    thread: str | None
 26    "Thread (`thr_...`) of the source message. Requires `message`."
 27    type: Required[str]
 28    'Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app\'s bundle.'
 29    user: Required[str]
 30    "Recipient user ID (`usr_...`). Must be a member of the calling app's tenant."
 31
 32
 33class NotificationListResponseDataItem(BaseModel):
 34    archived_at: datetime | None = Field(
 35        default=None,
 36        description="When the recipient archived this notification. `null` if the notification has not been archived.",
 37    )
 38    created_at: datetime = Field(..., description="When the notification was sent (ISO 8601).")
 39    id: str = Field(..., description="Notification ID (`ntf_...`).")
 40    read_at: datetime | None = Field(
 41        default=None,
 42        description="When the recipient marked this notification read. `null` if the notification has not been read.",
 43    )
 44    rendered: dict[str, Any] = Field(
 45        ...,
 46        description='Type-specific render spec resolved at request time. All types include `title`, `kind`, and `actions`; custom types may add their own keys. Notifications whose type is no longer registered render with `kind: "unknown"`.',
 47    )
 48    status: str = Field(
 49        ...,
 50        description='Current read state of the notification. One of `"unread"`, `"read"`, or `"archived"`.',
 51    )
 52    type: str = Field(
 53        ...,
 54        description='Notification type slug, e.g. `"app_info"` for a built-in type or `"custom:deploy_complete"` for a custom type.',
 55    )
 56
 57
 58class NotificationListResponse(BaseModel):
 59    """
 60    Successful response
 61    """
 62
 63    after_cursor: str | None = Field(
 64        default=None,
 65        description="Opaque cursor to pass as `after_cursor` on the next request to fetch older notifications. `null` when this is the last page.",
 66    )
 67    before_cursor: str | None = Field(
 68        default=None,
 69        description="Always `null` inbox pagination is forward-only and does not support fetching newer pages via cursor.",
 70    )
 71    data: list[NotificationListResponseDataItem] = Field(
 72        ..., description="Array of notification objects for the current page, ordered newest first."
 73    )
 74    has_more: bool = Field(
 75        ...,
 76        description="`true` if additional (older) notifications exist beyond this page; `false` if this is the last page.",
 77    )
 78
 79
 80class NotificationUnreadCountResponse(BaseModel):
 81    """
 82    Successful response
 83    """
 84
 85    count: int = Field(
 86        ...,
 87        description='Total number of notifications with `"unread"` status belonging to the authenticated user.',
 88    )
 89
 90
 91class AsyncNotificationResource:
 92    def __init__(self, http: HttpClient):
 93        self._http = http
 94
 95    async def list(
 96        self,
 97        *,
 98        status: str | None = None,
 99        limit: int | None = None,
100        after_cursor: str | None = None,
101    ) -> NotificationListResponse:
102        """
103        List a user's notifications
104        Returns a cursor-paginated list of inbox notifications for the authenticated
105        user, ordered by creation time descending (newest first). All status groups
106        are included by default; pass `status` to narrow results to a specific group.
107        Each notification's `rendered` field contains type-specific display data
108        resolved at request time. Notifications whose type is no longer registered
109        in the platform are rendered with `kind: "unknown"` rather than being omitted.
110        Pagination is forward-only: supply `after_cursor` from a previous response to
111        fetch the next (older) page. The `before_cursor` field is always `null` for
112        this endpoint. Requires an app-scoped token.
113
114        Args:
115            status: Filter by notification status. One of `"all"`, `"active"`, `"unread"`, `"read"`, or `"archived"`. Defaults to `"all"` when omitted.
116            limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
117            after_cursor: Opaque pagination cursor from a previous response's `after_cursor` field. Omit to fetch the most recent notifications.
118
119        Returns:
120            Successful response
121        """
122        query: dict[str, object] = {}
123        if status is not None:
124            query["status"] = status
125        if limit is not None:
126            query["limit"] = limit
127        if after_cursor is not None:
128            query["after_cursor"] = after_cursor
129        return await self._http.request(
130            "/api/v1/notifications",
131            query=query,
132            response_type=NotificationListResponse,
133        )
134
135    async def read_all(self) -> None:
136        """
137        Mark all notifications as read
138        Marks every `"unread"` notification belonging to the authenticated user as
139        `"read"` in a single operation. Notifications that are already `"read"` or
140        `"archived"` are not affected.
141        This call is safe to retry if there are no unread notifications, it
142        succeeds without error. Requires an app-scoped token. Returns 204 No Content
143        on success.
144
145        Returns:
146            No content
147        """
148        await self._http.request("/api/v1/notifications/read_all", method="POST")
149
150    async def send(self, input: NotificationSendInput) -> Notification:
151        """
152        Send a custom notification to a user
153        Delivers a custom-typed notification to one of the calling app's users.
154        Apps define notification types by declaring `NotificationType` config objects
155        in their bundle (one per `lookup_key`). Supply the type as
156        `"custom:<lookup_key>"` and provide a `data` map that is merged with
157        platform-provided context to render the notification's display fields.
158        Only app-scoped tokens may call this endpoint user tokens are rejected with
159        403. The app scope is stamped onto the notification automatically; an app
160        cannot target recipients outside its tenant. Built-in platform types such as
161        `"app_info"` and `"billing_alert"` are not accepted here.
162        The `notifications.send` script binding also accepts the viewer a script runs
163        as: a user, an agent, or a team's system viewer. Such a sender may notify only
164        a user it can see in its own organization and sandbox. When the sender is a
165        user, the recipient must also be able to see the sender. An agent cannot see
166        user records, so an agent sender must name a source message: it may then
167        notify a user in its own organization and sandbox who can read that message.
168        Pass `thread` and `message` together to name the message the notification is
169        about. The send is then refused unless that message is in that thread and both
170        the sender and the recipient can read it, so a notification cannot quote a
171        message its recipient cannot open.
172        Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice
173        with the same `idempotency_key` for the same recipient, the second call
174        returns the original notification without creating a duplicate. The key is
175        scoped to the calling app, so the same raw key used by different apps cannot
176        collide.
177
178        Args:
179            input: Request body.
180            input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
181            input.idempotency_key: Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
182            input.message: Source message (`msg_...`) that the sender and the recipient must both be able to read.
183            input.thread: Thread (`thr_...`) of the source message. Requires `message`.
184            input.type: Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app's bundle.
185            input.user: Recipient user ID (`usr_...`). Must be a member of the calling app's tenant.
186
187        Returns:
188            The created notification, or the existing notification when deduplicated by `idempotency_key`.
189        """
190        return await self._http.request(
191            "/api/v1/notifications/send",
192            method="POST",
193            body=input,
194            response_type=Notification,
195        )
196
197    async def unread_count(self) -> NotificationUnreadCountResponse:
198        """
199        Get the unread notification count
200        Returns the total number of `"unread"` notifications for the authenticated
201        user. Useful for displaying a badge or indicator in your UI without
202        fetching the full notification list.
203        Notifications with `"read"` or `"archived"` status are not included in the
204        count. Requires an app-scoped token.
205
206        Returns:
207            Successful response
208        """
209        return await self._http.request(
210            "/api/v1/notifications/unread_count",
211            response_type=NotificationUnreadCountResponse,
212        )
213
214    async def archive(self, notification: str) -> None:
215        """
216        Archive a notification
217        Moves a notification to `"archived"` status regardless of whether it is
218        currently `"unread"` or `"read"`. Archived notifications are excluded from
219        the default inbox view but remain retrievable by passing `status: "archived"`
220        to the list endpoint.
221        The authenticated user must own the notification. Passing a notification ID
222        that belongs to a different user returns a 404. If the notification is
223        already archived this call succeeds without error (idempotent).
224        Requires an app-scoped token. Returns 204 No Content on success.
225
226        Args:
227            notification: Notification ID (`ntf_...`) to archive. Must belong to the authenticated user.
228
229        Returns:
230            No content
231        """
232        await self._http.request(f"/api/v1/notifications/{notification}/archive", method="POST")
233
234    async def read(self, notification: str) -> None:
235        """
236        Mark a notification as read
237        Transitions a notification from `"unread"` to `"read"` status. If the
238        notification is already `"read"` or `"archived"`, the call succeeds without
239        changing its status (idempotent).
240        The authenticated user must own the notification. Passing a notification ID
241        that belongs to a different user returns a 404. Requires an app-scoped token.
242        Returns 204 No Content on success.
243
244        Args:
245            notification: Notification ID (`ntf_...`) to mark as read. Must belong to the authenticated user.
246
247        Returns:
248            No content
249        """
250        await self._http.request(f"/api/v1/notifications/{notification}/read", method="POST")
251
252    async def unarchive(self, notification: str) -> None:
253        """
254        Unarchive a notification
255        Restores an `"archived"` notification to its previous active status:
256        `"read"` if the notification had been read before archiving, or `"unread"`
257        otherwise. The notification will appear again in the default inbox view.
258        The authenticated user must own the notification. Passing a notification ID
259        that belongs to a different user returns a 404. If the notification is not
260        currently archived this call succeeds without changing its status (idempotent).
261        Requires an app-scoped token. Returns 204 No Content on success.
262
263        Args:
264            notification: Notification ID (`ntf_...`) to unarchive. Must belong to the authenticated user.
265
266        Returns:
267            No content
268        """
269        await self._http.request(f"/api/v1/notifications/{notification}/unarchive", method="POST")
270
271
272class NotificationResource:
273    def __init__(self, http: SyncHttpClient):
274        self._http = http
275
276    def list(
277        self,
278        *,
279        status: str | None = None,
280        limit: int | None = None,
281        after_cursor: str | None = None,
282    ) -> NotificationListResponse:
283        """
284        List a user's notifications
285        Returns a cursor-paginated list of inbox notifications for the authenticated
286        user, ordered by creation time descending (newest first). All status groups
287        are included by default; pass `status` to narrow results to a specific group.
288        Each notification's `rendered` field contains type-specific display data
289        resolved at request time. Notifications whose type is no longer registered
290        in the platform are rendered with `kind: "unknown"` rather than being omitted.
291        Pagination is forward-only: supply `after_cursor` from a previous response to
292        fetch the next (older) page. The `before_cursor` field is always `null` for
293        this endpoint. Requires an app-scoped token.
294
295        Args:
296            status: Filter by notification status. One of `"all"`, `"active"`, `"unread"`, `"read"`, or `"archived"`. Defaults to `"all"` when omitted.
297            limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
298            after_cursor: Opaque pagination cursor from a previous response's `after_cursor` field. Omit to fetch the most recent notifications.
299
300        Returns:
301            Successful response
302        """
303        query: dict[str, object] = {}
304        if status is not None:
305            query["status"] = status
306        if limit is not None:
307            query["limit"] = limit
308        if after_cursor is not None:
309            query["after_cursor"] = after_cursor
310        return self._http.request(
311            "/api/v1/notifications",
312            query=query,
313            response_type=NotificationListResponse,
314        )
315
316    def read_all(self) -> None:
317        """
318        Mark all notifications as read
319        Marks every `"unread"` notification belonging to the authenticated user as
320        `"read"` in a single operation. Notifications that are already `"read"` or
321        `"archived"` are not affected.
322        This call is safe to retry if there are no unread notifications, it
323        succeeds without error. Requires an app-scoped token. Returns 204 No Content
324        on success.
325
326        Returns:
327            No content
328        """
329        self._http.request("/api/v1/notifications/read_all", method="POST")
330
331    def send(self, input: NotificationSendInput) -> Notification:
332        """
333        Send a custom notification to a user
334        Delivers a custom-typed notification to one of the calling app's users.
335        Apps define notification types by declaring `NotificationType` config objects
336        in their bundle (one per `lookup_key`). Supply the type as
337        `"custom:<lookup_key>"` and provide a `data` map that is merged with
338        platform-provided context to render the notification's display fields.
339        Only app-scoped tokens may call this endpoint user tokens are rejected with
340        403. The app scope is stamped onto the notification automatically; an app
341        cannot target recipients outside its tenant. Built-in platform types such as
342        `"app_info"` and `"billing_alert"` are not accepted here.
343        The `notifications.send` script binding also accepts the viewer a script runs
344        as: a user, an agent, or a team's system viewer. Such a sender may notify only
345        a user it can see in its own organization and sandbox. When the sender is a
346        user, the recipient must also be able to see the sender. An agent cannot see
347        user records, so an agent sender must name a source message: it may then
348        notify a user in its own organization and sandbox who can read that message.
349        Pass `thread` and `message` together to name the message the notification is
350        about. The send is then refused unless that message is in that thread and both
351        the sender and the recipient can read it, so a notification cannot quote a
352        message its recipient cannot open.
353        Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice
354        with the same `idempotency_key` for the same recipient, the second call
355        returns the original notification without creating a duplicate. The key is
356        scoped to the calling app, so the same raw key used by different apps cannot
357        collide.
358
359        Args:
360            input: Request body.
361            input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
362            input.idempotency_key: Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
363            input.message: Source message (`msg_...`) that the sender and the recipient must both be able to read.
364            input.thread: Thread (`thr_...`) of the source message. Requires `message`.
365            input.type: Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app's bundle.
366            input.user: Recipient user ID (`usr_...`). Must be a member of the calling app's tenant.
367
368        Returns:
369            The created notification, or the existing notification when deduplicated by `idempotency_key`.
370        """
371        return self._http.request(
372            "/api/v1/notifications/send",
373            method="POST",
374            body=input,
375            response_type=Notification,
376        )
377
378    def unread_count(self) -> NotificationUnreadCountResponse:
379        """
380        Get the unread notification count
381        Returns the total number of `"unread"` notifications for the authenticated
382        user. Useful for displaying a badge or indicator in your UI without
383        fetching the full notification list.
384        Notifications with `"read"` or `"archived"` status are not included in the
385        count. Requires an app-scoped token.
386
387        Returns:
388            Successful response
389        """
390        return self._http.request(
391            "/api/v1/notifications/unread_count",
392            response_type=NotificationUnreadCountResponse,
393        )
394
395    def archive(self, notification: str) -> None:
396        """
397        Archive a notification
398        Moves a notification to `"archived"` status regardless of whether it is
399        currently `"unread"` or `"read"`. Archived notifications are excluded from
400        the default inbox view but remain retrievable by passing `status: "archived"`
401        to the list endpoint.
402        The authenticated user must own the notification. Passing a notification ID
403        that belongs to a different user returns a 404. If the notification is
404        already archived this call succeeds without error (idempotent).
405        Requires an app-scoped token. Returns 204 No Content on success.
406
407        Args:
408            notification: Notification ID (`ntf_...`) to archive. Must belong to the authenticated user.
409
410        Returns:
411            No content
412        """
413        self._http.request(f"/api/v1/notifications/{notification}/archive", method="POST")
414
415    def read(self, notification: str) -> None:
416        """
417        Mark a notification as read
418        Transitions a notification from `"unread"` to `"read"` status. If the
419        notification is already `"read"` or `"archived"`, the call succeeds without
420        changing its status (idempotent).
421        The authenticated user must own the notification. Passing a notification ID
422        that belongs to a different user returns a 404. Requires an app-scoped token.
423        Returns 204 No Content on success.
424
425        Args:
426            notification: Notification ID (`ntf_...`) to mark as read. Must belong to the authenticated user.
427
428        Returns:
429            No content
430        """
431        self._http.request(f"/api/v1/notifications/{notification}/read", method="POST")
432
433    def unarchive(self, notification: str) -> None:
434        """
435        Unarchive a notification
436        Restores an `"archived"` notification to its previous active status:
437        `"read"` if the notification had been read before archiving, or `"unread"`
438        otherwise. The notification will appear again in the default inbox view.
439        The authenticated user must own the notification. Passing a notification ID
440        that belongs to a different user returns a 404. If the notification is not
441        currently archived this call succeeds without changing its status (idempotent).
442        Requires an app-scoped token. Returns 204 No Content on success.
443
444        Args:
445            notification: Notification ID (`ntf_...`) to unarchive. Must belong to the authenticated user.
446
447        Returns:
448            No content
449        """
450        self._http.request(f"/api/v1/notifications/{notification}/unarchive", method="POST")
class NotificationSendInput(typing.TypedDict):
17class NotificationSendInput(TypedDict, total=False):
18    "Send a custom notification to a user"
19
20    data: dict[str, Any] | None
21    "Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted."
22    idempotency_key: str | None
23    "Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app."
24    message: str | None
25    "Source message (`msg_...`) that the sender and the recipient must both be able to read."
26    thread: str | None
27    "Thread (`thr_...`) of the source message. Requires `message`."
28    type: Required[str]
29    'Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app\'s bundle.'
30    user: Required[str]
31    "Recipient user ID (`usr_...`). Must be a member of the calling app's tenant."

Send a custom notification to a user

data: dict[str, typing.Any] | None

Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.

idempotency_key: str | None

Optional deduplication key. A second call with the same idempotency_key for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.

message: str | None

Source message (msg_...) that the sender and the recipient must both be able to read.

thread: str | None

Thread (thr_...) of the source message. Requires message.

type: Required[str]

Custom notification type identifier in the form "custom:<lookup_key>", where <lookup_key> matches a NotificationType config declared in the calling app's bundle.

user: Required[str]

Recipient user ID (usr_...). Must be a member of the calling app's tenant.

class NotificationListResponseDataItem(pydantic.main.BaseModel):
34class NotificationListResponseDataItem(BaseModel):
35    archived_at: datetime | None = Field(
36        default=None,
37        description="When the recipient archived this notification. `null` if the notification has not been archived.",
38    )
39    created_at: datetime = Field(..., description="When the notification was sent (ISO 8601).")
40    id: str = Field(..., description="Notification ID (`ntf_...`).")
41    read_at: datetime | None = Field(
42        default=None,
43        description="When the recipient marked this notification read. `null` if the notification has not been read.",
44    )
45    rendered: dict[str, Any] = Field(
46        ...,
47        description='Type-specific render spec resolved at request time. All types include `title`, `kind`, and `actions`; custom types may add their own keys. Notifications whose type is no longer registered render with `kind: "unknown"`.',
48    )
49    status: str = Field(
50        ...,
51        description='Current read state of the notification. One of `"unread"`, `"read"`, or `"archived"`.',
52    )
53    type: str = Field(
54        ...,
55        description='Notification type slug, e.g. `"app_info"` for a built-in type or `"custom:deploy_complete"` for a custom type.',
56    )

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes:
  • __class_vars__: The names of the class variables defined on the model.
  • __private_attributes__: Metadata about the private attributes of the model.
  • __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.
  • __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
  • __pydantic_core_schema__: The core schema of the model.
  • __pydantic_custom_init__: Whether the model has a custom __init__ function.
  • __pydantic_decorators__: Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item maps to the __parameter__ attribute of generic classes.
  • __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
  • __pydantic_post_init__: The name of the post-init method for the model, if defined.
  • __pydantic_root_model__: Whether the model is a [RootModel][pydantic.root_model.RootModel].
  • __pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
  • __pydantic_fields__: A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
  • __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
  • __pydantic_extra__: A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
  • __pydantic_fields_set__: The names of fields explicitly set during instantiation.
  • __pydantic_private__: Values of private attributes set on the model instance.
archived_at: datetime.datetime | None = None

When the recipient archived this notification. null if the notification has not been archived.

created_at: datetime.datetime = PydanticUndefined

When the notification was sent (ISO 8601).

id: str = PydanticUndefined

Notification ID (ntf_...).

read_at: datetime.datetime | None = None

When the recipient marked this notification read. null if the notification has not been read.

rendered: dict[str, typing.Any] = PydanticUndefined

Type-specific render spec resolved at request time. All types include title, kind, and actions; custom types may add their own keys. Notifications whose type is no longer registered render with kind: "unknown".

status: str = PydanticUndefined

Current read state of the notification. One of "unread", "read", or "archived".

type: str = PydanticUndefined

Notification type slug, e.g. "app_info" for a built-in type or "custom:deploy_complete" for a custom type.

class NotificationListResponse(pydantic.main.BaseModel):
59class NotificationListResponse(BaseModel):
60    """
61    Successful response
62    """
63
64    after_cursor: str | None = Field(
65        default=None,
66        description="Opaque cursor to pass as `after_cursor` on the next request to fetch older notifications. `null` when this is the last page.",
67    )
68    before_cursor: str | None = Field(
69        default=None,
70        description="Always `null` inbox pagination is forward-only and does not support fetching newer pages via cursor.",
71    )
72    data: list[NotificationListResponseDataItem] = Field(
73        ..., description="Array of notification objects for the current page, ordered newest first."
74    )
75    has_more: bool = Field(
76        ...,
77        description="`true` if additional (older) notifications exist beyond this page; `false` if this is the last page.",
78    )

Successful response

after_cursor: str | None = None

Opaque cursor to pass as after_cursor on the next request to fetch older notifications. null when this is the last page.

before_cursor: str | None = None

Always null inbox pagination is forward-only and does not support fetching newer pages via cursor.

data: list[NotificationListResponseDataItem] = PydanticUndefined

Array of notification objects for the current page, ordered newest first.

has_more: bool = PydanticUndefined

true if additional (older) notifications exist beyond this page; false if this is the last page.

class NotificationUnreadCountResponse(pydantic.main.BaseModel):
81class NotificationUnreadCountResponse(BaseModel):
82    """
83    Successful response
84    """
85
86    count: int = Field(
87        ...,
88        description='Total number of notifications with `"unread"` status belonging to the authenticated user.',
89    )

Successful response

count: int = PydanticUndefined

Total number of notifications with "unread" status belonging to the authenticated user.

class AsyncNotificationResource:
 92class AsyncNotificationResource:
 93    def __init__(self, http: HttpClient):
 94        self._http = http
 95
 96    async def list(
 97        self,
 98        *,
 99        status: str | None = None,
100        limit: int | None = None,
101        after_cursor: str | None = None,
102    ) -> NotificationListResponse:
103        """
104        List a user's notifications
105        Returns a cursor-paginated list of inbox notifications for the authenticated
106        user, ordered by creation time descending (newest first). All status groups
107        are included by default; pass `status` to narrow results to a specific group.
108        Each notification's `rendered` field contains type-specific display data
109        resolved at request time. Notifications whose type is no longer registered
110        in the platform are rendered with `kind: "unknown"` rather than being omitted.
111        Pagination is forward-only: supply `after_cursor` from a previous response to
112        fetch the next (older) page. The `before_cursor` field is always `null` for
113        this endpoint. Requires an app-scoped token.
114
115        Args:
116            status: Filter by notification status. One of `"all"`, `"active"`, `"unread"`, `"read"`, or `"archived"`. Defaults to `"all"` when omitted.
117            limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
118            after_cursor: Opaque pagination cursor from a previous response's `after_cursor` field. Omit to fetch the most recent notifications.
119
120        Returns:
121            Successful response
122        """
123        query: dict[str, object] = {}
124        if status is not None:
125            query["status"] = status
126        if limit is not None:
127            query["limit"] = limit
128        if after_cursor is not None:
129            query["after_cursor"] = after_cursor
130        return await self._http.request(
131            "/api/v1/notifications",
132            query=query,
133            response_type=NotificationListResponse,
134        )
135
136    async def read_all(self) -> None:
137        """
138        Mark all notifications as read
139        Marks every `"unread"` notification belonging to the authenticated user as
140        `"read"` in a single operation. Notifications that are already `"read"` or
141        `"archived"` are not affected.
142        This call is safe to retry if there are no unread notifications, it
143        succeeds without error. Requires an app-scoped token. Returns 204 No Content
144        on success.
145
146        Returns:
147            No content
148        """
149        await self._http.request("/api/v1/notifications/read_all", method="POST")
150
151    async def send(self, input: NotificationSendInput) -> Notification:
152        """
153        Send a custom notification to a user
154        Delivers a custom-typed notification to one of the calling app's users.
155        Apps define notification types by declaring `NotificationType` config objects
156        in their bundle (one per `lookup_key`). Supply the type as
157        `"custom:<lookup_key>"` and provide a `data` map that is merged with
158        platform-provided context to render the notification's display fields.
159        Only app-scoped tokens may call this endpoint user tokens are rejected with
160        403. The app scope is stamped onto the notification automatically; an app
161        cannot target recipients outside its tenant. Built-in platform types such as
162        `"app_info"` and `"billing_alert"` are not accepted here.
163        The `notifications.send` script binding also accepts the viewer a script runs
164        as: a user, an agent, or a team's system viewer. Such a sender may notify only
165        a user it can see in its own organization and sandbox. When the sender is a
166        user, the recipient must also be able to see the sender. An agent cannot see
167        user records, so an agent sender must name a source message: it may then
168        notify a user in its own organization and sandbox who can read that message.
169        Pass `thread` and `message` together to name the message the notification is
170        about. The send is then refused unless that message is in that thread and both
171        the sender and the recipient can read it, so a notification cannot quote a
172        message its recipient cannot open.
173        Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice
174        with the same `idempotency_key` for the same recipient, the second call
175        returns the original notification without creating a duplicate. The key is
176        scoped to the calling app, so the same raw key used by different apps cannot
177        collide.
178
179        Args:
180            input: Request body.
181            input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
182            input.idempotency_key: Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
183            input.message: Source message (`msg_...`) that the sender and the recipient must both be able to read.
184            input.thread: Thread (`thr_...`) of the source message. Requires `message`.
185            input.type: Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app's bundle.
186            input.user: Recipient user ID (`usr_...`). Must be a member of the calling app's tenant.
187
188        Returns:
189            The created notification, or the existing notification when deduplicated by `idempotency_key`.
190        """
191        return await self._http.request(
192            "/api/v1/notifications/send",
193            method="POST",
194            body=input,
195            response_type=Notification,
196        )
197
198    async def unread_count(self) -> NotificationUnreadCountResponse:
199        """
200        Get the unread notification count
201        Returns the total number of `"unread"` notifications for the authenticated
202        user. Useful for displaying a badge or indicator in your UI without
203        fetching the full notification list.
204        Notifications with `"read"` or `"archived"` status are not included in the
205        count. Requires an app-scoped token.
206
207        Returns:
208            Successful response
209        """
210        return await self._http.request(
211            "/api/v1/notifications/unread_count",
212            response_type=NotificationUnreadCountResponse,
213        )
214
215    async def archive(self, notification: str) -> None:
216        """
217        Archive a notification
218        Moves a notification to `"archived"` status regardless of whether it is
219        currently `"unread"` or `"read"`. Archived notifications are excluded from
220        the default inbox view but remain retrievable by passing `status: "archived"`
221        to the list endpoint.
222        The authenticated user must own the notification. Passing a notification ID
223        that belongs to a different user returns a 404. If the notification is
224        already archived this call succeeds without error (idempotent).
225        Requires an app-scoped token. Returns 204 No Content on success.
226
227        Args:
228            notification: Notification ID (`ntf_...`) to archive. Must belong to the authenticated user.
229
230        Returns:
231            No content
232        """
233        await self._http.request(f"/api/v1/notifications/{notification}/archive", method="POST")
234
235    async def read(self, notification: str) -> None:
236        """
237        Mark a notification as read
238        Transitions a notification from `"unread"` to `"read"` status. If the
239        notification is already `"read"` or `"archived"`, the call succeeds without
240        changing its status (idempotent).
241        The authenticated user must own the notification. Passing a notification ID
242        that belongs to a different user returns a 404. Requires an app-scoped token.
243        Returns 204 No Content on success.
244
245        Args:
246            notification: Notification ID (`ntf_...`) to mark as read. Must belong to the authenticated user.
247
248        Returns:
249            No content
250        """
251        await self._http.request(f"/api/v1/notifications/{notification}/read", method="POST")
252
253    async def unarchive(self, notification: str) -> None:
254        """
255        Unarchive a notification
256        Restores an `"archived"` notification to its previous active status:
257        `"read"` if the notification had been read before archiving, or `"unread"`
258        otherwise. The notification will appear again in the default inbox view.
259        The authenticated user must own the notification. Passing a notification ID
260        that belongs to a different user returns a 404. If the notification is not
261        currently archived this call succeeds without changing its status (idempotent).
262        Requires an app-scoped token. Returns 204 No Content on success.
263
264        Args:
265            notification: Notification ID (`ntf_...`) to unarchive. Must belong to the authenticated user.
266
267        Returns:
268            No content
269        """
270        await self._http.request(f"/api/v1/notifications/{notification}/unarchive", method="POST")
AsyncNotificationResource(http: archastro.platform.runtime.http_client.HttpClient)
93    def __init__(self, http: HttpClient):
94        self._http = http
async def list( self, *, status: str | None = None, limit: int | None = None, after_cursor: str | None = None) -> NotificationListResponse:
 96    async def list(
 97        self,
 98        *,
 99        status: str | None = None,
100        limit: int | None = None,
101        after_cursor: str | None = None,
102    ) -> NotificationListResponse:
103        """
104        List a user's notifications
105        Returns a cursor-paginated list of inbox notifications for the authenticated
106        user, ordered by creation time descending (newest first). All status groups
107        are included by default; pass `status` to narrow results to a specific group.
108        Each notification's `rendered` field contains type-specific display data
109        resolved at request time. Notifications whose type is no longer registered
110        in the platform are rendered with `kind: "unknown"` rather than being omitted.
111        Pagination is forward-only: supply `after_cursor` from a previous response to
112        fetch the next (older) page. The `before_cursor` field is always `null` for
113        this endpoint. Requires an app-scoped token.
114
115        Args:
116            status: Filter by notification status. One of `"all"`, `"active"`, `"unread"`, `"read"`, or `"archived"`. Defaults to `"all"` when omitted.
117            limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
118            after_cursor: Opaque pagination cursor from a previous response's `after_cursor` field. Omit to fetch the most recent notifications.
119
120        Returns:
121            Successful response
122        """
123        query: dict[str, object] = {}
124        if status is not None:
125            query["status"] = status
126        if limit is not None:
127            query["limit"] = limit
128        if after_cursor is not None:
129            query["after_cursor"] = after_cursor
130        return await self._http.request(
131            "/api/v1/notifications",
132            query=query,
133            response_type=NotificationListResponse,
134        )

List a user's notifications Returns a cursor-paginated list of inbox notifications for the authenticated user, ordered by creation time descending (newest first). All status groups are included by default; pass status to narrow results to a specific group. Each notification's rendered field contains type-specific display data resolved at request time. Notifications whose type is no longer registered in the platform are rendered with kind: "unknown" rather than being omitted. Pagination is forward-only: supply after_cursor from a previous response to fetch the next (older) page. The before_cursor field is always null for this endpoint. Requires an app-scoped token.

Arguments:
  • status: Filter by notification status. One of "all", "active", "unread", "read", or "archived". Defaults to "all" when omitted.
  • limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
  • after_cursor: Opaque pagination cursor from a previous response's after_cursor field. Omit to fetch the most recent notifications.
Returns:

Successful response

async def read_all(self) -> None:
136    async def read_all(self) -> None:
137        """
138        Mark all notifications as read
139        Marks every `"unread"` notification belonging to the authenticated user as
140        `"read"` in a single operation. Notifications that are already `"read"` or
141        `"archived"` are not affected.
142        This call is safe to retry if there are no unread notifications, it
143        succeeds without error. Requires an app-scoped token. Returns 204 No Content
144        on success.
145
146        Returns:
147            No content
148        """
149        await self._http.request("/api/v1/notifications/read_all", method="POST")

Mark all notifications as read Marks every "unread" notification belonging to the authenticated user as "read" in a single operation. Notifications that are already "read" or "archived" are not affected. This call is safe to retry if there are no unread notifications, it succeeds without error. Requires an app-scoped token. Returns 204 No Content on success.

Returns:

No content

async def send( self, input: NotificationSendInput) -> archastro.platform.types.notifications.Notification:
151    async def send(self, input: NotificationSendInput) -> Notification:
152        """
153        Send a custom notification to a user
154        Delivers a custom-typed notification to one of the calling app's users.
155        Apps define notification types by declaring `NotificationType` config objects
156        in their bundle (one per `lookup_key`). Supply the type as
157        `"custom:<lookup_key>"` and provide a `data` map that is merged with
158        platform-provided context to render the notification's display fields.
159        Only app-scoped tokens may call this endpoint user tokens are rejected with
160        403. The app scope is stamped onto the notification automatically; an app
161        cannot target recipients outside its tenant. Built-in platform types such as
162        `"app_info"` and `"billing_alert"` are not accepted here.
163        The `notifications.send` script binding also accepts the viewer a script runs
164        as: a user, an agent, or a team's system viewer. Such a sender may notify only
165        a user it can see in its own organization and sandbox. When the sender is a
166        user, the recipient must also be able to see the sender. An agent cannot see
167        user records, so an agent sender must name a source message: it may then
168        notify a user in its own organization and sandbox who can read that message.
169        Pass `thread` and `message` together to name the message the notification is
170        about. The send is then refused unless that message is in that thread and both
171        the sender and the recipient can read it, so a notification cannot quote a
172        message its recipient cannot open.
173        Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice
174        with the same `idempotency_key` for the same recipient, the second call
175        returns the original notification without creating a duplicate. The key is
176        scoped to the calling app, so the same raw key used by different apps cannot
177        collide.
178
179        Args:
180            input: Request body.
181            input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
182            input.idempotency_key: Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
183            input.message: Source message (`msg_...`) that the sender and the recipient must both be able to read.
184            input.thread: Thread (`thr_...`) of the source message. Requires `message`.
185            input.type: Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app's bundle.
186            input.user: Recipient user ID (`usr_...`). Must be a member of the calling app's tenant.
187
188        Returns:
189            The created notification, or the existing notification when deduplicated by `idempotency_key`.
190        """
191        return await self._http.request(
192            "/api/v1/notifications/send",
193            method="POST",
194            body=input,
195            response_type=Notification,
196        )

Send a custom notification to a user Delivers a custom-typed notification to one of the calling app's users. Apps define notification types by declaring NotificationType config objects in their bundle (one per lookup_key). Supply the type as "custom:<lookup_key>" and provide a data map that is merged with platform-provided context to render the notification's display fields. Only app-scoped tokens may call this endpoint user tokens are rejected with

  1. The app scope is stamped onto the notification automatically; an app cannot target recipients outside its tenant. Built-in platform types such as "app_info" and "billing_alert" are not accepted here. The notifications.send script binding also accepts the viewer a script runs as: a user, an agent, or a team's system viewer. Such a sender may notify only a user it can see in its own organization and sandbox. When the sender is a user, the recipient must also be able to see the sender. An agent cannot see user records, so an agent sender must name a source message: it may then notify a user in its own organization and sandbox who can read that message. Pass thread and message together to name the message the notification is about. The send is then refused unless that message is in that thread and both the sender and the recipient can read it, so a notification cannot quote a message its recipient cannot open. Pass idempotency_key to deduplicate sends. If you call this endpoint twice with the same idempotency_key for the same recipient, the second call returns the original notification without creating a duplicate. The key is scoped to the calling app, so the same raw key used by different apps cannot collide.
Arguments:
  • input: Request body.
  • input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
  • input.idempotency_key: Optional deduplication key. A second call with the same idempotency_key for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
  • input.message: Source message (msg_...) that the sender and the recipient must both be able to read.
  • input.thread: Thread (thr_...) of the source message. Requires message.
  • input.type: Custom notification type identifier in the form "custom:<lookup_key>", where <lookup_key> matches a NotificationType config declared in the calling app's bundle.
  • input.user: Recipient user ID (usr_...). Must be a member of the calling app's tenant.
Returns:

The created notification, or the existing notification when deduplicated by idempotency_key.

async def unread_count( self) -> NotificationUnreadCountResponse:
198    async def unread_count(self) -> NotificationUnreadCountResponse:
199        """
200        Get the unread notification count
201        Returns the total number of `"unread"` notifications for the authenticated
202        user. Useful for displaying a badge or indicator in your UI without
203        fetching the full notification list.
204        Notifications with `"read"` or `"archived"` status are not included in the
205        count. Requires an app-scoped token.
206
207        Returns:
208            Successful response
209        """
210        return await self._http.request(
211            "/api/v1/notifications/unread_count",
212            response_type=NotificationUnreadCountResponse,
213        )

Get the unread notification count Returns the total number of "unread" notifications for the authenticated user. Useful for displaying a badge or indicator in your UI without fetching the full notification list. Notifications with "read" or "archived" status are not included in the count. Requires an app-scoped token.

Returns:

Successful response

async def archive(self, notification: str) -> None:
215    async def archive(self, notification: str) -> None:
216        """
217        Archive a notification
218        Moves a notification to `"archived"` status regardless of whether it is
219        currently `"unread"` or `"read"`. Archived notifications are excluded from
220        the default inbox view but remain retrievable by passing `status: "archived"`
221        to the list endpoint.
222        The authenticated user must own the notification. Passing a notification ID
223        that belongs to a different user returns a 404. If the notification is
224        already archived this call succeeds without error (idempotent).
225        Requires an app-scoped token. Returns 204 No Content on success.
226
227        Args:
228            notification: Notification ID (`ntf_...`) to archive. Must belong to the authenticated user.
229
230        Returns:
231            No content
232        """
233        await self._http.request(f"/api/v1/notifications/{notification}/archive", method="POST")

Archive a notification Moves a notification to "archived" status regardless of whether it is currently "unread" or "read". Archived notifications are excluded from the default inbox view but remain retrievable by passing status: "archived" to the list endpoint. The authenticated user must own the notification. Passing a notification ID that belongs to a different user returns a 404. If the notification is already archived this call succeeds without error (idempotent). Requires an app-scoped token. Returns 204 No Content on success.

Arguments:
  • notification: Notification ID (ntf_...) to archive. Must belong to the authenticated user.
Returns:

No content

async def read(self, notification: str) -> None:
235    async def read(self, notification: str) -> None:
236        """
237        Mark a notification as read
238        Transitions a notification from `"unread"` to `"read"` status. If the
239        notification is already `"read"` or `"archived"`, the call succeeds without
240        changing its status (idempotent).
241        The authenticated user must own the notification. Passing a notification ID
242        that belongs to a different user returns a 404. Requires an app-scoped token.
243        Returns 204 No Content on success.
244
245        Args:
246            notification: Notification ID (`ntf_...`) to mark as read. Must belong to the authenticated user.
247
248        Returns:
249            No content
250        """
251        await self._http.request(f"/api/v1/notifications/{notification}/read", method="POST")

Mark a notification as read Transitions a notification from "unread" to "read" status. If the notification is already "read" or "archived", the call succeeds without changing its status (idempotent). The authenticated user must own the notification. Passing a notification ID that belongs to a different user returns a 404. Requires an app-scoped token. Returns 204 No Content on success.

Arguments:
  • notification: Notification ID (ntf_...) to mark as read. Must belong to the authenticated user.
Returns:

No content

async def unarchive(self, notification: str) -> None:
253    async def unarchive(self, notification: str) -> None:
254        """
255        Unarchive a notification
256        Restores an `"archived"` notification to its previous active status:
257        `"read"` if the notification had been read before archiving, or `"unread"`
258        otherwise. The notification will appear again in the default inbox view.
259        The authenticated user must own the notification. Passing a notification ID
260        that belongs to a different user returns a 404. If the notification is not
261        currently archived this call succeeds without changing its status (idempotent).
262        Requires an app-scoped token. Returns 204 No Content on success.
263
264        Args:
265            notification: Notification ID (`ntf_...`) to unarchive. Must belong to the authenticated user.
266
267        Returns:
268            No content
269        """
270        await self._http.request(f"/api/v1/notifications/{notification}/unarchive", method="POST")

Unarchive a notification Restores an "archived" notification to its previous active status: "read" if the notification had been read before archiving, or "unread" otherwise. The notification will appear again in the default inbox view. The authenticated user must own the notification. Passing a notification ID that belongs to a different user returns a 404. If the notification is not currently archived this call succeeds without changing its status (idempotent). Requires an app-scoped token. Returns 204 No Content on success.

Arguments:
  • notification: Notification ID (ntf_...) to unarchive. Must belong to the authenticated user.
Returns:

No content

class NotificationResource:
273class NotificationResource:
274    def __init__(self, http: SyncHttpClient):
275        self._http = http
276
277    def list(
278        self,
279        *,
280        status: str | None = None,
281        limit: int | None = None,
282        after_cursor: str | None = None,
283    ) -> NotificationListResponse:
284        """
285        List a user's notifications
286        Returns a cursor-paginated list of inbox notifications for the authenticated
287        user, ordered by creation time descending (newest first). All status groups
288        are included by default; pass `status` to narrow results to a specific group.
289        Each notification's `rendered` field contains type-specific display data
290        resolved at request time. Notifications whose type is no longer registered
291        in the platform are rendered with `kind: "unknown"` rather than being omitted.
292        Pagination is forward-only: supply `after_cursor` from a previous response to
293        fetch the next (older) page. The `before_cursor` field is always `null` for
294        this endpoint. Requires an app-scoped token.
295
296        Args:
297            status: Filter by notification status. One of `"all"`, `"active"`, `"unread"`, `"read"`, or `"archived"`. Defaults to `"all"` when omitted.
298            limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
299            after_cursor: Opaque pagination cursor from a previous response's `after_cursor` field. Omit to fetch the most recent notifications.
300
301        Returns:
302            Successful response
303        """
304        query: dict[str, object] = {}
305        if status is not None:
306            query["status"] = status
307        if limit is not None:
308            query["limit"] = limit
309        if after_cursor is not None:
310            query["after_cursor"] = after_cursor
311        return self._http.request(
312            "/api/v1/notifications",
313            query=query,
314            response_type=NotificationListResponse,
315        )
316
317    def read_all(self) -> None:
318        """
319        Mark all notifications as read
320        Marks every `"unread"` notification belonging to the authenticated user as
321        `"read"` in a single operation. Notifications that are already `"read"` or
322        `"archived"` are not affected.
323        This call is safe to retry if there are no unread notifications, it
324        succeeds without error. Requires an app-scoped token. Returns 204 No Content
325        on success.
326
327        Returns:
328            No content
329        """
330        self._http.request("/api/v1/notifications/read_all", method="POST")
331
332    def send(self, input: NotificationSendInput) -> Notification:
333        """
334        Send a custom notification to a user
335        Delivers a custom-typed notification to one of the calling app's users.
336        Apps define notification types by declaring `NotificationType` config objects
337        in their bundle (one per `lookup_key`). Supply the type as
338        `"custom:<lookup_key>"` and provide a `data` map that is merged with
339        platform-provided context to render the notification's display fields.
340        Only app-scoped tokens may call this endpoint user tokens are rejected with
341        403. The app scope is stamped onto the notification automatically; an app
342        cannot target recipients outside its tenant. Built-in platform types such as
343        `"app_info"` and `"billing_alert"` are not accepted here.
344        The `notifications.send` script binding also accepts the viewer a script runs
345        as: a user, an agent, or a team's system viewer. Such a sender may notify only
346        a user it can see in its own organization and sandbox. When the sender is a
347        user, the recipient must also be able to see the sender. An agent cannot see
348        user records, so an agent sender must name a source message: it may then
349        notify a user in its own organization and sandbox who can read that message.
350        Pass `thread` and `message` together to name the message the notification is
351        about. The send is then refused unless that message is in that thread and both
352        the sender and the recipient can read it, so a notification cannot quote a
353        message its recipient cannot open.
354        Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice
355        with the same `idempotency_key` for the same recipient, the second call
356        returns the original notification without creating a duplicate. The key is
357        scoped to the calling app, so the same raw key used by different apps cannot
358        collide.
359
360        Args:
361            input: Request body.
362            input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
363            input.idempotency_key: Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
364            input.message: Source message (`msg_...`) that the sender and the recipient must both be able to read.
365            input.thread: Thread (`thr_...`) of the source message. Requires `message`.
366            input.type: Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app's bundle.
367            input.user: Recipient user ID (`usr_...`). Must be a member of the calling app's tenant.
368
369        Returns:
370            The created notification, or the existing notification when deduplicated by `idempotency_key`.
371        """
372        return self._http.request(
373            "/api/v1/notifications/send",
374            method="POST",
375            body=input,
376            response_type=Notification,
377        )
378
379    def unread_count(self) -> NotificationUnreadCountResponse:
380        """
381        Get the unread notification count
382        Returns the total number of `"unread"` notifications for the authenticated
383        user. Useful for displaying a badge or indicator in your UI without
384        fetching the full notification list.
385        Notifications with `"read"` or `"archived"` status are not included in the
386        count. Requires an app-scoped token.
387
388        Returns:
389            Successful response
390        """
391        return self._http.request(
392            "/api/v1/notifications/unread_count",
393            response_type=NotificationUnreadCountResponse,
394        )
395
396    def archive(self, notification: str) -> None:
397        """
398        Archive a notification
399        Moves a notification to `"archived"` status regardless of whether it is
400        currently `"unread"` or `"read"`. Archived notifications are excluded from
401        the default inbox view but remain retrievable by passing `status: "archived"`
402        to the list endpoint.
403        The authenticated user must own the notification. Passing a notification ID
404        that belongs to a different user returns a 404. If the notification is
405        already archived this call succeeds without error (idempotent).
406        Requires an app-scoped token. Returns 204 No Content on success.
407
408        Args:
409            notification: Notification ID (`ntf_...`) to archive. Must belong to the authenticated user.
410
411        Returns:
412            No content
413        """
414        self._http.request(f"/api/v1/notifications/{notification}/archive", method="POST")
415
416    def read(self, notification: str) -> None:
417        """
418        Mark a notification as read
419        Transitions a notification from `"unread"` to `"read"` status. If the
420        notification is already `"read"` or `"archived"`, the call succeeds without
421        changing its status (idempotent).
422        The authenticated user must own the notification. Passing a notification ID
423        that belongs to a different user returns a 404. Requires an app-scoped token.
424        Returns 204 No Content on success.
425
426        Args:
427            notification: Notification ID (`ntf_...`) to mark as read. Must belong to the authenticated user.
428
429        Returns:
430            No content
431        """
432        self._http.request(f"/api/v1/notifications/{notification}/read", method="POST")
433
434    def unarchive(self, notification: str) -> None:
435        """
436        Unarchive a notification
437        Restores an `"archived"` notification to its previous active status:
438        `"read"` if the notification had been read before archiving, or `"unread"`
439        otherwise. The notification will appear again in the default inbox view.
440        The authenticated user must own the notification. Passing a notification ID
441        that belongs to a different user returns a 404. If the notification is not
442        currently archived this call succeeds without changing its status (idempotent).
443        Requires an app-scoped token. Returns 204 No Content on success.
444
445        Args:
446            notification: Notification ID (`ntf_...`) to unarchive. Must belong to the authenticated user.
447
448        Returns:
449            No content
450        """
451        self._http.request(f"/api/v1/notifications/{notification}/unarchive", method="POST")
NotificationResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
274    def __init__(self, http: SyncHttpClient):
275        self._http = http
def list( self, *, status: str | None = None, limit: int | None = None, after_cursor: str | None = None) -> NotificationListResponse:
277    def list(
278        self,
279        *,
280        status: str | None = None,
281        limit: int | None = None,
282        after_cursor: str | None = None,
283    ) -> NotificationListResponse:
284        """
285        List a user's notifications
286        Returns a cursor-paginated list of inbox notifications for the authenticated
287        user, ordered by creation time descending (newest first). All status groups
288        are included by default; pass `status` to narrow results to a specific group.
289        Each notification's `rendered` field contains type-specific display data
290        resolved at request time. Notifications whose type is no longer registered
291        in the platform are rendered with `kind: "unknown"` rather than being omitted.
292        Pagination is forward-only: supply `after_cursor` from a previous response to
293        fetch the next (older) page. The `before_cursor` field is always `null` for
294        this endpoint. Requires an app-scoped token.
295
296        Args:
297            status: Filter by notification status. One of `"all"`, `"active"`, `"unread"`, `"read"`, or `"archived"`. Defaults to `"all"` when omitted.
298            limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
299            after_cursor: Opaque pagination cursor from a previous response's `after_cursor` field. Omit to fetch the most recent notifications.
300
301        Returns:
302            Successful response
303        """
304        query: dict[str, object] = {}
305        if status is not None:
306            query["status"] = status
307        if limit is not None:
308            query["limit"] = limit
309        if after_cursor is not None:
310            query["after_cursor"] = after_cursor
311        return self._http.request(
312            "/api/v1/notifications",
313            query=query,
314            response_type=NotificationListResponse,
315        )

List a user's notifications Returns a cursor-paginated list of inbox notifications for the authenticated user, ordered by creation time descending (newest first). All status groups are included by default; pass status to narrow results to a specific group. Each notification's rendered field contains type-specific display data resolved at request time. Notifications whose type is no longer registered in the platform are rendered with kind: "unknown" rather than being omitted. Pagination is forward-only: supply after_cursor from a previous response to fetch the next (older) page. The before_cursor field is always null for this endpoint. Requires an app-scoped token.

Arguments:
  • status: Filter by notification status. One of "all", "active", "unread", "read", or "archived". Defaults to "all" when omitted.
  • limit: Maximum number of notifications to return per page. Defaults to 20; maximum is 100.
  • after_cursor: Opaque pagination cursor from a previous response's after_cursor field. Omit to fetch the most recent notifications.
Returns:

Successful response

def read_all(self) -> None:
317    def read_all(self) -> None:
318        """
319        Mark all notifications as read
320        Marks every `"unread"` notification belonging to the authenticated user as
321        `"read"` in a single operation. Notifications that are already `"read"` or
322        `"archived"` are not affected.
323        This call is safe to retry if there are no unread notifications, it
324        succeeds without error. Requires an app-scoped token. Returns 204 No Content
325        on success.
326
327        Returns:
328            No content
329        """
330        self._http.request("/api/v1/notifications/read_all", method="POST")

Mark all notifications as read Marks every "unread" notification belonging to the authenticated user as "read" in a single operation. Notifications that are already "read" or "archived" are not affected. This call is safe to retry if there are no unread notifications, it succeeds without error. Requires an app-scoped token. Returns 204 No Content on success.

Returns:

No content

332    def send(self, input: NotificationSendInput) -> Notification:
333        """
334        Send a custom notification to a user
335        Delivers a custom-typed notification to one of the calling app's users.
336        Apps define notification types by declaring `NotificationType` config objects
337        in their bundle (one per `lookup_key`). Supply the type as
338        `"custom:<lookup_key>"` and provide a `data` map that is merged with
339        platform-provided context to render the notification's display fields.
340        Only app-scoped tokens may call this endpoint user tokens are rejected with
341        403. The app scope is stamped onto the notification automatically; an app
342        cannot target recipients outside its tenant. Built-in platform types such as
343        `"app_info"` and `"billing_alert"` are not accepted here.
344        The `notifications.send` script binding also accepts the viewer a script runs
345        as: a user, an agent, or a team's system viewer. Such a sender may notify only
346        a user it can see in its own organization and sandbox. When the sender is a
347        user, the recipient must also be able to see the sender. An agent cannot see
348        user records, so an agent sender must name a source message: it may then
349        notify a user in its own organization and sandbox who can read that message.
350        Pass `thread` and `message` together to name the message the notification is
351        about. The send is then refused unless that message is in that thread and both
352        the sender and the recipient can read it, so a notification cannot quote a
353        message its recipient cannot open.
354        Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice
355        with the same `idempotency_key` for the same recipient, the second call
356        returns the original notification without creating a duplicate. The key is
357        scoped to the calling app, so the same raw key used by different apps cannot
358        collide.
359
360        Args:
361            input: Request body.
362            input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
363            input.idempotency_key: Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
364            input.message: Source message (`msg_...`) that the sender and the recipient must both be able to read.
365            input.thread: Thread (`thr_...`) of the source message. Requires `message`.
366            input.type: Custom notification type identifier in the form `"custom:<lookup_key>"`, where `<lookup_key>` matches a `NotificationType` config declared in the calling app's bundle.
367            input.user: Recipient user ID (`usr_...`). Must be a member of the calling app's tenant.
368
369        Returns:
370            The created notification, or the existing notification when deduplicated by `idempotency_key`.
371        """
372        return self._http.request(
373            "/api/v1/notifications/send",
374            method="POST",
375            body=input,
376            response_type=Notification,
377        )

Send a custom notification to a user Delivers a custom-typed notification to one of the calling app's users. Apps define notification types by declaring NotificationType config objects in their bundle (one per lookup_key). Supply the type as "custom:<lookup_key>" and provide a data map that is merged with platform-provided context to render the notification's display fields. Only app-scoped tokens may call this endpoint user tokens are rejected with

  1. The app scope is stamped onto the notification automatically; an app cannot target recipients outside its tenant. Built-in platform types such as "app_info" and "billing_alert" are not accepted here. The notifications.send script binding also accepts the viewer a script runs as: a user, an agent, or a team's system viewer. Such a sender may notify only a user it can see in its own organization and sandbox. When the sender is a user, the recipient must also be able to see the sender. An agent cannot see user records, so an agent sender must name a source message: it may then notify a user in its own organization and sandbox who can read that message. Pass thread and message together to name the message the notification is about. The send is then refused unless that message is in that thread and both the sender and the recipient can read it, so a notification cannot quote a message its recipient cannot open. Pass idempotency_key to deduplicate sends. If you call this endpoint twice with the same idempotency_key for the same recipient, the second call returns the original notification without creating a duplicate. The key is scoped to the calling app, so the same raw key used by different apps cannot collide.
Arguments:
  • input: Request body.
  • input.data: Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted.
  • input.idempotency_key: Optional deduplication key. A second call with the same idempotency_key for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app.
  • input.message: Source message (msg_...) that the sender and the recipient must both be able to read.
  • input.thread: Thread (thr_...) of the source message. Requires message.
  • input.type: Custom notification type identifier in the form "custom:<lookup_key>", where <lookup_key> matches a NotificationType config declared in the calling app's bundle.
  • input.user: Recipient user ID (usr_...). Must be a member of the calling app's tenant.
Returns:

The created notification, or the existing notification when deduplicated by idempotency_key.

def unread_count( self) -> NotificationUnreadCountResponse:
379    def unread_count(self) -> NotificationUnreadCountResponse:
380        """
381        Get the unread notification count
382        Returns the total number of `"unread"` notifications for the authenticated
383        user. Useful for displaying a badge or indicator in your UI without
384        fetching the full notification list.
385        Notifications with `"read"` or `"archived"` status are not included in the
386        count. Requires an app-scoped token.
387
388        Returns:
389            Successful response
390        """
391        return self._http.request(
392            "/api/v1/notifications/unread_count",
393            response_type=NotificationUnreadCountResponse,
394        )

Get the unread notification count Returns the total number of "unread" notifications for the authenticated user. Useful for displaying a badge or indicator in your UI without fetching the full notification list. Notifications with "read" or "archived" status are not included in the count. Requires an app-scoped token.

Returns:

Successful response

def archive(self, notification: str) -> None:
396    def archive(self, notification: str) -> None:
397        """
398        Archive a notification
399        Moves a notification to `"archived"` status regardless of whether it is
400        currently `"unread"` or `"read"`. Archived notifications are excluded from
401        the default inbox view but remain retrievable by passing `status: "archived"`
402        to the list endpoint.
403        The authenticated user must own the notification. Passing a notification ID
404        that belongs to a different user returns a 404. If the notification is
405        already archived this call succeeds without error (idempotent).
406        Requires an app-scoped token. Returns 204 No Content on success.
407
408        Args:
409            notification: Notification ID (`ntf_...`) to archive. Must belong to the authenticated user.
410
411        Returns:
412            No content
413        """
414        self._http.request(f"/api/v1/notifications/{notification}/archive", method="POST")

Archive a notification Moves a notification to "archived" status regardless of whether it is currently "unread" or "read". Archived notifications are excluded from the default inbox view but remain retrievable by passing status: "archived" to the list endpoint. The authenticated user must own the notification. Passing a notification ID that belongs to a different user returns a 404. If the notification is already archived this call succeeds without error (idempotent). Requires an app-scoped token. Returns 204 No Content on success.

Arguments:
  • notification: Notification ID (ntf_...) to archive. Must belong to the authenticated user.
Returns:

No content

def read(self, notification: str) -> None:
416    def read(self, notification: str) -> None:
417        """
418        Mark a notification as read
419        Transitions a notification from `"unread"` to `"read"` status. If the
420        notification is already `"read"` or `"archived"`, the call succeeds without
421        changing its status (idempotent).
422        The authenticated user must own the notification. Passing a notification ID
423        that belongs to a different user returns a 404. Requires an app-scoped token.
424        Returns 204 No Content on success.
425
426        Args:
427            notification: Notification ID (`ntf_...`) to mark as read. Must belong to the authenticated user.
428
429        Returns:
430            No content
431        """
432        self._http.request(f"/api/v1/notifications/{notification}/read", method="POST")

Mark a notification as read Transitions a notification from "unread" to "read" status. If the notification is already "read" or "archived", the call succeeds without changing its status (idempotent). The authenticated user must own the notification. Passing a notification ID that belongs to a different user returns a 404. Requires an app-scoped token. Returns 204 No Content on success.

Arguments:
  • notification: Notification ID (ntf_...) to mark as read. Must belong to the authenticated user.
Returns:

No content

def unarchive(self, notification: str) -> None:
434    def unarchive(self, notification: str) -> None:
435        """
436        Unarchive a notification
437        Restores an `"archived"` notification to its previous active status:
438        `"read"` if the notification had been read before archiving, or `"unread"`
439        otherwise. The notification will appear again in the default inbox view.
440        The authenticated user must own the notification. Passing a notification ID
441        that belongs to a different user returns a 404. If the notification is not
442        currently archived this call succeeds without changing its status (idempotent).
443        Requires an app-scoped token. Returns 204 No Content on success.
444
445        Args:
446            notification: Notification ID (`ntf_...`) to unarchive. Must belong to the authenticated user.
447
448        Returns:
449            No content
450        """
451        self._http.request(f"/api/v1/notifications/{notification}/unarchive", method="POST")

Unarchive a notification Restores an "archived" notification to its previous active status: "read" if the notification had been read before archiving, or "unread" otherwise. The notification will appear again in the default inbox view. The authenticated user must own the notification. Passing a notification ID that belongs to a different user returns a 404. If the notification is not currently archived this call succeeds without changing its status (idempotent). Requires an app-scoped token. Returns 204 No Content on success.

Arguments:
  • notification: Notification ID (ntf_...) to unarchive. Must belong to the authenticated user.
Returns:

No content