Kalo te dokumentacioni
API

Bisedat

Çdo veprim në këtë grup: çfarë pranon, çfarë kthen dhe gabimet me të cilat mund të përgjigjet.

Veprimet

GET/threads

List threads in a folder

Lejetthreads:readLexon

Reads the local index. Passing query searches that same index.

Plain words must all appear, and each one matches loosely: case, accents and separators are ignored and part of a longer word counts, so min and ben jamin both find "Benjamin". A quoted phrase is matched as written apart from case and accents, so its separators have to line up: "ben jamin" does not find "Ben-Jamin", while "quarterly invoice" finds "Quarterly invoice". When nothing matches exactly, close spellings are returned instead, so benjimin finds "Benjamin": a plain word, or the value of from:, to:, cc:, subject:, body:, filename: or label:, may differ from the start of a word by one typo (a changed, missing, extra or swapped letter) when it has four to seven letters and by two when it has eight or more, while a quoted phrase, a word containing a digit, a shorter word and an excluded word still match exactly, and the pages that follow keep matching the same way. Filler words are dropped from a list of plain words when something else is left to search for, so mail server searches for server alone and emails from john searches for john. The filler is a, an, the, and, or, of, to, from, for, about, with, in, on, at, by, my, me, all, any, some, show, find, get, email, emails, mail, mails, message, messages, thread and threads, and it is kept when dropping it would leave nothing but a single letter.

Operators narrow the search: from:, to:, cc:, subject:, body:, label:, filename:, in: (inbox, sent, drafts, spam, trash, archive, snoozed, anywhere or a label name), is: (unread, read, starred, important, snoozed, muted, draft, sent), has: (attachment, pdf, image, video, audio, document, spreadsheet, presentation, userlabels, nouserlabels), after:YYYY/MM/DD, before:YYYY/MM/DD, newer_than:7d and older_than:1y (units h, d, w, m, y). Combine them with OR, AND, NOT, parentheses, braces for a set of alternatives ({stripe paddle}) and a leading - to exclude. Recipients are stored as one list without roles and never hold a Bcc, so cc: reads the same field as to: and bcc: matches nothing of its own. from:me is mail you sent, and to:me is mail carrying one of your own addresses, aliases included, among its recipients or as the address it was delivered to.

A value the search cannot use is ignored rather than narrowing, so a typo in a value widens the result instead of emptying it. Ignored: category:, larger:, smaller:, size:, messagesize:, list:, rfc822msgid:, received:, sent:, the category words (is:primary, is:personal, is:social, is:promotions, is:updates, is:forums, is:reservations, is:purchases), a has: word that names none of the kinds above, an importance: other than high or low, a date that cannot be read, and a duration whose unit is not h, d, w, m or y. An operator name it does not know, project: for instance, is searched as plain text instead.

Words and the from:, to:, cc:, subject: and body: operators read only the newest message on each thread: its sender, its recipients, its subject and the first 4,000 characters of its body. filename: and has: read every attachment on the whole conversation, and label:, in: and is: read the whole conversation. A plain word also matches the name of any attachment on the conversation, whichever message carried it. A message that arrived encrypted has no body text to match. folder still applies unless the query names one with in:, or with an is: that is a folder such as is:sent, and in:anywhere searches every folder, on its own as well as beside other terms. A drafts listing is the exception: GET /drafts and GET /threads?folder=draft stay in drafts whatever the query names.

Dates read the newest activity on the thread, in UTC. after: includes the day it names and before: excludes it. A date can be written YYYY/MM/DD, YYYY-MM-DD, YYYYMMDD, as a bare year, or as epoch seconds or milliseconds; A short date reads day first (16/09/2026), unless the second number cannot be a month (09/16/2026), and a number above 12 settles it either way. A day that does not exist is rejected and ignored.

nextPageToken is opaque. Pass back what you were given, never construct one.

Requires the threads:read scope.

Parametrat e pyetjes

folderstring

Label the threads must carry, case insensitive. Defaults to inbox, and bin is read as trash.

Parazgjedhja"inbox"
querystring

Mailbox search. Plain words must all appear and match loosely, ignoring case, accents and separators, against the newest message on each thread and the name of any attachment on it, while a quoted phrase has to appear as written and filler words such as the or emails are dropped when something else is left to search for. Operators such as from:ada, label:Invoices, is:unread, has:pdf and newer_than:7d narrow it, and naming a folder with in: replaces folder, so in:anywhere searches them all. When nothing matches exactly, close spellings are returned instead, so benjimin finds "Benjamin". A value the search cannot use is ignored rather than narrowing.

