Skip to content

Posts

pynteracta.api.posts

Posts resource client.

PostsAPI

Bases: ResourceClient

Client for post detail, community listing, and comments endpoints.

Source code in src/pynteracta/api/posts.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
class PostsAPI(ResourceClient):
    """Client for post detail, community listing, and comments endpoints."""

    def __init__(self, transport: HttpTransport) -> None:
        super().__init__(transport)

    def get(  # noqa: PLR0913
        self,
        post_id: int,
        *,
        load_main_attachment: bool = False,
        load_main_attachment_view_link: bool = False,
        load_main_attachment_download_link: bool = False,
        load_main_attachment_preview_image_link: bool = False,
        load_main_attachment_preview_image_animated_link: bool = False,
        load_main_attachment_preview_image_hi_res_link: bool = False,
        load_main_attachment_preview_image_hi_res_animated_link: bool = False,
    ) -> Post:
        """GET ``/communication/posts/data/post-detail-by-id/{postId}``."""
        path = _GET_POST_PATH.format(post_id=post_id)
        params = build_query_params(
            load_main_attachment=load_main_attachment,
            load_main_attachment_view_link=load_main_attachment_view_link,
            load_main_attachment_download_link=load_main_attachment_download_link,
            load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
            load_main_attachment_preview_image_animated_link=(
                load_main_attachment_preview_image_animated_link
            ),
            load_main_attachment_preview_image_hi_res_link=(
                load_main_attachment_preview_image_hi_res_link
            ),
            load_main_attachment_preview_image_hi_res_animated_link=(
                load_main_attachment_preview_image_hi_res_animated_link
            ),
        )
        return Post.from_dict(self._get(path, params=params or None))

    def list_in_community(  # noqa: PLR0912, PLR0913, PLR0915
        self,
        community_id: int,
        *,
        page_token: str | None = None,
        page_size: int | None = None,
        calculate_total_items_count: bool | None = None,
        load_post_details: bool = True,
        load_main_attachment: bool | None = None,
        load_main_attachment_view_link: bool | None = None,
        load_main_attachment_download_link: bool | None = None,
        load_main_attachment_preview_image_link: bool | None = None,
        load_main_attachment_preview_image_animated_link: bool | None = None,
        load_main_attachment_preview_image_hi_res_link: bool | None = None,
        load_main_attachment_preview_image_hi_res_animated_link: bool | None = None,
        load_capabilities: bool | None = None,
        # --- ordering ---
        order_by: str | None = None,
        order_desc: bool | None = None,
        pinned_first: bool | None = None,
        # --- communityPostFilters (curated subset) ---
        title: str | None = None,
        description: str | None = None,
        contains_text: str | None = None,
        created_by_user_ids: list[int] | None = None,
        created_by_group_ids: list[int] | None = None,
        creation_timestamp_from: int | float | str | None = None,
        creation_timestamp_to: int | float | str | None = None,
        modified_timestamp_from: int | float | str | None = None,
        modified_timestamp_to: int | float | str | None = None,
        hashtag_ids: list[int] | None = None,
        hashtags_logical_and: bool | None = None,
        post_types: list[int] | None = None,
        current_workflow_status_ids: list[int] | None = None,
        visibility: int | None = None,
        followed_by_me: bool | None = None,
        mentioned: bool | None = None,
        to_manage: bool | None = None,
        only_pinned: bool | None = None,
        post_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
        screen_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
        # --- opt-in validation ---
        validate_with: PostDefinition | None = None,
        # --- escape hatch ---
        community_post_filters: dict[str, Any] | None = None,
        **filters: Any,
    ) -> PostList:
        """POST ``/communication/posts/data/list/community/{communityId}``.

        Args:
            community_id: Target community.
            order_by: Sort field — one of :data:`POST_ORDER_FIELDS` or ``'postCustomField-{id}'``.
            order_desc: Descending sort (``True``) or ascending (``False``).
            pinned_first: Show pinned posts first.
            title: Filter on post title.
            description: Filter on post description.
            contains_text: Full-text filter on post content.
            created_by_user_ids: Filter by creator user ids.
            created_by_group_ids: Filter by creator group ids.
            creation_timestamp_from: Lower bound on creation date (epoch-ms, datetime, or ISO str).
            creation_timestamp_to: Upper bound on creation date.
            modified_timestamp_from: Lower bound on modification date.
            modified_timestamp_to: Upper bound on modification date.
            hashtag_ids: Filter by hashtag ids.
            hashtags_logical_and: Combine hashtag filters with AND (default OR).
            post_types: Filter by post type ids (1=CUSTOM, 2=EVENTO, 3=QUESTIONARIO).
            current_workflow_status_ids: Filter by workflow status ids.
            visibility: Filter by visibility (public/private).
            followed_by_me: Only posts followed by the current user.
            mentioned: Only posts where the current user was mentioned.
            to_manage: Only posts the current user has actions to take on.
            only_pinned: Only pinned posts.
            post_field_filters: Custom-field filters — list of :class:`PostFieldFilter` or dicts
                with keys ``column_id``/``columnId``, ``type_id``/``typeId``, ``parameters``.
            screen_field_filters: Workflow screen-field filters (same structure).
            validate_with: When supplied, validates ``post_field_filters`` and
                ``screen_field_filters`` against this community's post-definition before sending
                (no extra network call; raises :class:`~pynteracta.exceptions.ValidationError`).
            community_post_filters: Pre-built ``communityPostFilters`` dict — escape hatch for
                the long-tail fields not promoted to explicit kwargs.
            **filters: Additional camelCase fields forwarded to the request body (escape hatch).
        """
        if order_by is not None:
            _validate_order_by(order_by)

        # Coerce date kwargs to epoch-millis
        cf_from = to_epoch_millis(creation_timestamp_from)
        cf_to = to_epoch_millis(creation_timestamp_to)
        mf_from = to_epoch_millis(modified_timestamp_from)
        mf_to = to_epoch_millis(modified_timestamp_to)

        # Opt-in validation of field filters
        coerced_pff: list[PostFieldFilter] | None = None
        coerced_sff: list[PostFieldFilter] | None = None
        if post_field_filters is not None and validate_with is not None:
            coerced_pff = validate_field_filters(post_field_filters, validate_with)
        elif post_field_filters is not None:
            coerced_pff = [
                f if isinstance(f, PostFieldFilter) else PostFieldFilter.from_dict(f)
                for f in post_field_filters
            ]
        if screen_field_filters is not None and validate_with is not None:
            coerced_sff = validate_field_filters(screen_field_filters, validate_with, screen=True)
        elif screen_field_filters is not None:
            coerced_sff = [
                f if isinstance(f, PostFieldFilter) else PostFieldFilter.from_dict(f)
                for f in screen_field_filters
            ]

        # Build the complete communityPostFilters (SaaS-compatible: all fields present).
        # Priority: defaults → community_post_filters escape hatch → explicit kwargs.
        cpf: dict[str, Any] = dict(_DEFAULT_COMMUNITY_POST_FILTERS)
        if community_post_filters:
            cpf.update(community_post_filters)
        if title is not None:
            cpf["title"] = title
        if description is not None:
            cpf["description"] = description
        if contains_text is not None:
            cpf["containsText"] = contains_text
        if created_by_user_ids is not None:
            cpf["createdByUserIds"] = created_by_user_ids
        if created_by_group_ids is not None:
            cpf["createdByGroupIds"] = created_by_group_ids
        if cf_from is not None:
            cpf["creationTimestampFrom"] = cf_from
        if cf_to is not None:
            cpf["creationTimestampTo"] = cf_to
        if mf_from is not None:
            cpf["modifiedTimestampFrom"] = mf_from
        if mf_to is not None:
            cpf["modifiedTimestampTo"] = mf_to
        if hashtag_ids is not None:
            cpf["hashtagIds"] = hashtag_ids
        if hashtags_logical_and is not None:
            cpf["hashtagsLogicalAnd"] = hashtags_logical_and
        if post_types is not None:
            cpf["postTypes"] = post_types
        if current_workflow_status_ids is not None:
            cpf["currentWorkflowStatusIds"] = current_workflow_status_ids
        if visibility is not None:
            cpf["visibility"] = visibility
        if followed_by_me is not None:
            cpf["followedByMe"] = followed_by_me
        if mentioned is not None:
            cpf["mentioned"] = mentioned
        if to_manage is not None:
            cpf["toManage"] = to_manage
        if only_pinned is not None:
            cpf["onlyPinned"] = only_pinned
        if coerced_pff is not None:
            cpf["postFieldFilters"] = [f.to_dict() for f in coerced_pff]
        if coerced_sff is not None:
            cpf["screenFieldFilters"] = [f.to_dict() for f in coerced_sff]

        # Build the complete request body matching the SaaS payload structure.
        body: dict[str, Any] = {}
        if page_token is not None:
            body["pageToken"] = page_token
        if page_size is not None:
            body["pageSize"] = page_size
        if calculate_total_items_count is not None:
            body["calculateTotalItemsCount"] = calculate_total_items_count
        body["orderBy"] = order_by if order_by is not None else _DEFAULT_ORDER_BY
        body["orderDesc"] = order_desc if order_desc is not None else True
        body["communityPostFilters"] = cpf
        body["pinnedFirst"] = pinned_first if pinned_first is not None else True
        body["communityAttachmentFilters"] = dict(_DEFAULT_COMMUNITY_ATTACHMENT_FILTERS)
        for key, value in filters.items():
            if value is not None:
                body[snake_to_camel(key)] = value

        path = _LIST_COMMUNITY_PATH.format(community_id=community_id)
        params = build_query_params(
            load_post_details=load_post_details,
            load_main_attachment=load_main_attachment,
            load_main_attachment_view_link=load_main_attachment_view_link,
            load_main_attachment_download_link=load_main_attachment_download_link,
            load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
            load_main_attachment_preview_image_animated_link=(
                load_main_attachment_preview_image_animated_link
            ),
            load_main_attachment_preview_image_hi_res_link=(
                load_main_attachment_preview_image_hi_res_link
            ),
            load_main_attachment_preview_image_hi_res_animated_link=(
                load_main_attachment_preview_image_hi_res_animated_link
            ),
            load_capabilities=load_capabilities,
        )
        return PostList.from_dict(self._post(path, json=body, params=params))

    def list_in_community_raw(  # noqa: PLR0913
        self,
        community_id: int,
        req: ListCommunityPostsFilteredRequestDTO,
        *,
        load_post_details: bool = True,
        load_main_attachment: bool | None = None,
        load_main_attachment_view_link: bool | None = None,
        load_main_attachment_download_link: bool | None = None,
        load_main_attachment_preview_image_link: bool | None = None,
        load_main_attachment_preview_image_animated_link: bool | None = None,
        load_main_attachment_preview_image_hi_res_link: bool | None = None,
        load_main_attachment_preview_image_hi_res_animated_link: bool | None = None,
        load_capabilities: bool | None = None,
    ) -> PostList:
        """POST community post list with a pre-built request DTO (escape hatch)."""
        path = _LIST_COMMUNITY_PATH.format(community_id=community_id)
        params = build_query_params(
            load_post_details=load_post_details,
            load_main_attachment=load_main_attachment,
            load_main_attachment_view_link=load_main_attachment_view_link,
            load_main_attachment_download_link=load_main_attachment_download_link,
            load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
            load_main_attachment_preview_image_animated_link=(
                load_main_attachment_preview_image_animated_link
            ),
            load_main_attachment_preview_image_hi_res_link=(
                load_main_attachment_preview_image_hi_res_link
            ),
            load_main_attachment_preview_image_hi_res_animated_link=(
                load_main_attachment_preview_image_hi_res_animated_link
            ),
            load_capabilities=load_capabilities,
        )
        return PostList.from_dict(
            self._post(path, json=req.model_dump(mode="json", exclude_none=True), params=params)
        )

    def iterate_in_community(  # noqa: PLR0913
        self,
        community_id: int,
        *,
        page_size: int | None = None,
        order_by: str | None = None,
        order_desc: bool | None = None,
        pinned_first: bool | None = None,
        title: str | None = None,
        description: str | None = None,
        contains_text: str | None = None,
        created_by_user_ids: list[int] | None = None,
        created_by_group_ids: list[int] | None = None,
        creation_timestamp_from: int | float | str | None = None,
        creation_timestamp_to: int | float | str | None = None,
        modified_timestamp_from: int | float | str | None = None,
        modified_timestamp_to: int | float | str | None = None,
        hashtag_ids: list[int] | None = None,
        hashtags_logical_and: bool | None = None,
        post_types: list[int] | None = None,
        current_workflow_status_ids: list[int] | None = None,
        visibility: int | None = None,
        followed_by_me: bool | None = None,
        mentioned: bool | None = None,
        to_manage: bool | None = None,
        only_pinned: bool | None = None,
        post_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
        screen_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
        validate_with: PostDefinition | None = None,
        community_post_filters: dict[str, Any] | None = None,
        **filters: Any,
    ) -> PageIterator[generated.BaseListPostsElementDTOModel]:
        """Lazy iterator over all pages of :meth:`list_in_community`."""

        def fetch(page_token: str | None) -> PostList:
            return self.list_in_community(
                community_id,
                page_token=page_token,
                page_size=page_size,
                order_by=order_by,
                order_desc=order_desc,
                pinned_first=pinned_first,
                title=title,
                description=description,
                contains_text=contains_text,
                created_by_user_ids=created_by_user_ids,
                created_by_group_ids=created_by_group_ids,
                creation_timestamp_from=creation_timestamp_from,
                creation_timestamp_to=creation_timestamp_to,
                modified_timestamp_from=modified_timestamp_from,
                modified_timestamp_to=modified_timestamp_to,
                hashtag_ids=hashtag_ids,
                hashtags_logical_and=hashtags_logical_and,
                post_types=post_types,
                current_workflow_status_ids=current_workflow_status_ids,
                visibility=visibility,
                followed_by_me=followed_by_me,
                mentioned=mentioned,
                to_manage=to_manage,
                only_pinned=only_pinned,
                post_field_filters=post_field_filters,
                screen_field_filters=screen_field_filters,
                validate_with=validate_with,
                community_post_filters=community_post_filters,
                **filters,
            )

        return PageIterator(fetch, items_getter=lambda page: page.items_typed)

    def get_by_client_uid(  # noqa: PLR0913
        self,
        client_uid: str,
        *,
        load_main_attachment: bool = False,
        load_main_attachment_view_link: bool = False,
        load_main_attachment_download_link: bool = False,
        load_main_attachment_preview_image_link: bool = False,
        load_main_attachment_preview_image_animated_link: bool = False,
        load_main_attachment_preview_image_hi_res_link: bool = False,
        load_main_attachment_preview_image_hi_res_animated_link: bool = False,
    ) -> Post:
        """GET ``/communication/posts/data/post-detail-by-client-uid/{clientUid}``."""
        path = _GET_POST_BY_CLIENT_UID_PATH.format(client_uid=client_uid)
        params = build_query_params(
            load_main_attachment=load_main_attachment,
            load_main_attachment_view_link=load_main_attachment_view_link,
            load_main_attachment_download_link=load_main_attachment_download_link,
            load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
            load_main_attachment_preview_image_animated_link=(
                load_main_attachment_preview_image_animated_link
            ),
            load_main_attachment_preview_image_hi_res_link=(
                load_main_attachment_preview_image_hi_res_link
            ),
            load_main_attachment_preview_image_hi_res_animated_link=(
                load_main_attachment_preview_image_hi_res_animated_link
            ),
        )
        return Post.from_dict(self._get(path, params=params or None))

    def capabilities(self, post_id: int) -> PostCapabilities:
        """GET ``/communication/posts/data/post-capabilities/{postId}``."""
        path = _POST_CAPABILITIES_PATH.format(post_id=post_id)
        return PostCapabilities.from_dict(self._get(path))

    def history(
        self,
        post_id: int,
        *,
        page_token: str | None = None,
        page_size: int | None = None,
        calculate_total_items_count: bool | None = None,
        **filters: Any,
    ) -> PostHistoryEventList:
        """POST ``/communication/posts/data/history-list/{postId}``."""
        body = build_paginated_body(
            page_token=page_token,
            page_size=page_size,
            calculate_total_items_count=calculate_total_items_count,
            **filters,
        )
        req = ListPostHistoryEventsRequestDTO.model_validate(body)
        return self.history_raw(post_id, req)

    def history_raw(
        self, post_id: int, req: ListPostHistoryEventsRequestDTO
    ) -> PostHistoryEventList:
        """POST history with a pre-built request DTO (escape hatch)."""
        path = _HISTORY_LIST_PATH.format(post_id=post_id)
        return PostHistoryEventList.from_dict(
            self._post(path, json=req.model_dump(mode="json", exclude_none=True))
        )

    def iterate_history(
        self,
        post_id: int,
        *,
        page_size: int | None = None,
        **filters: Any,
    ) -> PageIterator[generated.PostActivityHistoryEventDTO1]:
        """Lazy iterator over all pages of :meth:`history`."""

        def fetch(page_token: str | None) -> PostHistoryEventList:
            return self.history(post_id, page_token=page_token, page_size=page_size, **filters)

        return PageIterator(fetch, items_getter=lambda page: page.items_typed)

    def global_stream(  # noqa: PLR0913
        self,
        *,
        sync_token: str | None = None,
        page_token: str | None = None,
        load_main_attachment: bool | None = None,
        load_main_attachment_view_link: bool | None = None,
        load_main_attachment_download_link: bool | None = None,
        load_main_attachment_preview_image_link: bool | None = None,
        load_main_attachment_preview_image_animated_link: bool | None = None,
        load_main_attachment_preview_image_hi_res_link: bool | None = None,
        load_main_attachment_preview_image_hi_res_animated_link: bool | None = None,
    ) -> GlobalPostStream:
        """POST ``/communication/posts/data/global-stream`` (filters via query params)."""
        params = build_query_params(
            sync_token=sync_token,
            page_token=page_token,
            load_main_attachment=load_main_attachment,
            load_main_attachment_view_link=load_main_attachment_view_link,
            load_main_attachment_download_link=load_main_attachment_download_link,
            load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
            load_main_attachment_preview_image_animated_link=(
                load_main_attachment_preview_image_animated_link
            ),
            load_main_attachment_preview_image_hi_res_link=(
                load_main_attachment_preview_image_hi_res_link
            ),
            load_main_attachment_preview_image_hi_res_animated_link=(
                load_main_attachment_preview_image_hi_res_animated_link
            ),
        )
        return GlobalPostStream.from_dict(
            self._post(_GLOBAL_STREAM_PATH, json={}, params=params or None)
        )

    def iterate_global_stream(
        self,
        *,
        sync_token: str | None = None,
        load_main_attachment: bool | None = None,
    ) -> PageIterator[generated.BasePostsStreamChunkElementDTOModel]:
        """Lazy iterator over all pages of :meth:`global_stream`."""

        def fetch(page_token: str | None) -> GlobalPostStream:
            return self.global_stream(
                sync_token=sync_token,
                page_token=page_token,
                load_main_attachment=load_main_attachment,
            )

        return PageIterator(fetch, items_getter=lambda page: page.items_typed)

    def community_list(
        self,
        community_id: int,
        *,
        page_token: str | None = None,
        page_size: int | None = None,
        calculate_total_items_count: bool | None = None,
        **filters: Any,
    ) -> PostList:
        """POST ``/communication/posts/data/community-list/{communityId}``.

        Lighter listing endpoint using :class:`ListCommunityPostsRequestDTO` (basic filters only).
        Distinct from ``list/community`` which uses the more fully-featured
        :class:`ListCommunityPostsFilteredRequestDTO`.
        """
        body = build_paginated_body(
            page_token=page_token,
            page_size=page_size,
            calculate_total_items_count=calculate_total_items_count,
            **filters,
        )
        req = ListCommunityPostsRequestDTO.model_validate(body)
        return self.community_list_raw(community_id, req)

    def community_list_raw(self, community_id: int, req: ListCommunityPostsRequestDTO) -> PostList:
        """POST community-list with a pre-built request DTO (escape hatch)."""
        path = _COMMUNITY_LIST_PATH.format(community_id=community_id)
        return PostList.from_dict(
            self._post(path, json=req.model_dump(mode="json", exclude_none=True))
        )

    def iterate_community_list(
        self,
        community_id: int,
        *,
        page_size: int | None = None,
        **filters: Any,
    ) -> PageIterator[generated.BaseListPostsElementDTOModel]:
        """Lazy iterator over all pages of :meth:`community_list`."""

        def fetch(page_token: str | None) -> PostList:
            return self.community_list(
                community_id, page_token=page_token, page_size=page_size, **filters
            )

        return PageIterator(fetch, items_getter=lambda page: page.items_typed)

    def check_visibility(self, post_ids: list[int]) -> VisibilityResult:
        """POST ``/communication/posts/data/check-visibility``."""
        req = CheckVisibilityRequestDTO(ids=post_ids)
        return self.check_visibility_raw(req)

    def check_visibility_raw(self, req: CheckVisibilityRequestDTO) -> VisibilityResult:
        """POST check-visibility with a pre-built request DTO (escape hatch)."""
        return VisibilityResult.from_dict(
            self._post(_CHECK_VISIBILITY_PATH, json=req.model_dump(mode="json", exclude_none=True))
        )

    def check_visibility_with_comments(self, post_ids: list[int]) -> VisibilityResult:
        """POST ``/communication/posts/data/check-visibility-with-comments``."""
        req = CheckVisibilityRequestDTO(ids=post_ids)
        return self.check_visibility_with_comments_raw(req)

    def check_visibility_with_comments_raw(
        self, req: CheckVisibilityRequestDTO
    ) -> VisibilityResult:
        """POST check-visibility-with-comments with a pre-built request DTO (escape hatch)."""
        return VisibilityResult.from_dict(
            self._post(
                _CHECK_VISIBILITY_WITH_COMMENTS_PATH,
                json=req.model_dump(mode="json", exclude_none=True),
            )
        )

    def comments(
        self,
        post_id: int,
        *,
        page_token: str | None = None,
        page_size: int | None = None,
        calculate_total_items_count: bool | None = None,
        **filters: Any,
    ) -> PostCommentList:
        """POST ``/communication/posts/data/comments-list/{postId}``."""
        body = build_paginated_body(
            page_token=page_token,
            page_size=page_size,
            calculate_total_items_count=calculate_total_items_count,
            **filters,
        )
        req = ListPostCommentsRequestDTO.model_validate(body)
        return self.comments_raw(post_id, req)

    def comments_raw(self, post_id: int, req: ListPostCommentsRequestDTO) -> PostCommentList:
        """POST post comments with a pre-built request DTO (escape hatch)."""
        path = _COMMENTS_PATH.format(post_id=post_id)
        return PostCommentList.from_dict(
            self._post(path, json=req.model_dump(mode="json", exclude_none=True))
        )

    def iterate_comments(
        self,
        post_id: int,
        *,
        page_size: int | None = None,
        **filters: Any,
    ) -> PageIterator[generated.PostCommentDTO1]:
        """Lazy iterator over all pages of :meth:`comments`."""

        def fetch(page_token: str | None) -> PostCommentList:
            return self.comments(post_id, page_token=page_token, page_size=page_size, **filters)

        return PageIterator(fetch, items_getter=lambda page: page.items_typed)

