پرش به مستندات
Python

صفحه‌بندی

`list` برای یک صفحه، `list_all` برای همهٔ صفحه‌ها، و `iterate` برای هر بار یک آیتم.

یک صفحه: list

list_page.py
cursor: str | None = None while True:    page = client.emails.list(status='failed', limit=50, cursor=cursor)     for email in page['items']:        print(email['id'], email['lastError'])     if not page['hasMore'] or page['nextCursor'] is None:        break     cursor = page['nextCursor']

هر صفحه {'items': [...], 'hasMore': ..., 'nextCursor': ...} است. nextCursor را با همان فیلترها به‌عنوان cursor= پس بدهید تا صفحهٔ بعد از آن را بگیرید.

nextCursor روی آخرین صفحه None است، و hasMore می‌گوید آیا ردیف‌های مطابق دیگری پس از این صفحه هست یا نه. در openemail.types هر صفحه یک Page[T] است، پس emails.list یک Page[EmailResource] برمی‌گرداند و بررسی‌کنندهٔ نوع می‌داند هر آیتم چه چیزی در خود دارد.

API رشته‌ها و پیش‌نویس‌ها را با یک pageToken صفحه‌بندی می‌کند. کلاینت آن را به‌صورت nextCursor به شما می‌دهد و به‌صورت cursor= پس می‌گیرد، مثل هر فهرست دیگری، و list_all و iterate آن را برایتان دنبال می‌کنند. این مقدار مات است: همان چیزی را که گرفته‌اید بازبفرستید و هرگز خودتان یکی نسازید.

همهٔ صفحه‌ها: list_all

list_all.py
complaints = client.suppressions.list_all(reason='complaint')print(len(complaints), [row['email'] for row in complaints]) book = client.addresses.list_all()print(book['unrestricted'], len(book['addresses']), len(book['domains']))

list_all تا آخرین صفحه nextCursor را دنبال می‌کند و یک list برمی‌گرداند. پیش از برگشتنش همهٔ صفحه‌ها گرفته می‌شوند، پس فیلتری به آن بدهید که تمام شود.

addresses.list_all تنها موردی است که چیز دیگری برمی‌گرداند: کل دفترچهٔ نشانی‌ها، {'unrestricted': ..., 'addresses': [...], 'domains': [...]}، با نشانی‌های همهٔ صفحه‌ها در آن.

یکی‌یکی: iterate

iterate.py
from itertools import islice for email in client.emails.iterate(status='bounced'):    if email['createdAt'] < '2026-09-01':        break     print(email['id'], email['lastError']) first_ten = list(islice(client.threads.iterate(folder='inbox'), 10))print([thread['id'] for thread in first_ten])

iterate یک ژنراتور برمی‌گرداند. فراخوانی آن چیزی نمی‌فرستد: صفحهٔ نخست وقتی گرفته می‌شود که حلقه نخستین آیتمش را بخواهد، و هر صفحهٔ بعدی فقط وقتی که حلقه به پایان صفحهٔ پیشین برسد. بیرون آمدن از حلقه، یا برداشتن یک برش با itertools.islice، درخواست‌ها را متوقف می‌کند.

limit= روی list_all و iterate اندازهٔ هر صفحه‌ای است که می‌گیرند، نه سقفی بر تعداد آیتم‌هایی که به دست می‌آورید، پس limit بزرگ‌تر یعنی درخواست‌های کمتر. cursor= پیمایش را از صفحه‌ای آغاز می‌کند که از پیش در دست دارید. هر دو وقتی می‌ایستند که hasMore برابر false یا nextCursor برابر None باشد، و همچنین وقتی صفحه‌ای همان cursorی را نام ببرد که آن را آورده است، تا صفحه‌ای که بد رفتار می‌کند نتواند تا ابد حلقه بزند.

فهرست‌های درون یک فضای نام

list_all و iterate همان اندپوینتی را صفحه‌به‌صفحه می‌پیمایند که list کنارشان می‌پیماید، و همین‌طور جفت‌های دیگری که به نام فهرستی که می‌پیمایند نام‌گذاری شده‌اند. هر جفت همان فیلترهای فهرست خودش را می‌گیرد.

