Error

The error family.

The server renders every refusal as {"error": {"type", "message", "next_step", ...details}}; type picks the class here (the same names and HTTP statuses the API uses). Extra keys land in details and read as attributes: err.connect_url, err.existing_id.

class Error(Exception)

Base class for every NoClick platform error.

Attributes
typestr
http_statusint | None
messagestr
next_stepstr | None
detailsdict[str, Any]
status
request_idstr | None

Error types

ClasstypeHTTPWhen
Offer

One way past a refusal for money: a link a person opens to pay, no sign-in needed.

InvalidRequestinvalid_request400

The request is malformed or a value is out of range; field names the argument when there is one.

Unauthenticatedunauthenticated401

No key was sent, or the key or session token isn't valid (revoked, expired, or not a platform key).

PaymentRequiredpayment_required402

Your account can't pay for this: balance_usd is what's left and required_usd what the call needs, in US dollars.

PlanRequiredplan_required402

The account's plan doesn't allow this: plans cap some resources.

PriceExceededprice_exceeded402

It would cost more than the ceiling you set (max_monthly_usd on PhoneNumber.buy).

ApprovalRequiredapproval_required402

Policy wants a person to approve this call first.

SpendCapExceededspend_cap_exceeded402

A monthly spend cap (scope: key, user, agent, ...) is used up.

SpendingPausedspending_paused402

You paused this user's spending (user.pause_spending()), so nothing that costs money runs for them until user.resume_spending().

PermissionDeniedpermission_denied403

The key or session lacks the scope, or the user it acts for can't do this (another user's object, a suspended user).

PolicyDeniedpolicy_denied403

Your policy (noclick.Policy) forbids this tool.

NotFoundnot_found404

Nothing by that id or name in this account, or owned by the user the call acts for.

Conflictconflict409

It already exists (existing_id names it), or another call holds it, like a conversation mid-turn.

NotAvailablenot_available409

Not available here: a feature the account doesn't have yet (phone numbers), or a sandbox that has stopped.

ActionRequiredaction_required409

Something has to be set up first, such as an agent answering a number before it can place calls.

NeedsConnectionneeds_connection424

The connection has no account connected yet; send the person connect_url.

CredentialDisconnectedcredential_disconnected424

The connection's account was revoked or stopped working; send the person connect_url to reconnect it (same name).

QuotaExceededquota_exceeded429

An account limit is reached (live sandboxes, background commands, inboxes); retrying later won't help.

RateLimitedrate_limited429

Too many requests, or a send cap reached (emails, inbox replies); retry_after says when to try again.

UpstreamErrorupstream_error502

A service NoClick relays to refused the call or failed.

RequestTimeoutrequest_timeout504

The work outlasted what one request may wait (about 90 seconds).

ServerErrorserver_error

A 5xx the server could not describe as a platform error.

APIConnectionErrorconnection_error

The API could not be reached, even after retries.

OperationFailedoperation_failed

An operation finished failed without a more specific error type.

OperationCanceledoperation_canceled

The operation was canceled before it finished.

Expiredexpired410

A request or operation expired before anyone acted on it.

OperationTimeoutoperation_timeout

Operation.wait(timeout=...) ran out before the operation finished.

WebhookSignatureErrorwebhook_signature_invalid

A webhook delivery's NoClick-Signature doesn't match its body, or its timestamp is too old.

OperationExpired

Another name for Expired.

Offer

class Offer

One way past a refusal for money: a link a person opens to pay, no sign-in needed. Paying stays that person's act; hand them url.

Attributes
kindstr

plan (a plan that includes what was refused), funds (an amount added to the balance) or topup (a monthly add-on, on the older plans).

labelstr

What it buys, in words: the Plus plan, billed monthly.

price_usdfloat
urlstr
expires_atAny

When the link stops working; refused again before then, the same link comes back.

operationOperation

The payment operation the link settles: wait() returns once it's paid, and raises OperationExpired if it never is.

PaymentRequired

class PaymentRequired

Your account can't pay for this: balance_usd is what's left and required_usd what the call needs, in US dollars. offers are links a person opens to add funds or change plan; retry once one is paid. A model provider's account out of funds (your own key) raises it too, with reason "provider_out_of_funds". A deployed app's paid call names the app in project and project_id (invite-only beta):

except noclick.PaymentRequired as short:
    for offer in short.offers:
        print(offer.label, offer.price_usd, offer.url)
Attributes
balance_usdfloat | None
required_usdfloat | None

PlanRequired

class PlanRequired

The account's plan doesn't allow this: plans cap some resources. offers are links to the plans that do.

ApprovalRequired

class ApprovalRequired(Error)

Policy wants a person to approve this call first. A Human.approve request is already out; wait on it, then retry with approval_id=:

except noclick.ApprovalRequired as pending:
    if pending.operation.wait():
        noclick.run("gmail.send_email_message", args, approval_id=pending.approval_id)

approve_url is set only when the approver is the one the call is made for. operation is None only when a user's session, or a key pinned to them, makes a call someone else approves.

Attributes
approval_idstr | None
approve_urlstr | None

The page where the approver answers.

operationHumanRequest | None

The approval as an operation: .wait() returns True once approved. None when the call's credential can't read it: a user's session, or a key pinned to them, for a call someone else approves.

SpendCapExceeded

class SpendCapExceeded(Error)

A monthly spend cap (scope: key, user, agent, ...) is used up. A deployed app's paid call names the app in project and project_id, with scope project when it's the app's own budget_usd_per_month (invite-only beta).

Attributes
capfloat | None
spentfloat | None
scopestr | None

SpendingPaused

class SpendingPaused(Error)

You paused this user's spending (user.pause_spending()), so nothing that costs money runs for them until user.resume_spending(). message and next_step are for you; user_message and action (a (label, url) pair, or None) are what you asked NoClick to tell the user, to show them as they are; since is when you paused them:

except noclick.SpendingPaused as paused:
    show_banner(paused.user_message, paused.action)
Attributes
user_messagestr | None
actiontuple[str, str] | None
sinceAny

Conflict

class Conflict(Error)

It already exists (existing_id names it), or another call holds it, like a conversation mid-turn.

Attributes
existing_idstr | None

CredentialDisconnected

class CredentialDisconnected

The connection's account was revoked or stopped working; send the person connect_url to reconnect it (same name).

UpstreamError

class UpstreamError(Error)

A service NoClick relays to refused the call or failed. A refusal, such as an integration's service answering a run with an error, comes in its own words, its HTTP status in upstream_status, and answers 424: it isn't retried, since sending the same call again won't help. A failure (a model's provider down, a service that didn't answer) answers 502 and is retried; once retries run out, retrying in a moment usually works.

RequestTimeout

class RequestTimeout(Error, TimeoutError)

The work outlasted what one request may wait (about 90 seconds). The client doesn't retry it, since the work may still be going on: an agent's turn goes on and lands in its conversation (operation_id and conversation say where).

WebhookSignatureError

class WebhookSignatureError(Error)

A webhook delivery's NoClick-Signature doesn't match its body, or its timestamp is too old. Raised by Webhook.verify in your receiver; answer it with a 400 and drop the delivery.