Browser

Browsers: a browser an agent drives, and profiles that keep a person's logins.

profile = noclick.BrowserProfile.from_name("ana-work", create_if_missing=True, user="user_42")
profile.login("https://portal.example.com", reason="to download your invoices").wait()

with noclick.Browser.create(profile=profile, timeout_s=900) as browser:
    browser.goto("https://portal.example.com/invoices")
    result = browser.act("Download every invoice from September")
    print(result.summary)
# closed on exit

A browser is Chromium in a sandbox, driven by a model that sees the page and acts on it. NoClick solves the CAPTCHAs it can; when a page still needs a person (a CAPTCHA it couldn't solve, a two-factor code), the browser parks, unbilled, while that person finishes the step on a page NoClick sends them. A profile keeps the sign-ins a person made once; when a site signs it out, the next browser asks that person to sign in again the same way, and saves the new sign-in. A profile counts as a credential, so it is never exported and only its own user's browsers and agents use it.

class Browser

A running browser; it closes at expiresAt, or when you close() it. Billed per minute while it runs, plus the model tokens act and extract use; time it waits on a person is neither billed nor counted against timeoutS.

Attributes
idstring
statusBrowserStatus

starting, running, parked (waiting on a person, or an agent's browser waiting for its conversation's next turn), closed or failed.

regionstring | null

Where it runs: its profile's region, else the one it was created in.

profileIdstring | null

The profile it is signed in with (null if none).

agentIdstring | null

The agent driving it, for an agent's browser.

liveUrlstring | null

A NoClick page where you watch it live and can take over; it works while the browser runs.

urlstring | null

The page it is on.

titlestring | null
timeoutSnumber | null

How long it may run; parked time doesn't count.

solveCaptchasboolean | null

Whether NoClick solves CAPTCHAs before asking a person.

parkedSnumber | null

Seconds it has waited parked: not billed, not counted against timeoutS.

costUsdnumber | null

What it has cost so far: minutes and model tokens.

userIdstring | null
createdAtDate | null
expiresAtDate | null
closedAtDate | null

createstatic

static create(options?: BrowserCreateOptions): Promise<Browser>

Start a browser; with profile it is signed in to the profile's sites and acts in the profile's user.

Parameters
options.profileBrowserProfile | string

Signed in to this profile's sites; the browser acts in the profile's user, runs in its region and saves new sign-ins into it when it closes. One such browser per profile at a time: a second throws Conflict naming the first (browser_id).

options.timeoutSnumber

How long it may run: 300 by default, up to 3600; time waiting on a person doesn't count.

options.regionstring

Where it runs without a profile (regions({ kind: "browser" })); the account's default when omitted.

options.solveCaptchasboolean

NoClick solves the CAPTCHAs it can before asking a person (default); false for sites whose terms forbid it.

options.humanHuman

Who is asked when a page needs a person: the user by default, you for an account browser.

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 browser, running on a blank page, with its live_url.

fromIdstatic

static fromId(browserId: string, options?: CallOptions): Browser

A lazy reference to a browser by id, for one you started earlier.

Parameters
browserIdstringrequired
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

A browser that loads the first time you read a field. Nothing is sent yet.

getstatic

static get(browserId: string, options?: CallOptions): Promise<Browser>

Load a browser by id now; an unknown id raises noclick.NotFound.

Parameters
browserIdstringrequired
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 browser, loaded: its status, the page it is on and its live_url.

liststatic

static list(
  options?: ReadOptions & {
    profile?: BrowserProfile | string;
    status?: BrowserStatus | "live";
    limit?: number;
  },
): Promise<Browser[]>

The current user's browsers, optionally one profile's; status: "live" lists those starting, running or parked.

Parameters
options.profileBrowserProfile | string
options.statusBrowserStatus | "live"
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 browser, newest first, fetched page by page. Agents' browsers are listed too.

listPagestatic

static listPage(
  options?: ReadOptions & PageOptions & {
    profile?: BrowserProfile | string;
    status?: BrowserStatus | "live";
  },
): Promise<Page<Browser>>

One page of browsers; 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.profileBrowserProfile | string
options.statusBrowserStatus | "live"
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 browsers and whose next_cursor is None on the last page.

goto

goto(url: string): Promise<PageState>

Open url and wait for the page to load.

Parameters
urlstringrequired
Returns

The page it landed on: its url after redirects and its title.

act

act(
  instruction: string,
  options: BrowserActOptions & { background: true },
): Promise<Operation<ActResult>>

Have the model carry out instruction on the page, with files downloaded into the browser first for its forms. NoClick solves the CAPTCHAs it can, giving one half a minute; one still there, or a two-factor prompt, parks the browser (not billed, not counted against its timeout) and sends a person a page carrying the live view, and the step waits until they have dealt with it; so does the sign-in page of a site whose saved sign-in expired, and the new sign-in is saved to the profile. { background: true } returns at once with an Operation whose wait() resolves to the ActResult.

Parameters
instructionstringrequired
options.backgroundbooleanrequired

Return at once with an Operation whose wait() resolves to the ActResult.

options.maxStepsnumber

At most this many actions: 50 by default, up to 200.

options.filesstring[]

https URLs (a bucket's signedUrl works) NoClick downloads into the browser for the task's forms; up to 5.

options.timeoutSnumber

Seconds to wait here; the step keeps going after.

Returns

How it went: whether it's done, a summary, the steps it took, the url it ended on and any downloads. With background=True, an Operation at once, whose wait() gives that result.

extract

extract(query: string, options?: { schema?: JsonObject }): Promise<T>

Read what query describes off the page, shaped by schema (a JSON Schema) when you pass one.

Parameters
querystringrequired
options.schemaJsonObject
Returns

The data as JSON: an object or a list matching schema, or the model's own shape without one.

screenshot

screenshot(options?: { fullPage?: boolean }): Promise<Uint8Array>

A PNG of the viewport, or the whole page with fullPage.

Parameters
options.fullPageboolean
Returns

The PNG's bytes.

content

content(options?: { format?: BrowserContentFormat }): Promise<string>

The page's content as markdown (default), text or html.

Parameters
options.formatBrowserContentFormatdefault "markdown"
Returns

The page's content in that format; markdown keeps headings, links and tables.

close

close(): Promise<void>

Close the browser now (billing stops with it). The profile keeps any new sign-ins.

BrowserProfile

class BrowserProfile

Saved sign-ins for one person. BrowserProfile.fromName("ana-work", { createIfMissing: true, user: "user_42" }) is lazy; profile.login(url) asks the person to sign in once, and browsers started with the profile are signed in. Its region is where its browsers run; its sign-ins are kept in the US whatever the region.

Attributes
idstring
namestring
regionstring | null

Where its browsers run, fixed when it is created.

userIdstring | null
lastUsedAtDate | null

When a browser last used it (null if never).

createdAtDate | null
sitesSiteLogin[]

The sites it is signed in to, most recently signed in first (throws until hydrated).

createstatic

static create(
  name: string,
  options?: CallOptions & { region?: string },
): Promise<BrowserProfile>

Create an empty profile called name (unique per user; a duplicate throws Conflict with existingId). region is where its browsers run (regions({ kind: "browser" }); the account's default when omitted), fixed for its life; its sign-ins are kept in the US.

Parameters
namestringrequired
options.regionstring
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 new profile, signed in nowhere yet.

fromNamestatic

static fromName(
  name: string,
  options?: CallOptions & { createIfMissing?: boolean; region?: string },
): BrowserProfile

A lazy reference to the profile called name; with createIfMissing it's created, empty, on first use, in region when you pass one.

Parameters
namestringrequired
options.createIfMissingbooleandefault false
options.regionstring
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 profile that loads, or is created, the first time it's used. Nothing is sent yet.

fromIdstatic

static fromId(profileId: string, options?: CallOptions): BrowserProfile

A lazy reference to a profile by id.

Parameters
profileIdstringrequired
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

A profile that loads the first time you read a field. Nothing is sent yet.

getstatic

static get(profileId: string, options?: CallOptions): Promise<BrowserProfile>

Load a profile by id now; an unknown id raises noclick.NotFound.

Parameters
profileIdstringrequired
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 profile, loaded, with the sites it is signed in to.

liststatic

static list(
  options?: ReadOptions & { limit?: number },
): Promise<BrowserProfile[]>

The current user's profiles (the account's own outside asUser, or those userFilter covers).

Parameters
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 profile, newest first, fetched page by page, each with its sites.

listPagestatic

static listPage(
  options?: ReadOptions & PageOptions,
): Promise<Page<BrowserProfile>>

One page of profiles; 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.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 profiles and whose next_cursor is None on the last page.

login

login(
  url: string,
  options?: { human?: Human; reason?: string },
): Promise<BrowserLogin>

Ask a person to sign in to the site at url in a live browser; the sign-in is saved to this profile. human is who is asked: the profile's user when omitted (an account profile with no human sends nothing, so pass the link's url on yourself). await login.wait() resolves to the SiteLogin. You ask once: when the site signs the profile out, the browser that meets its sign-in page asks the same person again (SiteLogin.signedInBy). The link's browser starts (and is billed) only once the person opens it.

Parameters
urlstringrequired
options.humanHuman
options.reasonstring
Returns

The sign-in link, already sent: its url, when it expires_at (in 24 hours) and where it went. wait() returns the SiteLogin once the person has signed in.

forget

forget(domain: string): Promise<void>

Sign the profile out of domain and drop what it and its subdomains stored. A short browser (about a minute, billed like any) clears them and saves the profile; this resolves once it has. It throws Conflict (naming the browser) while another browser saves into the profile, and a browser already using the profile keeps the old state until it closes.

Parameters
domainstringrequired

delete

delete(): Promise<void>

Delete the profile and every sign-in in it.

BrowserLogin

class BrowserLogin extends Operation

A live-browser link where a person signs in to a site, and the operation that finishes once they have: await login.wait() resolves to the SiteLogin.

Attributes
urlstring

The page where the person signs in, in a live browser.

expiresAtDate | null
domainstring | null

The site's domain.

deliveredViastring[]

Channels the link went out on (["email"]); empty when nobody was sent it.

undeliveredJsonObject[]

Channels that failed, each with a reason: send the link yourself.

liststatic

static list(
  options?: KindScopedFilters & { limit?: number },
): Promise<Operation<SiteLogin>[]>

Sign-in operations (kind browser.login), newest first.

Parameters
options.limitnumber

Return at most this many.

options.clientNoClick
options.userUserOption

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

options.statusOperationStatus | "live" | readonly (OperationStatus | "live")[]

Statuses, or "live" for every non-terminal one.

options.agentstring | ApiObject

An Agent or agent id.

options.statusNotOperationStatus | readonly OperationStatus[]
options.keystring

The requesting key: its id or its prefix (nk_live_ab12).

options.createdAfterDate | string
options.createdBeforeDate | string
options.updatedAfterDate | string

Rows changed since (for polling).

options.userFilterUserFilter

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

Returns

Every matching operation (or the first limit); wait() on one returns the SiteLogin.

listPagestatic

static listPage(
  options?: KindScopedFilters & PageOptions,
): Promise<Page<Operation<SiteLogin>>>

One page of sign-in operations; 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.clientNoClick
options.userUserOption

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

options.statusOperationStatus | "live" | readonly (OperationStatus | "live")[]

Statuses, or "live" for every non-terminal one.

options.agentstring | ApiObject

An Agent or agent id.

options.statusNotOperationStatus | readonly OperationStatus[]
options.keystring

The requesting key: its id or its prefix (nk_live_ab12).

options.createdAfterDate | string
options.createdBeforeDate | string
options.updatedAfterDate | string

Rows changed since (for polling).

options.userFilterUserFilter

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

Returns

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

summarystatic

static summary(options?: KindScopedFilters): Promise<OperationSummary>

How many sign-in operations match, by status.

Parameters
options.clientNoClick
options.userUserOption

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

options.statusOperationStatus | "live" | readonly (OperationStatus | "live")[]

Statuses, or "live" for every non-terminal one.

options.agentstring | ApiObject

An Agent or agent id.

options.statusNotOperationStatus | readonly OperationStatus[]
options.keystring

The requesting key: its id or its prefix (nk_live_ab12).

options.createdAfterDate | string
options.createdBeforeDate | string
options.updatedAfterDate | string

Rows changed since (for polling).

options.userFilterUserFilter

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

Returns

The total that match and a count for every status in by_status.

PageState

interface PageState

Where the browser is: the page's url (after redirects) and title.

Attributes
urlstring | null
titlestring | null
rawJsonObject

The response JSON exactly as the API sent it.

ActResult

interface ActResult

How an act went: done is false when it ran out of steps or couldn't go on (summary says why).

Attributes
doneboolean
summarystring
stepsBrowserActStep[]
urlstring | null
downloadsBrowserDownload[]
costUsdnumber | null
rawJsonObject

The response JSON exactly as the API sent it.

SiteLogin

interface SiteLogin

A site a profile is signed in to. When the site signs the profile out, the next browser that meets its sign-in page asks signedInBy to sign in again in the live view, as for a two-factor code, and saves the new sign-in.

Attributes
domainstring
signedInAtDate | null
signedInBystring | null

The email of the person who signed in (the one login asked), and who is asked again when the sign-in expires; null for a link you passed on yourself, and then the browser's human is asked.

lastUsedAtDate | null

When a browser last used the sign-in (null if never).

rawJsonObject

The response JSON exactly as the API sent it.