labelIdsstring

Comma-separated label ids. A thread must carry every one of them and sit in folder, which is how the app filters a folder by a label. To list a label's threads whichever folder they are in, pass its id as folder instead: folder=USER_BIG_CLIENTS.

sortstring

The four orders of the thread list: newest, oldest, sender and subject. sender and subject are alphabetical, newest first within one sender or subject. Threads that arrived in the same instant are ordered by id, so every order pages to the end without skipping or repeating one.

Një nga"newest""oldest""sender""subject"Parazgjedhja"newest"
dateFromstring

Keeps threads whose newest message arrived at or after this instant. ISO 8601 with a time and an offset, such as 2026-09-01T00:00:00Z.

Formatidate-time
dateTostring

Keeps threads whose newest message arrived at or before this instant. Both ends are included, and dateFrom after dateTo is a 422.

Formatidate-time
fromContactsstring

true keeps only threads whose newest message came from a saved contact, the From contacts filter of the thread list. A key limited to particular addresses reads the contacts its owner saved, and an app acting for a member reads the contacts that member saved.

Një nga"true""false"
limitinteger

Threads per page, a whole number from 1 to 100. Defaults to 25.

Të paktën 1Më së shumti 100
pageTokenstring

The previous page's nextPageToken, passed back as it came. Send the same sort, dates and filters with it.

Kthen

200

A page of threads.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.list()threads.listAll()threads.iterate()
CLI
openemail threads list
MCP
listThreads

GET/threads/{id}

Retrieve a thread

Lejetthreads:readLexon

Every message in it, not only the most recent.

The messages are passed through as the mailbox stored them rather than projected onto a field list, and this document describes only encryption, which is the one field whose absence a caller cannot safely guess at. A message that arrived encrypted carries it and has an EMPTY BODY; read encryption.format before concluding a message was empty, and note that the two *-signed formats are ordinary readable mail.

Requires the threads:read scope.

Parametrat e shtegut

idstringE detyrueshme

Thread id, as returned by list or carried on a message.

Kthen

The thread, with every message on it.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.get()
CLI
openemail threads get
MCP
getThread

PATCH/threads/{id}

Mark read/unread and change labels

Lejetthreads:writeNdryshon të dhëna

Applies and removes labels, and sets read state, on one conversation. Label ids come from GET /labels; the system ids INBOX, ARCHIVE, STARRED, IMPORTANT, SPAM and UNREAD are taken in any case, so archiving is addLabelIds: ["ARCHIVE"] with removeLabelIds: ["INBOX"]. An id in addLabelIds that names no label is a 422 label_not_found, and nothing on the thread changes: create the label with POST /labels first. An unknown id in removeLabelIds is not an error, since the thread does not carry it. TRASH, SNOOZED and DRAFT are refused with label_not_directly_settable; use the trash and snooze endpoints.

Requires the threads:write scope.

Parametrat e shtegut

idstringE detyrueshme

Thread id.

Trupi i kërkesës

readboolean

true removes UNREAD and false adds it.

addLabelIdsstring[]

Label ids to put on the thread. Each must name a label.

Deri në 50 elemente
removeLabelIdsstring[]

Label ids to take off the thread.

Deri në 50 elemente

Kthen

200

Applied.

Gabimet

422

label_not_found for an id in addLabelIds that names no label, or label_not_directly_settable for TRASH, SNOOZED or DRAFT.

Gabimet që mund të kthejë çdo veprim400401403404500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.update()
CLI
openemail threads update
MCP
markThreadsReadmarkThreadsUnreadmodifyLabelsrestoreThreads

DELETE/threads/{id}

Delete a thread for good

Lejetthreads:writeFshin

Deletes every message in the thread, with its attachments, and cannot be undone, which is what Delete from Bin does in the app. It works on a thread in any folder, so move it to the Bin with POST /threads/{id}/trash when you only mean to throw it away.

Requires the threads:write scope.

Parametrat e shtegut

idstringE detyrueshme

The thread, as GET /threads returns it.

Kthen

Gone for good.

Gabimet

500

thread_delete_failed: the thread could not be deleted, and nothing was removed.

Gabimet që mund të kthejë çdo veprim400401403404422Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.delete()
CLI
openemail threads delete
MCP
deleteThreadsForever