capabilities(post_id)

GET /communication/posts/data/post-capabilities/{postId}.

Source code in src/pynteracta/api/posts.py
def capabilities(self, post_id: int) -> PostCapabilities:
    """GET ``/communication/posts/data/post-capabilities/{postId}``."""
    path = _POST_CAPABILITIES_PATH.format(post_id=post_id)
    return PostCapabilities.from_dict(self._get(path))

check_visibility(post_ids)

POST /communication/posts/data/check-visibility.

Source code in src/pynteracta/api/posts.py
def check_visibility(self, post_ids: list[int]) -> VisibilityResult:
    """POST ``/communication/posts/data/check-visibility``."""
    req = CheckVisibilityRequestDTO(ids=post_ids)
    return self.check_visibility_raw(req)

check_visibility_raw(req)

POST check-visibility with a pre-built request DTO (escape hatch).

Source code in src/pynteracta/api/posts.py
def check_visibility_raw(self, req: CheckVisibilityRequestDTO) -> VisibilityResult:
    """POST check-visibility with a pre-built request DTO (escape hatch)."""
    return VisibilityResult.from_dict(
        self._post(_CHECK_VISIBILITY_PATH, json=req.model_dump(mode="json", exclude_none=True))
    )

check_visibility_with_comments(post_ids)

