Python
Changelog
Every release of the package, newest first.
0.0.3
The third release adds the 73 methods the TypeScript SDK gained since 0.0.2, so it covers all 558 again.
threads.muteandthreads.unmutemute a conversation and take the mute off, as Mute does in the app, and both needthreads:write. A muted thread in the inbox moves to the archive, and new mail in it goes straight to the archive, unread, with no push, sound or desktop notification. Muting is for the whole workspace, a muted thread carries the built-inMUTElabel, andis:mutedfinds it inquery.- The inbox has tabs: Primary, Promotions, Updates, Social and Forums.
threads.list,list_allanditeratetakecategory=to read one tab, andcategory:promotionsfilters the same way inquery.threads.countsreturnscategories, the conversations and unread conversations of the inbox in each tab. threads.list_sender_categories,set_sender_categoryandclear_sender_categorymanage the senders whose mail always goes to one tab, whatever the sorting rules would say. Saving a choice also moves the inbox threads whose newest message is from that sender, up to the newest 1,000. A key limited to particular addresses or domains can read the choices but not change them.- The new
follow_upsnamespace holds the reminders on mail you sent:setasks for a thread to come back to the top of the inbox, unread, with the built-inFOLLOW_UPlabel and a push, if nobody replies byremindAt,listreads the reminders still waiting and the ones that ended, andcancelcancels one. A real reply closes the reminder by itself, and a thread holds one waiting reminder per person, so setting another moves the time.emails.sendand each message ofemails.send_batchtakefollowUpAtto set a reminder as the message goes out: adatetime, an ISO 8601 instant or a duration such asP3D. - The new
out_of_officenamespace manages the automatic reply an address sends while its owner is away.setsaves the reply of one address, or of a catch-all with*@example.com, with its message, subject, start, end andcontactsOnly,listreads every reply saved in the workspace, andclearremoves one. While a reply is active, each person who writes gets the message once for the whole away period, and spam, bulk mail, automatic mail and bounces get no reply. - Labels can be applied by AI:
labels.createandlabels.updatetakeaiInstructions, what the label is for in plain words, andaiEnabled, which has AI read each arriving message against them and add the label when it fits. It only labels and never archives or moves mail, turning it on needs instructions and a paid plan, and a workspace may have 10 such labels.labels.testruns the AI over the newest 20 inbox threads and returns the ones the label would catch, without labelling anything, and spends one AI action. settings.getandsettings.updatecarry three more account settings:inboxTabsshows the inbox as tabs,primaryOnlyAlertskeeps pushes, sounds and desktop notifications to mail sorted into Primary while tabs are on, andphoneFollowUpssends a push when a reminder comes due.- Mail travels in two lanes, so a newsletter cannot hold up or harm app mail.
emails.send, each message ofemails.send_batchandtemplates.sendtakestream:transactional, the default, for mail one person is waiting for, orbroadcastfor newsletters. Every email carries thestreamit went out on, and every copy of a broadcast is on the broadcast lane. - The new
sendingnamespace reads the lanes:list_streamsreturns both with their state and their numbers for the last 7 days, which are recipients, bounces, complaints and the two rates. The broadcast lane pauses itself above 4% bounces or 0.2% complaints, a send to it is then refused with 409stream_paused, and app mail keeps going.resume_streamresumes it, for the workspace owner, and asks an app for a verification code. tools.check_addresssays whether an address is worth sending to before the first message:valid,risky,invalidorunknown, with the reasons. It checks the syntax, whether the domain takes mail, throwaway domains and shared addresses such asinfo@, suggests a correction for a likely typo, and withemails:readadds what the workspace knows about the address.deep=Truealso asks whether the mailbox exists, which is billed per address through pay as you go and needsemails:send, andtools.check_addresseschecks up to 100 in one call.- A workspace on Business or Enterprise that sends at least 100,000 emails a month can buy a dedicated sending IP. For the workspace owner,
billing.list_add_onssays whether it is for sale, what it costs, whether the workspace qualifies and whether it has one,billing.start_add_on_checkoutreturns the link where the person pays, andbilling.cancel_add_onends it at the end of the month already paid for.sending.list_dedicated_ipsandsending.get_dedicated_ipread each IP with itsstatusandwarmupPercent, since a new IP is warmed up over several weeks. domains.get_mail_app_settingsreturnssmtpSubmission, the SMTP server on port 587 for apps, devices and libraries that only offer STARTTLS. Itssecurityisstarttls, a new member ofMAIL_APP_SECURITIES, and it takes the same username and app password assmtp.importscan read a live mailbox, as the Migrations page of the app does:discover_mailboxfinds the mail server for an address,check_mailboxsigns in once and lists the folders and how many messages an import would bring, andconnect_mailboxstarts copying the mailbox into one address, withcontactsandcalendarsto bring those across too. The old mailbox is only ever read, a message the address already holds is skipped, and the password is kept sealed until the import finishes and for 30 days at most. An import waits by itself when the old provider slows it down, with thestatusparked, and when the password stops working it isneeds-passwordandresumesends a new one.- Every import carries
source,remoteandchildren, andImportFormatgainsimapandmicrosoft. calendar.import_icsandcontacts.import_vcftake an iCalendar or vCard file as bytes and queue it. Events become events of your own and nobody on them is sent anything, cards become contact cards that join no audience, and what is already here is left as it is and counted, so sending a file twice adds nothing.list_imports,list_all_importsanditerate_importsread the imports of each kind,get_importreads one with its counts and a report of what it left out and why, andundo_importdeletes everything an import added.me.list_requests,me.list_activityandme.statslet a key read its own request log, its own history and its own figures with no scope at all, so a key that can only send can still watch itself. They read the calling key and nothing else:keys.list_requests,keys.list_workspace_requestsandkeys.statsare still the ones that reach other keys, behindkeys:read.me.statsfillssendsonly when the key holdsemails:readand leaves itNoneotherwise, and an OAuth access token is refused with 403api_key_only, because calls made with one are not logged.- Every reader of the request log, in
meand inkeys, takes two more filters:statuses=keeps the calls answered with one of up to 20 exact HTTP status codes, andpath=keeps the calls to one route, whatever the method.path=matches the route, not the exact path: an id counts as:idand an email address as:address, so/emails/:idreads the calls made to any single email, and a path that ends in*reads every route that starts with it. Both combine withfailed_only=,since=anduntil=. - The new
automationsnamespace holds emails and other steps that run by themselves for each contact: a welcome series when somebody joins an audience, a nudge after a trial starts, a note on a birthday. You edit a draftdefinitionandpublishit, which saves a numbered version and sets the automation live, and each contact stays on the version they entered on.list,list_all,iterate,get,create,updateanddeletemanage them,list_startersreturns ready-made definitions,pause,resume,archiveandduplicatechange their state,send_testsends the email of one step to one address,list_versionsandrestore_versionread the published versions and copy one back into the draft, andstatsreturns totals, per-step numbers and a daily series. list_enrollments,list_all_enrollments,iterate_enrollmentsandget_enrollmentread who is in an automation and what each step did for them,enrollputs a contact in andexit_enrollmenttakes one out. Reading needsautomations:readand every changeautomations:write, andpublish,resumeandsend_testalso needemails:send. A draft that cannot run is refused with 422invalid_automation, andproblemson the error lists every problem that blocks it.- The new
eventsnamespace records what your contacts did, from your own code:sendstores one event against a contact, starts every live automation whose trigger names it and ends the waits that were holding out for it,send_batchrecords up to 100 in one call and reports per event, andlist_namesreturns the event names the workspace has seen. Both sends carry anIdempotency-Key, generated per call or passed asidempotency_key=, so a retry never records an event twice, and a key or an app may send 600 events a minute.contacts.list_events,list_all_eventsanditerate_eventsread the events of one contact. WEBHOOK_EVENTSgainedautomation.entered,automation.exited,automation.pausedandautomation.webhook. Likeform.*, they belong to the whole workspace, have to be named ineventTypes, and never reach an endpoint limited to some addresses or domains.- A sign-up form field can fill more of the contact:
mapsToalso takesphone,company,jobTitle,websiteandbirthday, saved on the contact card when the sign-up is accepted and only where the card has nothing yet. A single contact now comes withsignUps, its last 20 sign-ups with their answers, for a caller that holdsforms:read.
0.0.2
The second release adds the 55 methods the TypeScript SDK gained since 0.0.1, so it covers all 485 again.
contacts.list_cards,list_all_cards,iterate_cards,get_card,create_card,update_cardanddelete_cardread and write the address book as contact cards, with phone numbers, postal addresses, websites, organisation, job title, birthday and the name in parts. Phones and computers that sync the address book over CardDAV get every change on their next sync.calendar.list_feeds,create_feed,reset_feedanddelete_feedmanage secret links that publish the calendar to Google Calendar, Outlook or Apple Calendar, andlist_subscriptions,create_subscription,update_subscription,refresh_subscriptionanddelete_subscriptionmanage the calendars you subscribe to by link.respond_to_eventcan propose a new time, anddecline_proposalkeeps the original one.- Every event carries
subscriptionId,rdatesandrecurrenceId, for the subscription it comes from, the occurrences added outside its rule and the start a changed occurrence replaces. domains.get_mail_app_settings,list_app_passwords,create_app_password,update_app_password,delete_app_passwordandsend_mail_app_setupput an address into Apple Mail, Gmail, Outlook, Thunderbird or any other mail app over IMAP, SMTP and POP3, and its calendar and contacts over CalDAV and CardDAV.update_mail_app_settingsturns each kind of connection on or off.domains.updatetakessenderName, the name mail from a domain goes out under when the sending address has no name of its own.knowledgeis new: the notes, files and web pages the AI uses when it writes replies, drafts email and answers in the assistant. It lists, searches, adds, refreshes and removes items, suggests notes, flags duplicates and conflicts, and keeps sites, sitemaps, feeds and Zendesk help centers in step through connectors.threads.reply_suggestionsreads the replies the reading pane suggests under the latest message of a thread.settings.updatetakesreplySuggestions,semanticSearchandknowledgeLearningto turn those features off for the workspace.threads.list,list_allanditeratetakesemanticto match the words of a query by meaning, andaddressto keep the threads delivered to one address.tracking.list,list_all,iterateandget_statstakeaddresstoo.emails.composetakesdraft,withSubject,from,bcc,send,timeZone,template,templatesandfiles, so one description can write or change a whole email.tools.read_verification_codefinds the sign-in or verification code in a message, andtools.estimate_costprices every plan for a usage. Neither needs a scope.settings.getandsettings.updatereach every setting the app has:@domainsets a whole domain, andNonelets a scope inherit again.drafts.createtakesforwardOfto forward a message, andtemplates.publishtakesexpected_version.provider_importsmoves an account across from SendGrid, Postmark, Mailgun and Mailchimp as well as Resend, andthreads.countscounts drafts and labels too.IMPORT_FORMATSandImportFormatincludeproton, the format a mailbox import reports for a Proton Mail export.- The messages
threads.getreturns carrysentWith,forwardedFromandverificationCode, andsenders.getandsenders.researchshare what is known about a domain with every workspace. drafts.updatekeeps the attachments and the forward of a draft,settings.updatewithworkspaceNamerenames the workspace, and thesecurity.verify_step_updocs list all 40 calls that ask for a verification code.
0.0.1
The first release. It covers the whole TypeScript SDK as it stood when this release was cut: 430 methods in 41 namespaces, each under its TypeScript name in snake_case. A parity check proves that every one of them sends exactly the request its TypeScript twin sends, once with no options and once with every option set.
NextmailandAsyncNextmailhave an attribute for every namespace, fromemails,threadsandtemplatestoprovider_imports,dns_connectionsandaccount.listAllislist_all,getActiveisget_active, andtempMailistemp_mail.- A request body is a dict whose keys keep the API’s camelCase names, the options of a call are snake_case keyword arguments such as
idempotency_key=andlimit=, and a response comes back as a dict. Every body and result has aTypedDictinnextmail.types, named as in TypeScript. AsyncNextmailhas the same methods with the same arguments, awaited, and runs on asyncio and on trio.- Every paginated resource has
listfor one page,list_allfor every item as a list, anditerate, which yields items and fetches the next page only when it gets there. - An API refusal raises
NextmailApiError, withstatus,type,code,paramandrequest_id, andis_validation,is_not_found,is_rate_limited,is_step_up_required,is_retryableand the other checks. No response at all raisesNextmailNetworkError, withis_timeoutwhen the deadline passed. from nextmail import nextmailis a ready-made client built fromNEXTMAIL_API_KEYthe first time it is touched, andinitconfigures it once at startup.create_temp_mailandcreate_async_temp_mailopen disposable inboxes with no credential.access_token=takes an OAuth access token or a function that returns one, called before every request.verify_webhook_signaturechecks a delivery in constant time and returns the parsed event.client.raw.requestreaches an endpoint no method wraps yet.- Reads are retried on 408 and 5xx, and a 429 only when it carries
Retry-After.timeoutbounds the whole attempt, the response body included, and a credential is never sent over plain HTTP except to a server on this machine. - It needs Python 3.10 or newer, and depends only on
httpx,anyioandtyping-extensions.