POST/threads/{id}/trash

Move a thread to the Bin

Lejetthreads:writeFshin

Clears INBOX, SPAM, SNOOZED and ARCHIVE together, which is what the app does. Adding the TRASH label by hand through PATCH is refused, because doing only half of it leaves the thread listed in the Bin AND its old folder.

Requires the threads:write scope.

Parametrat e shtegut

idstringE detyrueshme

Thread id.

Kthen

200

Trashed.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.trash()
CLI
openemail threads trash
MCP
trashThreads

POST/threads/{id}/snooze

Snooze a thread

Lejetthreads:writeNdryshon të dhëna

Hides it and schedules its return. Both halves happen together: the label hides it, a stored wake time brings it back, and a thread snoozed by label alone never returns.

Requires the threads:write scope.

Parametrat e shtegut

idstringE detyrueshme

Thread id.

Trupi i kërkesës

wakeAtstringE detyrueshme
Formatidate-time

Kthen

200

Snoozed.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.snooze()
CLI
openemail threads snooze
MCP
snoozeThreads

POST/threads/{id}/unsnooze

Unsnooze a thread

Lejetthreads:writeNdryshon të dhëna

Brings it back now and cancels the scheduled return.

Requires the threads:write scope.

Parametrat e shtegut

idstringE detyrueshme

Thread id.

Kthen

200

Back in the inbox.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.unsnooze()
CLI
openemail threads unsnooze
MCP
unsnoozeThreads

GET/threads/{id}/messages/{messageId}/attachments

A message's attachments

Lejetthreads:readLexon

content is base64, and an empty string where the stored bytes could not be found.

This is the DISPLAY list. Of the parts named by a message's encryption.parts, the ciphertext part IS listed and downloads like any other file (it is the message, and downloading it is the only way an API client reads this mail). The PGP/MIME version part and any detached signature are held out deliberately, because they rendered as junk attachments and there is nothing a caller can do with them. Both keep their ids in encryption.parts, which correlates the two views, and this endpoint does not return them.

Requires the threads:read scope.

Parametrat e shtegut

idstringE detyrueshme

Thread id the message belongs to.

messageIdstringE detyrueshme

Message id from that thread's messages.

Kthen

200

Attachments.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.listAttachments()
CLI
openemail threads list-attachments

GET/threads/counts

Count the mail in each folder

Lejetthreads:readLexon

What the sidebar of the app shows: how many conversations each folder holds and how many of them are unread, and how many inbox conversations arrived at each address. unread is a pseudo-folder whose count is the unread conversations in the inbox. A key or an app limited to particular addresses counts only the mail that arrived at them, and address narrows the counts to one address, never wider than that.

Requires the threads:read scope.

Parametrat e pyetjes

addressstring

Count only the mail delivered to this address. One the key does not reach counts nothing rather than failing.

Nga 3 deri në 320 karaktere

Kthen

The counts.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.counts()
CLI
openemail threads counts
MCP
getMailboxCounts

GET/threads/{id}/summary

Read the summary of a thread

Lejetthreads:readLexon

The short AI summary the reading pane shows above a thread. It is written once and kept, and written again when a new message arrives, so reading it is cheap. state is ready with the summary, pending while one is being written (ask again in a few seconds), or none when there is nothing to summarise, such as a thread holding a message that arrived encrypted. Writing a summary spends one of the workspace's AI actions.

Requires the threads:read scope.

Parametrat e shtegut

idstringE detyrueshme

The thread, as GET /threads returns it.

Kthen

The summary, or the state it is in.

Gabimet

Gabimet që mund të kthejë çdo veprim400401403404422500Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.summary()
CLI
openemail threads summary
MCP
getThreadSummary

POST/threads/{id}/restore

Take a thread out of the Bin

Lejetthreads:writeNdryshon të dhëna

Puts a thread back in the inbox, out of the Bin and out of Spam, which is what Restore from Bin and Move to inbox do in the app. It is the undo of POST /threads/{id}/trash, and calling it again changes nothing.

Requires the threads:write scope.

Parametrat e shtegut

idstringE detyrueshme

The thread, as GET /threads returns it.

Kthen

Back in the inbox.

Gabimet

500

thread_update_failed: the labels could not be written, and nothing on the thread changed.

Gabimet që mund të kthejë çdo veprim400401403404422Katalogu i gabimeve

E disponueshme edhe në

SDK
threads.restore()
CLI
openemail threads restore
MCP
modifyLabelsrestoreThreads