POST /communication/posts/data/check-visibility-with-comments.

Source code in src/pynteracta/api/posts.py
def check_visibility_with_comments(self, post_ids: list[int]) -> VisibilityResult:
    """POST ``/communication/posts/data/check-visibility-with-comments``."""
    req = CheckVisibilityRequestDTO(ids=post_ids)
    return self.check_visibility_with_comments_raw(req)

check_visibility_with_comments_raw(req)

POST check-visibility-with-comments with a pre-built request DTO (escape hatch).

Source code in src/pynteracta/api/posts.py
def check_visibility_with_comments_raw(
    self, req: CheckVisibilityRequestDTO
) -> VisibilityResult:
    """POST check-visibility-with-comments with a pre-built request DTO (escape hatch)."""
    return VisibilityResult.from_dict(
        self._post(
            _CHECK_VISIBILITY_WITH_COMMENTS_PATH,
            json=req.model_dump(mode="json", exclude_none=True),
        )
    )

comments(post_id, *, page_token=None, page_size=None, calculate_total_items_count=None, **filters)

POST /communication/posts/data/comments-list/{postId}.

Source code in src/pynteracta/api/posts.py
def comments(
    self,
    post_id: int,
    *,
    page_token: str | None = None,
    page_size: int | None = None,
    calculate_total_items_count: bool | None = None,
    **filters: Any,
) -> PostCommentList:
    """POST ``/communication/posts/data/comments-list/{postId}``."""
    body = build_paginated_body(
        page_token=page_token,
        page_size=page_size,
        calculate_total_items_count=calculate_total_items_count,
        **filters,
    )
    req = ListPostCommentsRequestDTO.model_validate(body)
    return self.comments_raw(post_id, req)