فضای نامیک صفحههمهٔ صفحه‌هایکی‌یکی
emailslist_eventslist_all_eventsiterate_events
calendarlist_eventslist_all_eventsiterate_events
templateslist_versionslist_all_versionsiterate_versions
templateslist_imageslist_all_imagesiterate_images
trackinglist_openslist_all_opensiterate_opens
trackinglist_clickslist_all_clicksiterate_clicks
ruleslist_runslist_all_runsiterate_runs
audienceslist_contactslist_all_contactsiterate_contacts
broadcastslist_recipientslist_all_recipientsiterate_recipients
contactslist_peoplelist_all_peopleiterate_people
contactslist_threadslist_all_threadsiterate_threads
domainslist_addresseslist_all_addressesiterate_addresses
formslist_submissionslist_all_submissionsiterate_submissions
memberslist_invitationslist_all_invitationsiterate_invitations
fileslist_linkslist_all_linksiterate_links
temp_maillist_messageslist_all_messagesiterate_messages
webhookslist_deliverieslist_all_deliveriesiterate_deliveries
webhookslist_workspace_deliverieslist_all_workspace_deliveriesiterate_workspace_deliveries
webhookslist_activitylist_all_activityiterate_activity
webhookslist_workspace_activitylist_all_workspace_activityiterate_workspace_activity
keyslist_requestslist_all_requestsiterate_requests
keyslist_activitylist_all_activityiterate_activity
keyslist_workspace_requestslist_all_workspace_requestsiterate_workspace_requests
keyslist_workspace_activitylist_all_workspace_activityiterate_workspace_activity

صفحه‌هایی که چیزهای بیشتری دارند

other_pages.py
people = client.contacts.list_people(sort='recent', limit=50)print(len(people['items']), people['seen'], people['nextCursor']) sends = client.templates.list_sends('order-shipped', page=2, page_size=50)print(sends['total'], sends['page'], sends['pageSize'], len(sends['items']))

چند فهرست چیزی بیش از یک صفحه دارند. contacts.list_people در کنار items، hasMore و nextCursor فیلد seen را می‌افزاید، temp_mail.list_messages فیلد expiresAt را می‌افزاید، و addresses.list به‌جای items، addresses را برمی‌گرداند، در کنار unrestricted، domains، hasMore و nextCursor. هر کدام همچنان با cursor= ادامه می‌یابد و با list_all و iterate خودش پیموده می‌شود.

دو فهرست به شیوهٔ دیگری صفحه‌بندی می‌شوند. templates.list_sends صفحه‌ها را می‌شمارد: page= و page_size= را بدهید و total، page و pageSize را در کنار items بخوانید. imports.list_failures همان‌طور که API می‌فرستد رها می‌شود، {'object': 'list', 'data': [...], 'nextCursor': ...}، و با after=، یعنی عددِ درون nextCursor، ادامه می‌یابد. هیچ‌کدام list_all یا iterate ندارند.

اندازهٔ صفحه‌ها

بیشتر فهرست‌ها یک limit= از 1 تا 100 با پیش‌فرض 25 می‌گیرند، همان دو عدد در PAGE_LIMITS (PAGE_LIMITS.MAX_LIMIT و PAGE_LIMITS.DEFAULT_LIMIT). contacts.list، audiences.list_contacts، broadcasts.list_recipients و فهرست‌های tracking تا 200 را با پیش‌فرض 50 می‌پذیرند، و temp_mail.list_messages تا 50 را می‌پذیرد. مقداری بیرون از این بازه، به‌جای آنکه به مرز بازه بریده شود، با یک 422 رد می‌شود.

روی AsyncOpenEmail

کلاینت ناهمگام هم به همین شیوه صفحه‌بندی می‌کند. list و list_all با await فراخوانی می‌شوند، و iterate یک iterator ناهمگام برمی‌گرداند که با async for روی آن حلقه می‌زنید، بی‌آنکه جلوی فراخوانی await بگذارید.

async_pages.py
import asyncio from openemail import AsyncOpenEmail  async def main() -> None:    async with AsyncOpenEmail() as client:        page = await client.emails.list(status='failed', limit=50)        print(len(page['items']), page['nextCursor'])         everyone = await client.members.list_all()        print(len(everyone))         async for delivery in client.webhooks.iterate_deliveries('whe_…', status='failed'):            print(delivery['eventType'], delivery['responseCode'])  asyncio.run(main())