Objektet

DeletedThreadobject

objectstring
Një nga"thread"
idstring
deletedboolean
Një ngatrue

MailboxCountsobject

objectstringE detyrueshme
Një nga"mailbox_counts"
foldersobject[]E detyrueshme
labelstringE detyrueshme

The folder, as its label id in lower case.

Një nga"inbox""sent""spam""archive""trash""snoozed""unread"
countintegerE detyrueshme

Conversations in the folder.

unreadintegerE detyrueshme

How many of them are unread.

addressesobject[]E detyrueshme
addressstringE detyrueshme

The address the mail arrived at, or null for mail that recorded none.

Mund të jetë null
countintegerE detyrueshme

Inbox conversations delivered to it.

MessageEncryptionobject

What kind of encryption this message arrived carrying, read off its top-level Content-Type when it was ingested.

ABSENCE MEANS NOBODY LOOKED. The field is omitted on every message stored before detection existed. It never means "checked, and found none". A client reading a missing encryption as "this was plaintext" is asserting something no part of this system measured.

It is a statement about the ENVELOPE and not a verification. A message can be seen to be sealed without being opened, and those are different claims: nothing here says a signature checked out, says who holds a key, or licenses a padlock in a user interface.

SIGNED IS NOT SEALED, and that distinction is the whole reason format is an enum rather than a flag. For the three sealed formats the message's body fields are empty or hold PGP armor, and an empty body on such a message means "we cannot read this" rather than "there was nothing here". For the two signed formats the body is ordinary text and every consumer keeps working on it.

formatstringE detyrueshme

Which of the five envelope shapes was recognised. THREE of them mean the body is unreadable (pgp-mime, pgp-inline and smime-encrypted), and the other two, pgp-signed and smime-signed, mean the body arrived in the clear beside a detached signature and is read exactly like any other message. Branch on this value; branching on the mere presence of the object treats readable mail as unreadable.

Një nga"pgp-mime""pgp-signed""pgp-inline""smime-encrypted""smime-signed"
detectedAtstringE detyrueshme

When the classification was made, on our clock at ingest. It dates OUR READING of the envelope and says nothing about when the message was encrypted or signed, or by whom.

rawRetainedboolean

Whether the original RFC822 bytes were kept, so that something holding the key could open the message later. Today it is always false. Nothing retains the raw message yet. It is published now so a client can start reading it rather than needing a second pass over every stored message the day that changes.

Parazgjedhjafalse
partsobject[]

The envelope parts, each named by the id its bytes were written under. They are deliberately NOT in the message's attachment list (a PGP/MIME message would otherwise render two junk chips), so a sealed message commonly reports no attachments at all, and that emptiness is not evidence that nothing was attached. These ids are a CORRELATION KEY and not a handle: GET /threads/{id}/messages/{messageId}/attachments serves the display list, so it does not return them, and no other path in this API returns them either. index is the index into the original MIME parts.

indexintegerE detyrueshme
attachmentIdstringE detyrueshme
rolestringE detyrueshme
Një nga"version""ciphertext""signature"

RestoredThreadobject

objectstring
Një nga"thread"
idstring
restoredboolean
Një ngatrue

Threadobject

objectstring
Një nga"thread"
idstring

The id that was asked for. Echoed back rather than read off the result. The mailbox answers a thread as messages, labels and counts, with no id of its own.

messagesThreadMessage[]

Every message on the thread, oldest first, not only the most recent.

labelsobject[]

The folders and labels the thread sits in. Backend-shaped like the messages are, so only the two fields every backend agrees on are described.

idstring
namestring
messageCountinteger

The length of messages, counted here.

hasUnreadboolean
totalRepliesinteger
deliveredTostring

The workspace address the thread belongs to, lower-cased: the address its first message was delivered to, with any +tag removed, or the address it was sent from when the thread began with a send. Later messages joining the thread do not change it. Null when no address was recorded.

Mund të jetë null

ThreadMessageobject

A message, in whatever shape the mailbox stored it. The fields are deliberately not enumerated here. encryption is the one property this API describes, because it is the one whose absence cannot be guessed at safely.

ThreadSummaryobject

objectstringE detyrueshme
Një nga"thread_summary"
threadIdstringE detyrueshme
statestringE detyrueshme
Një nga"ready""pending""none"
summarystringE detyrueshme

One or two sentences, present when state is ready.

Mund të jetë null