comments_raw(post_id, req)

POST post comments with a pre-built request DTO (escape hatch).

Source code in src/pynteracta/api/posts.py
def comments_raw(self, post_id: int, req: ListPostCommentsRequestDTO) -> PostCommentList:
    """POST post comments with a pre-built request DTO (escape hatch)."""
    path = _COMMENTS_PATH.format(post_id=post_id)
    return PostCommentList.from_dict(
        self._post(path, json=req.model_dump(mode="json", exclude_none=True))
    )

community_list(community_id, *, page_token=None, page_size=None, calculate_total_items_count=None, **filters)

POST /communication/posts/data/community-list/{communityId}.

Lighter listing endpoint using :class:ListCommunityPostsRequestDTO (basic filters only). Distinct from list/community which uses the more fully-featured :class:ListCommunityPostsFilteredRequestDTO.

Source code in src/pynteracta/api/posts.py
def community_list(
    self,
    community_id: int,
    *,
    page_token: str | None = None,
    page_size: int | None = None,
    calculate_total_items_count: bool | None = None,
    **filters: Any,
) -> PostList:
    """POST ``/communication/posts/data/community-list/{communityId}``.

    Lighter listing endpoint using :class:`ListCommunityPostsRequestDTO` (basic filters only).
    Distinct from ``list/community`` which uses the more fully-featured
    :class:`ListCommunityPostsFilteredRequestDTO`.
    """
    body = build_paginated_body(
        page_token=page_token,
        page_size=page_size,
        calculate_total_items_count=calculate_total_items_count,
        **filters,
    )
    req = ListCommunityPostsRequestDTO.model_validate(body)
    return self.community_list_raw(community_id, req)

