Inbox

Inboxes: an email address your code or agent receives mail at.

inbox = noclick.Inbox.create(local_part="signup")
print(inbox.address)
mail = inbox.wait_for(sender="noreply@github.com", subject_contains="code", timeout_s=300).wait()
print(mail.text)

With agent=, every inbound message wakes that agent, in its email thread's own conversation (message.conversation), and the agent answers on the thread with a reply tool bound to the thread's latest message. Replies go to the sender only; an inbox on a domain you bought also writes new mail to one person at a time (inbox.send). Inboxes have names (Inbox.from_name). Mail proven to be from one of your users runs as that user, and senders says whose mail wakes the agent.

class Inbox

An email address that receives mail. inbox.address is where to send it.

Attributes
idstring
namestring | null

What your code calls it (null for one created without a name).

addressstring
agentIdstring | null

The agent each inbound message wakes (null if none).

sendersInboxSenders | null

Whose mail wakes its agent.

conversationstring | null

The conversation each message lands in, a template over {sender} and {thread} (null: each thread's own).

userIdstring | null
createdAtDate | null

createstatic

static create(options?: InboxCreateOptions): Promise<Inbox>

Create an inbox, named if you like (Inbox.fromName finds it). On an account inbox, a message proven to be from one of your users (the email on their User, with an aligned DKIM signature or SPF) runs as that user whatever senders says; any other runs as your account, and a user's own inbox runs every message as that user. Each email thread is a conversation of its own with the agent (message.conversation), and the agent gets a reply tool bound to the thread's latest message: it answers that sender, on that thread, and nobody else, so a turn that resumes after an approval still answers on the same thread.

Parameters
options.namestring

What your code calls it, unique among its user's inboxes (a taken one is a Conflict with existingId).

options.agentAgent | string | null

Woken by every inbound message. In fromName, null takes the inbox from its agent.

options.domainDomain | string

An address on your own domain (a Domain, its name, or a name under it): any address on one you bought; on one you connected, a name under it (help@mail.acme.com), so its existing mail keeps working.

options.sendersInboxSenders

Whose mail wakes the agent (anyone by default).

options.conversationstring

The agent's conversation each message lands in, a template over {sender} and {thread}: "mail-{sender}" is one per correspondent, "owner" the conversation agent.message reaches with that key. Omitted, each email thread is a conversation of its own.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

options.localPartstring

The part before the @ (generated when omitted).

Returns

The new inbox; address is where to send its mail.

fromNamestatic

static fromName(
  name: string,
  options?: Omit<InboxCreateOptions, "name"> & { createIfMissing?: boolean },
): Inbox

A lazy reference to the inbox called name for the current (or given) user. With createIfMissing your code is the definition: it's created on first use, and an existing inbox whose agent or senders differs is updated to match (its address is set once, when it's created). A field left out is never changed; agent: null takes it from its agent.

Parameters
namestringrequired
options.createIfMissingboolean
options.localPartstring

The part before the @ (generated when omitted).

options.agentAgent | string | null

Woken by every inbound message. In fromName, null takes the inbox from its agent.

(omit to leave it unchanged)
options.domainDomain | string

An address on your own domain (a Domain, its name, or a name under it): any address on one you bought; on one you connected, a name under it (help@mail.acme.com), so its existing mail keeps working.

options.sendersInboxSenders

Whose mail wakes the agent (anyone by default).

(omit to leave it unchanged)
options.conversationstring

The agent's conversation each message lands in, a template over {sender} and {thread}: "mail-{sender}" is one per correspondent, "owner" the conversation agent.message reaches with that key. Omitted, each email thread is a conversation of its own.

(omit to leave it unchanged)
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

An inbox that loads (or is created, or brought in step with your definition) the first time it's used. Nothing is sent yet.

fromIdstatic

static fromId(inboxId: string, options?: CallOptions): Inbox

A lazy reference to an inbox by id.

Parameters
inboxIdstringrequired
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
Returns

An inbox that loads the first time you read a field. Nothing is sent yet.

getstatic

static get(inboxId: string, options?: CallOptions): Promise<Inbox>

Load an inbox by id now; an unknown id raises noclick.NotFound.

