Getting started

Create a key, install the SDK and make your first calls.

Create an API key

Open the developer console and go to API keys. Choose what the key may do (every scope is listed under API keys and scopes), optionally cap what it can spend each month, and create it. The key starts with nk_live_ and is shown once, so copy it somewhere safe.

Creating a key accepts NoClick's Developer Terms, which cover using the platform, and its Acceptable Use Policy.

Keep the key on your server. For code that runs in a browser, mint a short-lived session instead.

Install the SDK

The Python SDK needs Python 3.10 or later; the TypeScript client, Node 20 or later (or Deno or Bun).

pip install noclick
export NOCLICK_API_KEY=nk_live_...

The SDK reads NOCLICK_API_KEY from the environment. NOCLICK_API_URL changes the endpoint; it defaults to https://api.noclick.com.

Make your first calls

Create a user, keyed by the id your product already uses for them, then a connection for them to fill:

import noclick

user = noclick.User.create("user_42", name="Ana Lima", email="ana@example.com")
print(user.id, user.console_url)

with noclick.as_user(user):
    gmail = noclick.Connection.from_name("gmail", integration="gmail", create_if_missing=True)
    print(gmail.connect_url)  # send Ana here

user.console_url opens the user in the developer console, where you can see everything done for them. gmail.connect_url is a page where Ana connects her Gmail. When she does, gmail.wait() returns and gmail.run(...) acts in her account.

Configure the client

Most code never builds a client: the SDK makes one from the environment the first time it's needed. To set the key in code, or to use a second account, build one yourself:

import noclick

noclick.configure(api_key="nk_live_...")  # replaces the default client

other = noclick.Client(api_key="nk_live_other")
noclick.User.list(client=other)  # class methods take client=

An object you get back keeps using the client that fetched it.

api_key can also be a function, called before every request, when your key comes from a secret store that rotates it.

Blocking or async

Every method blocks and returns its result. Each one also has an async form, .aio:

reply = agent.message("Hi")                    # blocks
reply = await agent.message.aio("Hi")          # inside async code

Both forms work anywhere, including Jupyter and code that already runs an event loop. Async and concurrency covers the details.

Lazy objects

noclick.User.from_id, noclick.Connection.from_name, noclick.Agent.from_name and noclick.Operation.from_id return an object without calling the API. The call happens the first time you use the object. With create_if_missing=True, that first use also creates it if it doesn't exist, so the same line of code works on a fresh account and a busy one:

agent = noclick.Agent.from_name("support", create_if_missing=True, instructions="Answer billing questions.")

When something fails

Every error the API returns is an noclick.Error subclass with a message, and usually a next_step: one sentence saying what to do about it.

try:
    noclick.User.create("user_42")
except noclick.Conflict as err:
    print(err.existing_id)  # "user_42": the id is taken

Errors and retries lists them all. Transient failures (timeouts, rate limits, most server errors) are retried for you, without doing the work twice.