community_list_raw(community_id, req)

POST community-list with a pre-built request DTO (escape hatch).

Source code in src/pynteracta/api/posts.py
def community_list_raw(self, community_id: int, req: ListCommunityPostsRequestDTO) -> PostList:
    """POST community-list with a pre-built request DTO (escape hatch)."""
    path = _COMMUNITY_LIST_PATH.format(community_id=community_id)
    return PostList.from_dict(
        self._post(path, json=req.model_dump(mode="json", exclude_none=True))
    )

get(post_id, *, load_main_attachment=False, load_main_attachment_view_link=False, load_main_attachment_download_link=False, load_main_attachment_preview_image_link=False, load_main_attachment_preview_image_animated_link=False, load_main_attachment_preview_image_hi_res_link=False, load_main_attachment_preview_image_hi_res_animated_link=False)

GET /communication/posts/data/post-detail-by-id/{postId}.

Source code in src/pynteracta/api/posts.py
def get(  # noqa: PLR0913
    self,
    post_id: int,
    *,
    load_main_attachment: bool = False,
    load_main_attachment_view_link: bool = False,
    load_main_attachment_download_link: bool = False,
    load_main_attachment_preview_image_link: bool = False,
    load_main_attachment_preview_image_animated_link: bool = False,
    load_main_attachment_preview_image_hi_res_link: bool = False,
    load_main_attachment_preview_image_hi_res_animated_link: bool = False,
) -> Post:
    """GET ``/communication/posts/data/post-detail-by-id/{postId}``."""
    path = _GET_POST_PATH.format(post_id=post_id)
    params = build_query_params(
        load_main_attachment=load_main_attachment,
        load_main_attachment_view_link=load_main_attachment_view_link,
        load_main_attachment_download_link=load_main_attachment_download_link,
        load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
        load_main_attachment_preview_image_animated_link=(
            load_main_attachment_preview_image_animated_link
        ),
        load_main_attachment_preview_image_hi_res_link=(
            load_main_attachment_preview_image_hi_res_link
        ),
        load_main_attachment_preview_image_hi_res_animated_link=(
            load_main_attachment_preview_image_hi_res_animated_link
        ),
    )
    return Post.from_dict(self._get(path, params=params or None))

get_by_client_uid(client_uid, *, load_main_attachment=False, load_main_attachment_view_link=False, load_main_attachment_download_link=False, load_main_attachment_preview_image_link=False, load_main_attachment_preview_image_animated_link=False, load_main_attachment_preview_image_hi_res_link=False, load_main_attachment_preview_image_hi_res_animated_link=False)

GET /communication/posts/data/post-detail-by-client-uid/{clientUid}.

Source code in src/pynteracta/api/posts.py
def get_by_client_uid(  # noqa: PLR0913
    self,
    client_uid: str,
    *,
    load_main_attachment: bool = False,
    load_main_attachment_view_link: bool = False,
    load_main_attachment_download_link: bool = False,
    load_main_attachment_preview_image_link: bool = False,
    load_main_attachment_preview_image_animated_link: bool = False,
    load_main_attachment_preview_image_hi_res_link: bool = False,
    load_main_attachment_preview_image_hi_res_animated_link: bool = False,
) -> Post:
    """GET ``/communication/posts/data/post-detail-by-client-uid/{clientUid}``."""
    path = _GET_POST_BY_CLIENT_UID_PATH.format(client_uid=client_uid)
    params = build_query_params(
        load_main_attachment=load_main_attachment,
        load_main_attachment_view_link=load_main_attachment_view_link,
        load_main_attachment_download_link=load_main_attachment_download_link,
        load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
        load_main_attachment_preview_image_animated_link=(
            load_main_attachment_preview_image_animated_link
        ),
        load_main_attachment_preview_image_hi_res_link=(
            load_main_attachment_preview_image_hi_res_link
        ),
        load_main_attachment_preview_image_hi_res_animated_link=(
            load_main_attachment_preview_image_hi_res_animated_link
        ),
    )
    return Post.from_dict(self._get(path, params=params or None))

global_stream(*, sync_token=None, page_token=None, load_main_attachment=None, load_main_attachment_view_link=None, load_main_attachment_download_link=None, load_main_attachment_preview_image_link=None, load_main_attachment_preview_image_animated_link=None, load_main_attachment_preview_image_hi_res_link=None, load_main_attachment_preview_image_hi_res_animated_link=None)

POST /communication/posts/data/global-stream (filters via query params).

Source code in src/pynteracta/api/posts.py
def global_stream(  # noqa: PLR0913
    self,
    *,
    sync_token: str | None = None,
    page_token: str | None = None,
    load_main_attachment: bool | None = None,
    load_main_attachment_view_link: bool | None = None,
    load_main_attachment_download_link: bool | None = None,
    load_main_attachment_preview_image_link: bool | None = None,
    load_main_attachment_preview_image_animated_link: bool | None = None,
    load_main_attachment_preview_image_hi_res_link: bool | None = None,
    load_main_attachment_preview_image_hi_res_animated_link: bool | None = None,
) -> GlobalPostStream:
    """POST ``/communication/posts/data/global-stream`` (filters via query params)."""
    params = build_query_params(
        sync_token=sync_token,
        page_token=page_token,
        load_main_attachment=load_main_attachment,
        load_main_attachment_view_link=load_main_attachment_view_link,
        load_main_attachment_download_link=load_main_attachment_download_link,
        load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
        load_main_attachment_preview_image_animated_link=(
            load_main_attachment_preview_image_animated_link
        ),
        load_main_attachment_preview_image_hi_res_link=(
            load_main_attachment_preview_image_hi_res_link
        ),
        load_main_attachment_preview_image_hi_res_animated_link=(
            load_main_attachment_preview_image_hi_res_animated_link
        ),
    )
    return GlobalPostStream.from_dict(
        self._post(_GLOBAL_STREAM_PATH, json={}, params=params or None)
    )

history(post_id, *, page_token=None, page_size=None, calculate_total_items_count=None, **filters)

POST /communication/posts/data/history-list/{postId}.

Source code in src/pynteracta/api/posts.py
def history(
    self,
    post_id: int,
    *,
    page_token: str | None = None,
    page_size: int | None = None,
    calculate_total_items_count: bool | None = None,
    **filters: Any,
) -> PostHistoryEventList:
    """POST ``/communication/posts/data/history-list/{postId}``."""
    body = build_paginated_body(
        page_token=page_token,
        page_size=page_size,
        calculate_total_items_count=calculate_total_items_count,
        **filters,
    )
    req = ListPostHistoryEventsRequestDTO.model_validate(body)
    return self.history_raw(post_id, req)