Parameters
inboxIdstringrequired
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

The inbox, loaded.

liststatic

static list(
  options?: ReadOptions & { agent?: Agent | string; limit?: number },
): Promise<Inbox[]>

The current user's inboxes (the account's own outside asUser, or those userFilter covers). agent keeps the ones whose mail wakes it.

Parameters
options.agentAgent | string
options.limitnumber

Return at most this many.

options.userFilterUserFilter

Which users the read covers (user_id query), instead of acting as one (user).

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

Every matching inbox, newest first, fetched page by page.

listPagestatic

static listPage(
  options?: ReadOptions & PageOptions & { agent?: Agent | string },
): Promise<Page<Inbox>>

One page of inboxes; pass nextCursor back as cursor.

Parameters
options.cursorstring | null

The next_cursor of the page before; omit it for the first page.

options.limitnumber

Return at most this many.

options.agentAgent | string
options.userFilterUserFilter

Which users the read covers (user_id query), instead of acting as one (user).

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

A page whose data holds the inboxes and whose next_cursor is None on the last page.

update

update(
  changes: {
    agent?: Agent | string | null;
    senders?: InboxSenders;
    conversation?: string | null;;
  },
): Promise<this>

Change which agent its mail wakes (null: none), whose mail does, or the conversation it lands in (conversation, a template; null: each thread's own), from the next message.

Parameters
changes{ agent?: Agent | string | null; senders?: InboxSenders; conversation?: string | null; }required
Returns

This inbox, updated. A field you leave out is unchanged.

delete

delete(): Promise<TrashItem>

Delete the inbox: its address stops receiving mail, and it goes to the trash with its mail, restorable for 30 days. Returns its TrashItem.

Returns

Its TrashItem: restore() puts it back at its address.

messages

messages(
  options?: {
    after?: string | InboxMessage;
    since?: Date | string;
    waitS?: number;
  },
): Promise<InboxMessage[]>

Messages oldest first, after after (a message or its id). With waitS the server holds the request until one arrives. since keeps those received at or after it.

Parameters
options.afterstring | InboxMessage
options.sinceDate | string
options.waitSnumber
Returns

Up to 50 messages. Pass the last one as after for the ones that follow; an empty list means none arrived in time.

message

message(messageId: string): Promise<InboxMessage>

One message in full: text, sender, subject and digested attachments.

Parameters
messageIdstringrequired
Returns

The message, loaded. An attachment's text appears once extraction, which runs just after the message arrives, has finished.

threads

threads(options?: PageOptions): Promise<Page<InboxThread>>

One page of its email threads, the most recently active first; pass nextCursor back as cursor.

Parameters
options.cursorstring | null

The next_cursor of the page before; omit it for the first page.

options.limitnumber

Return at most this many.

Returns

Threads without their messages; pass next_cursor back as cursor for the next page.

thread

thread(threadId: string): Promise<InboxThread>

One thread whole: what it received and the replies it sent, oldest first.

Parameters
threadIdstringrequired
Returns

The thread; each message's direction says which way it went.

send

send(options: InboxSendOptions): Promise<InboxMessage>

New mail from this inbox to one person: business mail you mean to send, never bulk or cold outreach. Only an inbox on a domain you bought sends new mail (one on noclick.email replies); up to 100 new emails per address a day. With thread, a follow-up: to and subject default to its correspondent and Re: its subject, and it lands in the recipient's copy of the thread. The message comes back sending until it goes (minutes, the first time an address sends), then sent.

await inbox.send({ to: "orders@millbrook.test", subject: "Saturday delivery", text: "Can you deliver on Saturday?" });
Parameters
options.tostring
options.subjectstring
options.htmlstring
options.threadstring | InboxThread

A thread (or its id) of this inbox to follow up on.

options.idempotencyKeystring

Makes a retried create safe: the same key returns the first result. Generated when omitted.

options.textstring
Returns

The message as sent: status is sending until it goes (minutes, the first time an address sends), then sent; delivery_status follows.

stream

async *stream(
  options?: {
    after?: string | InboxMessage;
    since?: Date | string;
    waitS?: number;
    signal?: AbortSignal;
  },
): AsyncGenerator<InboxMessage>

Every message (from the start, after after, or received at or after since) as it arrives; long-polls until you break or signal aborts.

Parameters
options.afterstring | InboxMessage
options.sinceDate | string
options.waitSnumber
options.signalAbortSignal
Returns

Each message in the order it arrived. It never ends on its own, so break when you're done.

waitFor

waitFor(
  options?: {
    sender?: string;
    subjectContains?: string;
    since?: Date | string;
    timeoutS?: number;
  },
): Promise<Operation<InboxMessage>>

Watch for the first message matching sender and/or subjectContains (a sign-up code, a receipt). wait() resolves to the InboxMessage, or throws Expired once timeoutS passes. since lets a message that arrived at or after it match too, so a wait started after you trigger the email can't miss it.

Parameters
options.senderstring
options.subjectContainsstring
options.sinceDate | string
options.timeoutSnumber
Returns

An operation whose .wait() gives the InboxMessage, or raises noclick.Expired once timeout_s passes without one.

InboxMessage

class InboxMessage

One email received by an inbox. A listing may trim the body: inbox.message(id) or await message.refresh() loads the full view (text and digested attachments).

Attributes
idstring
inboxIdstring | null
direction"inbound" | "outbound"

inbound (received), or outbound: mail the inbox sent (a reply, or new mail), in a thread's messages.

statusstring | null

received; for mail the inbox sent, sending (queued), sent or failed (it never went: deliveryError says why).

deliveryStatusstring | null

How mail the inbox sent landed: delivered, bounced, complained or failed; null until it's known.

deliveryErrorstring | null

Why sent mail failed or bounced, when it did.

senderstring | null

Who sent it: the message's From address when a DKIM signature aligned with it verified (as for mail a sending service delivers under its own bounce address), else the envelope sender. senderSource says which.

senderSource"header" | "envelope" | null

Where sender comes from: header (the From address, vouched for by an aligned DKIM signature) or envelope (the envelope sender). null for mail the inbox sent.

envelopeSenderstring | null

The envelope sender (SMTP MAIL FROM), often a sending service's bounce address. null for mail the inbox sent.

authenticatedboolean

Whether sender is vouched for, by an aligned DKIM signature (or, for the envelope sender, SPF). waitFor({ sender }) matches only authenticated mail. Who the mail runs as, and whether it's from the inbox's own person, is decided on the envelope sender alone.

tounknown
subjectstring | null
receivedAtDate | null
textstring

The body as text.

htmlstring | null

The HTML body, if it had one.

attachmentsJsonObject[]

Attachments, each digested to text.

conversationstring | null

The conversation its email thread is with the inbox's agent: every message of one thread shares it. A message from one of your users is in that user's conversations (agent.history(conversation, { user })).

agentErrorstring | null

Why it didn't wake the inbox's agent, or why that turn failed: a sender senders doesn't let in, a paused agent, a spent budget, the turn's own error (null otherwise).

agentOperationOperation<unknown> | null

The agent turn this message woke (null if none); wait() resolves to its AgentReply.

reply

reply(text: string): Promise<InboxReply>

Reply to the sender (only the sender; the thread is kept).

Parameters
textstringrequired
Returns

The reply as sent; delivery_status is the mail provider's word on it.

InboxReply

interface InboxReply

What message.reply(...) sent: status is ours, deliveryStatus the mail provider's.

Attributes
idstring | null
statusstring | null
deliveryStatusstring | null
rawJsonObject

The response JSON exactly as the API sent it.

InboxThread

interface InboxThread

One email thread of an inbox: what it received from one correspondent and the replies it sent them.

Attributes
idstring
conversationstring | null

The conversation it is with the inbox's agent (message.conversation).

subjectstring | null

Its first message's subject.

correspondentstring | null

Who the inbox writes with on it.

messageCountnumber
lastDirection"inbound" | "outbound"

Whether its newest message was received (inbound) or sent (outbound).

snippetstring | null

The start of its newest message.

lastAtDate | null
messagesInboxMessage[]

Its messages, both ways, oldest first: read whole (inbox.thread(id)) only.

rawJsonObject

The response JSON exactly as the API sent it.