history_raw(post_id, req)

POST history with a pre-built request DTO (escape hatch).

Source code in src/pynteracta/api/posts.py
def history_raw(
    self, post_id: int, req: ListPostHistoryEventsRequestDTO
) -> PostHistoryEventList:
    """POST history with a pre-built request DTO (escape hatch)."""
    path = _HISTORY_LIST_PATH.format(post_id=post_id)
    return PostHistoryEventList.from_dict(
        self._post(path, json=req.model_dump(mode="json", exclude_none=True))
    )

iterate_comments(post_id, *, page_size=None, **filters)

Lazy iterator over all pages of :meth:comments.

Source code in src/pynteracta/api/posts.py
def iterate_comments(
    self,
    post_id: int,
    *,
    page_size: int | None = None,
    **filters: Any,
) -> PageIterator[generated.PostCommentDTO1]:
    """Lazy iterator over all pages of :meth:`comments`."""

    def fetch(page_token: str | None) -> PostCommentList:
        return self.comments(post_id, page_token=page_token, page_size=page_size, **filters)

    return PageIterator(fetch, items_getter=lambda page: page.items_typed)

iterate_community_list(community_id, *, page_size=None, **filters)

Lazy iterator over all pages of :meth:community_list.

Source code in src/pynteracta/api/posts.py
def iterate_community_list(
    self,
    community_id: int,
    *,
    page_size: int | None = None,
    **filters: Any,
) -> PageIterator[generated.BaseListPostsElementDTOModel]:
    """Lazy iterator over all pages of :meth:`community_list`."""

    def fetch(page_token: str | None) -> PostList:
        return self.community_list(
            community_id, page_token=page_token, page_size=page_size, **filters
        )

    return PageIterator(fetch, items_getter=lambda page: page.items_typed)

iterate_global_stream(*, sync_token=None, load_main_attachment=None)

Lazy iterator over all pages of :meth:global_stream.

Source code in src/pynteracta/api/posts.py
def iterate_global_stream(
    self,
    *,
    sync_token: str | None = None,
    load_main_attachment: bool | None = None,
) -> PageIterator[generated.BasePostsStreamChunkElementDTOModel]:
    """Lazy iterator over all pages of :meth:`global_stream`."""

    def fetch(page_token: str | None) -> GlobalPostStream:
        return self.global_stream(
            sync_token=sync_token,
            page_token=page_token,
            load_main_attachment=load_main_attachment,
        )

    return PageIterator(fetch, items_getter=lambda page: page.items_typed)

iterate_history(post_id, *, page_size=None, **filters)

Lazy iterator over all pages of :meth:history.

Source code in src/pynteracta/api/posts.py
def iterate_history(
    self,
    post_id: int,
    *,
    page_size: int | None = None,
    **filters: Any,
) -> PageIterator[generated.PostActivityHistoryEventDTO1]:
    """Lazy iterator over all pages of :meth:`history`."""

    def fetch(page_token: str | None) -> PostHistoryEventList:
        return self.history(post_id, page_token=page_token, page_size=page_size, **filters)

    return PageIterator(fetch, items_getter=lambda page: page.items_typed)

iterate_in_community(community_id, *, page_size=None, order_by=None, order_desc=None, pinned_first=None, title=None, description=None, contains_text=None, created_by_user_ids=None, created_by_group_ids=None, creation_timestamp_from=None, creation_timestamp_to=None, modified_timestamp_from=None, modified_timestamp_to=None, hashtag_ids=None, hashtags_logical_and=None, post_types=None, current_workflow_status_ids=None, visibility=None, followed_by_me=None, mentioned=None, to_manage=None, only_pinned=None, post_field_filters=None, screen_field_filters=None, validate_with=None, community_post_filters=None, **filters)

Lazy iterator over all pages of :meth:list_in_community.

Source code in src/pynteracta/api/posts.py
def iterate_in_community(  # noqa: PLR0913
    self,
    community_id: int,
    *,
    page_size: int | None = None,
    order_by: str | None = None,
    order_desc: bool | None = None,
    pinned_first: bool | None = None,
    title: str | None = None,
    description: str | None = None,
    contains_text: str | None = None,
    created_by_user_ids: list[int] | None = None,
    created_by_group_ids: list[int] | None = None,
    creation_timestamp_from: int | float | str | None = None,
    creation_timestamp_to: int | float | str | None = None,
    modified_timestamp_from: int | float | str | None = None,
    modified_timestamp_to: int | float | str | None = None,
    hashtag_ids: list[int] | None = None,
    hashtags_logical_and: bool | None = None,
    post_types: list[int] | None = None,
    current_workflow_status_ids: list[int] | None = None,
    visibility: int | None = None,
    followed_by_me: bool | None = None,
    mentioned: bool | None = None,
    to_manage: bool | None = None,
    only_pinned: bool | None = None,
    post_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
    screen_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
    validate_with: PostDefinition | None = None,
    community_post_filters: dict[str, Any] | None = None,
    **filters: Any,
) -> PageIterator[generated.BaseListPostsElementDTOModel]:
    """Lazy iterator over all pages of :meth:`list_in_community`."""

    def fetch(page_token: str | None) -> PostList:
        return self.list_in_community(
            community_id,
            page_token=page_token,
            page_size=page_size,
            order_by=order_by,
            order_desc=order_desc,
            pinned_first=pinned_first,
            title=title,
            description=description,
            contains_text=contains_text,
            created_by_user_ids=created_by_user_ids,
            created_by_group_ids=created_by_group_ids,
            creation_timestamp_from=creation_timestamp_from,
            creation_timestamp_to=creation_timestamp_to,
            modified_timestamp_from=modified_timestamp_from,
            modified_timestamp_to=modified_timestamp_to,
            hashtag_ids=hashtag_ids,
            hashtags_logical_and=hashtags_logical_and,
            post_types=post_types,
            current_workflow_status_ids=current_workflow_status_ids,
            visibility=visibility,
            followed_by_me=followed_by_me,
            mentioned=mentioned,
            to_manage=to_manage,
            only_pinned=only_pinned,
            post_field_filters=post_field_filters,
            screen_field_filters=screen_field_filters,
            validate_with=validate_with,
            community_post_filters=community_post_filters,
            **filters,
        )

    return PageIterator(fetch, items_getter=lambda page: page.items_typed)

list_in_community(community_id, *, page_token=None, page_size=None, calculate_total_items_count=None, load_post_details=True, load_main_attachment=None, load_main_attachment_view_link=None, load_main_attachment_download_link=None, load_main_attachment_preview_image_link=None, load_main_attachment_preview_image_animated_link=None, load_main_attachment_preview_image_hi_res_link=None, load_main_attachment_preview_image_hi_res_animated_link=None, load_capabilities=None, order_by=None, order_desc=None, pinned_first=None, title=None, description=None, contains_text=None, created_by_user_ids=None, created_by_group_ids=None, creation_timestamp_from=None, creation_timestamp_to=None, modified_timestamp_from=None, modified_timestamp_to=None, hashtag_ids=None, hashtags_logical_and=None, post_types=None, current_workflow_status_ids=None, visibility=None, followed_by_me=None, mentioned=None, to_manage=None, only_pinned=None, post_field_filters=None, screen_field_filters=None, validate_with=None, community_post_filters=None, **filters)

POST /communication/posts/data/list/community/{communityId}.

Parameters:

Name Type Description Default
community_id int

Target community.

required
order_by str | None

Sort field — one of :data:POST_ORDER_FIELDS or 'postCustomField-{id}'.

None
order_desc bool | None

Descending sort (True) or ascending (False).

None
pinned_first bool | None

Show pinned posts first.

None
title str | None

Filter on post title.

None
description str | None

Filter on post description.

None
contains_text str | None

Full-text filter on post content.

None
created_by_user_ids list[int] | None

Filter by creator user ids.

None
created_by_group_ids list[int] | None

Filter by creator group ids.

None
creation_timestamp_from int | float | str | None

Lower bound on creation date (epoch-ms, datetime, or ISO str).

None
creation_timestamp_to int | float | str | None

Upper bound on creation date.

None
modified_timestamp_from int | float | str | None

Lower bound on modification date.

None
modified_timestamp_to int | float | str | None

Upper bound on modification date.

None
hashtag_ids list[int] | None

Filter by hashtag ids.

None
hashtags_logical_and bool | None

Combine hashtag filters with AND (default OR).

None
post_types list[int] | None

Filter by post type ids (1=CUSTOM, 2=EVENTO, 3=QUESTIONARIO).

None
current_workflow_status_ids list[int] | None

Filter by workflow status ids.

None
visibility int | None

Filter by visibility (public/private).

None
followed_by_me bool | None

Only posts followed by the current user.

None
mentioned bool | None

Only posts where the current user was mentioned.

None
to_manage bool | None

Only posts the current user has actions to take on.

None
only_pinned bool | None

Only pinned posts.

None
post_field_filters list[PostFieldFilter | dict[str, Any]] | None

Custom-field filters — list of :class:PostFieldFilter or dicts with keys column_id/columnId, type_id/typeId, parameters.

None
screen_field_filters list[PostFieldFilter | dict[str, Any]] | None

Workflow screen-field filters (same structure).

None
validate_with PostDefinition | None

When supplied, validates post_field_filters and screen_field_filters against this community's post-definition before sending (no extra network call; raises :class:~pynteracta.exceptions.ValidationError).

None
community_post_filters dict[str, Any] | None

Pre-built communityPostFilters dict — escape hatch for the long-tail fields not promoted to explicit kwargs.

None
**filters Any

Additional camelCase fields forwarded to the request body (escape hatch).

{}
Source code in src/pynteracta/api/posts.py
def list_in_community(  # noqa: PLR0912, PLR0913, PLR0915
    self,
    community_id: int,
    *,
    page_token: str | None = None,
    page_size: int | None = None,
    calculate_total_items_count: bool | None = None,
    load_post_details: bool = True,
    load_main_attachment: bool | None = None,
    load_main_attachment_view_link: bool | None = None,
    load_main_attachment_download_link: bool | None = None,
    load_main_attachment_preview_image_link: bool | None = None,
    load_main_attachment_preview_image_animated_link: bool | None = None,
    load_main_attachment_preview_image_hi_res_link: bool | None = None,
    load_main_attachment_preview_image_hi_res_animated_link: bool | None = None,
    load_capabilities: bool | None = None,
    # --- ordering ---
    order_by: str | None = None,
    order_desc: bool | None = None,
    pinned_first: bool | None = None,
    # --- communityPostFilters (curated subset) ---
    title: str | None = None,
    description: str | None = None,
    contains_text: str | None = None,
    created_by_user_ids: list[int] | None = None,
    created_by_group_ids: list[int] | None = None,
    creation_timestamp_from: int | float | str | None = None,
    creation_timestamp_to: int | float | str | None = None,
    modified_timestamp_from: int | float | str | None = None,
    modified_timestamp_to: int | float | str | None = None,
    hashtag_ids: list[int] | None = None,
    hashtags_logical_and: bool | None = None,
    post_types: list[int] | None = None,
    current_workflow_status_ids: list[int] | None = None,
    visibility: int | None = None,
    followed_by_me: bool | None = None,
    mentioned: bool | None = None,
    to_manage: bool | None = None,
    only_pinned: bool | None = None,
    post_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
    screen_field_filters: list[PostFieldFilter | dict[str, Any]] | None = None,
    # --- opt-in validation ---
    validate_with: PostDefinition | None = None,
    # --- escape hatch ---
    community_post_filters: dict[str, Any] | None = None,
    **filters: Any,
) -> PostList:
    """POST ``/communication/posts/data/list/community/{communityId}``.

    Args:
        community_id: Target community.
        order_by: Sort field — one of :data:`POST_ORDER_FIELDS` or ``'postCustomField-{id}'``.
        order_desc: Descending sort (``True``) or ascending (``False``).
        pinned_first: Show pinned posts first.
        title: Filter on post title.
        description: Filter on post description.
        contains_text: Full-text filter on post content.
        created_by_user_ids: Filter by creator user ids.
        created_by_group_ids: Filter by creator group ids.
        creation_timestamp_from: Lower bound on creation date (epoch-ms, datetime, or ISO str).
        creation_timestamp_to: Upper bound on creation date.
        modified_timestamp_from: Lower bound on modification date.
        modified_timestamp_to: Upper bound on modification date.
        hashtag_ids: Filter by hashtag ids.
        hashtags_logical_and: Combine hashtag filters with AND (default OR).
        post_types: Filter by post type ids (1=CUSTOM, 2=EVENTO, 3=QUESTIONARIO).
        current_workflow_status_ids: Filter by workflow status ids.
        visibility: Filter by visibility (public/private).
        followed_by_me: Only posts followed by the current user.
        mentioned: Only posts where the current user was mentioned.
        to_manage: Only posts the current user has actions to take on.
        only_pinned: Only pinned posts.
        post_field_filters: Custom-field filters — list of :class:`PostFieldFilter` or dicts
            with keys ``column_id``/``columnId``, ``type_id``/``typeId``, ``parameters``.
        screen_field_filters: Workflow screen-field filters (same structure).
        validate_with: When supplied, validates ``post_field_filters`` and
            ``screen_field_filters`` against this community's post-definition before sending
            (no extra network call; raises :class:`~pynteracta.exceptions.ValidationError`).
        community_post_filters: Pre-built ``communityPostFilters`` dict — escape hatch for
            the long-tail fields not promoted to explicit kwargs.
        **filters: Additional camelCase fields forwarded to the request body (escape hatch).
    """
    if order_by is not None:
        _validate_order_by(order_by)

    # Coerce date kwargs to epoch-millis
    cf_from = to_epoch_millis(creation_timestamp_from)
    cf_to = to_epoch_millis(creation_timestamp_to)
    mf_from = to_epoch_millis(modified_timestamp_from)
    mf_to = to_epoch_millis(modified_timestamp_to)

    # Opt-in validation of field filters
    coerced_pff: list[PostFieldFilter] | None = None
    coerced_sff: list[PostFieldFilter] | None = None
    if post_field_filters is not None and validate_with is not None:
        coerced_pff = validate_field_filters(post_field_filters, validate_with)
    elif post_field_filters is not None:
        coerced_pff = [
            f if isinstance(f, PostFieldFilter) else PostFieldFilter.from_dict(f)
            for f in post_field_filters
        ]
    if screen_field_filters is not None and validate_with is not None:
        coerced_sff = validate_field_filters(screen_field_filters, validate_with, screen=True)
    elif screen_field_filters is not None:
        coerced_sff = [
            f if isinstance(f, PostFieldFilter) else PostFieldFilter.from_dict(f)
            for f in screen_field_filters
        ]

    # Build the complete communityPostFilters (SaaS-compatible: all fields present).
    # Priority: defaults → community_post_filters escape hatch → explicit kwargs.
    cpf: dict[str, Any] = dict(_DEFAULT_COMMUNITY_POST_FILTERS)
    if community_post_filters:
        cpf.update(community_post_filters)
    if title is not None:
        cpf["title"] = title
    if description is not None:
        cpf["description"] = description
    if contains_text is not None:
        cpf["containsText"] = contains_text
    if created_by_user_ids is not None:
        cpf["createdByUserIds"] = created_by_user_ids
    if created_by_group_ids is not None:
        cpf["createdByGroupIds"] = created_by_group_ids
    if cf_from is not None:
        cpf["creationTimestampFrom"] = cf_from
    if cf_to is not None:
        cpf["creationTimestampTo"] = cf_to
    if mf_from is not None:
        cpf["modifiedTimestampFrom"] = mf_from
    if mf_to is not None:
        cpf["modifiedTimestampTo"] = mf_to
    if hashtag_ids is not None:
        cpf["hashtagIds"] = hashtag_ids
    if hashtags_logical_and is not None:
        cpf["hashtagsLogicalAnd"] = hashtags_logical_and
    if post_types is not None:
        cpf["postTypes"] = post_types
    if current_workflow_status_ids is not None:
        cpf["currentWorkflowStatusIds"] = current_workflow_status_ids
    if visibility is not None:
        cpf["visibility"] = visibility
    if followed_by_me is not None:
        cpf["followedByMe"] = followed_by_me
    if mentioned is not None:
        cpf["mentioned"] = mentioned
    if to_manage is not None:
        cpf["toManage"] = to_manage
    if only_pinned is not None:
        cpf["onlyPinned"] = only_pinned
    if coerced_pff is not None:
        cpf["postFieldFilters"] = [f.to_dict() for f in coerced_pff]
    if coerced_sff is not None:
        cpf["screenFieldFilters"] = [f.to_dict() for f in coerced_sff]

    # Build the complete request body matching the SaaS payload structure.
    body: dict[str, Any] = {}
    if page_token is not None:
        body["pageToken"] = page_token
    if page_size is not None:
        body["pageSize"] = page_size
    if calculate_total_items_count is not None:
        body["calculateTotalItemsCount"] = calculate_total_items_count
    body["orderBy"] = order_by if order_by is not None else _DEFAULT_ORDER_BY
    body["orderDesc"] = order_desc if order_desc is not None else True
    body["communityPostFilters"] = cpf
    body["pinnedFirst"] = pinned_first if pinned_first is not None else True
    body["communityAttachmentFilters"] = dict(_DEFAULT_COMMUNITY_ATTACHMENT_FILTERS)
    for key, value in filters.items():
        if value is not None:
            body[snake_to_camel(key)] = value

    path = _LIST_COMMUNITY_PATH.format(community_id=community_id)
    params = build_query_params(
        load_post_details=load_post_details,
        load_main_attachment=load_main_attachment,
        load_main_attachment_view_link=load_main_attachment_view_link,
        load_main_attachment_download_link=load_main_attachment_download_link,
        load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
        load_main_attachment_preview_image_animated_link=(
            load_main_attachment_preview_image_animated_link
        ),
        load_main_attachment_preview_image_hi_res_link=(
            load_main_attachment_preview_image_hi_res_link
        ),
        load_main_attachment_preview_image_hi_res_animated_link=(
            load_main_attachment_preview_image_hi_res_animated_link
        ),
        load_capabilities=load_capabilities,
    )
    return PostList.from_dict(self._post(path, json=body, params=params))

list_in_community_raw(community_id, req, *, load_post_details=True, load_main_attachment=None, load_main_attachment_view_link=None, load_main_attachment_download_link=None, load_main_attachment_preview_image_link=None, load_main_attachment_preview_image_animated_link=None, load_main_attachment_preview_image_hi_res_link=None, load_main_attachment_preview_image_hi_res_animated_link=None, load_capabilities=None)

POST community post list with a pre-built request DTO (escape hatch).

Source code in src/pynteracta/api/posts.py
def list_in_community_raw(  # noqa: PLR0913
    self,
    community_id: int,
    req: ListCommunityPostsFilteredRequestDTO,
    *,
    load_post_details: bool = True,
    load_main_attachment: bool | None = None,
    load_main_attachment_view_link: bool | None = None,
    load_main_attachment_download_link: bool | None = None,
    load_main_attachment_preview_image_link: bool | None = None,
    load_main_attachment_preview_image_animated_link: bool | None = None,
    load_main_attachment_preview_image_hi_res_link: bool | None = None,
    load_main_attachment_preview_image_hi_res_animated_link: bool | None = None,
    load_capabilities: bool | None = None,
) -> PostList:
    """POST community post list with a pre-built request DTO (escape hatch)."""
    path = _LIST_COMMUNITY_PATH.format(community_id=community_id)
    params = build_query_params(
        load_post_details=load_post_details,
        load_main_attachment=load_main_attachment,
        load_main_attachment_view_link=load_main_attachment_view_link,
        load_main_attachment_download_link=load_main_attachment_download_link,
        load_main_attachment_preview_image_link=load_main_attachment_preview_image_link,
        load_main_attachment_preview_image_animated_link=(
            load_main_attachment_preview_image_animated_link
        ),
        load_main_attachment_preview_image_hi_res_link=(
            load_main_attachment_preview_image_hi_res_link
        ),
        load_main_attachment_preview_image_hi_res_animated_link=(
            load_main_attachment_preview_image_hi_res_animated_link
        ),
        load_capabilities=load_capabilities,
    )
    return PostList.from_dict(
        self._post(path, json=req.model_dump(mode="json", exclude_none=True), params=params)
    )