Workflow
Workflows, built from a description and run from code.
brief = noclick.Workflow.create("Morning brief")
brief.build("Every day at 8, email me today's calendar").wait()
run = brief.run().wait()Your keys read every workflow your account can open in the app, its own and
those shared with it (access), and change, build and run the ones it owns
and pays for. NoClick's builder (the one in the app) builds and changes one
from what you describe: a WorkflowBuild you wait on, which may stop to ask
something first, and which can publish the workflow's app too. A run starts
where its trigger does, with the inputs as the trigger's payload. A run started
inside as_user (or with user=) is recorded for that user and counts
toward their spend cap; its steps still use the app's connections.
class WorkflowA workflow built in the NoClick app: its trigger, steps and outputs. Run it with
run(inputs); inputs names what its trigger takes. access is your account's: owner,
editor or viewer (one shared with it); changing, building and running take owning it and
paying for it.
- Like every live object, it also has hydrate(), refresh() and raw.
| id | string | |
| name | string | |
| description | string | null | |
| inputs | JsonObject | A JSON schema of what |
| appUrl | string | null | Where to open it in the NoClick app. |
| access | string | Your account's access: |
| createdAt | Date | null | |
| updatedAt | Date | null | |
| steps | WorkflowStep[] | Its steps in order, each with its settings, connection and trigger state (read with one workflow, not in a list). |
| edges | WorkflowEdge[] | How its steps are wired. |
| paused | boolean | Whether a pause switched its triggers off. |
| readiness | WorkflowReadiness | Whether it's set up to run, and the issues in the way. |
| urls | WorkflowUrl[] | The URLs it answers at. |
| latestBuild | WorkflowBuild | null | The build |
createstatic
static create(
name: string,
options?: { instructions?: string; description?: string; client?: NoClick },
): Promise<Workflow>A new workflow in your account. With instructions NoClick's builder starts building it:
wait on latestBuild. A name your account already has throws Conflict (change that one with
build).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
The new workflow; latest_build is its build when instructions describe it.
fromNamestatic
static fromName(name: string, options?: { client?: NoClick }): WorkflowA lazy reference to the workflow called name in the app; two with that name throw Conflict on first use.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
A workflow that loads the first time it's used. Nothing is sent yet.
fromIdstatic
static fromId(workflowId: string, options?: { client?: NoClick }): WorkflowA lazy reference to a workflow by id.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
A workflow that loads the first time it's used. Nothing is sent yet.
getstatic
static get(
workflowId: string,
options?: { client?: NoClick },
): Promise<Workflow>Load a workflow by id now; an unknown id raises noclick.NotFound.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
The workflow, loaded.
liststatic
static list(
options?: { q?: string; limit?: number; client?: NoClick },
): Promise<Workflow[]>The workflows your account can open (its own and those shared with it), most recently changed first; q is a prefix of the name.
Return at most this many.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
Every matching workflow, fetched page by page (or the first limit).
listPagestatic
static listPage(
options?: PageOptions & { q?: string; client?: NoClick },
): Promise<Page<Workflow>>One page of workflows; pass nextCursor back as cursor.
The next_cursor of the page before; omit it for the first page.
Return at most this many.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
A page whose data holds the workflows and whose next_cursor is None on the last page.
build
build(
instructions?: string,
options?: { publish?: boolean | JsonObject },
): Promise<WorkflowBuild>Change the workflow by describing the change; NoClick's builder makes it, reading the workflow
as it stands. publish: true then puts its app live (or pass { subdomain, title }; publish()
and unpublish() publish without a change). One build at a time: another in progress throws
Conflict. A change costs AI usage, as building in the app does. wait() resolves to the
WorkflowBuildResult; nextQuestion() resolves to anything it asks first.
A WorkflowBuild: wait() gives the WorkflowBuildResult (its steps, and what was
published), and next_question() returns anything it asks first.
publish
publish(options?: PublishOptions): Promise<WorkflowBuild>Put the workflow's app live as it now stands, at subdomain (omitted, the address it has); the result's published holds its url.
A WorkflowBuild whose result's published holds the app's url.
unpublish
unpublish(): Promise<WorkflowBuild>Take the workflow's app down: its public URL stops answering.
A WorkflowBuild; its result's published says unpublished.
pause
pause(reason?: string): Promise<this>Switch off each of its triggers that's on, with reason beside them: nothing starts it on its own until resume(). Runs from code still start.
This workflow, read again (paused is True).
resume
resume(): Promise<this>Switch back on each trigger a pause switched off (never one turned off by hand).
This workflow, read again.
restore
restore(): Promise<this>Bring the workflow back from the trash (within 30 days of delete()); its schedules and webhooks register again.
This workflow, read again.
delete
delete(): Promise<void>Move the workflow to the trash: its schedules and webhooks stop now, and restore() brings it back within 30 days.
Nothing.
run
run(
inputs?: JsonObject,
options?: WorkflowRunOptions,
): Promise<Operation<WorkflowRun>>Start a run with inputs (checked against the workflow's inputs schema; a mismatch throws
InvalidRequest naming the field). What would stop the run is refused before anything runs: a
step with no account connected throws NeedsConnection, and a workflow that can't start from
code or isn't set up ActionRequired. wait() resolves to the finished WorkflowRun, or
throws the run's error if it failed.
An operation whose .wait() gives the finished WorkflowRun, or
raises the run's error if it failed.
runs
runs(
options?: ReadOptions & {
status?: WorkflowRunStatus | readonly WorkflowRunStatus[];
limit?: number;
},
): Promise<WorkflowRun[]>Recent runs, newest first, however they started. Outside asUser you read runs recorded for
your account; userFilter reads your users'. The first limit (20 by default).
Return at most this many.
Which users the read covers (user_id query), instead of acting as one (user).
undefined = the ambient user (asUser), null = the account itself.
The first limit matching runs (20 by default; None for all of them).
getRun
getRun(runId: string): Promise<WorkflowRun>One run, with what each step did (steps: status, error and output, in order); an unknown id throws NotFound.
The WorkflowRun; an unknown id raises noclick.NotFound.
endpoint
endpoint(options?: { public?: boolean }): Promise<WorkflowEndpoint>The workflow's HTTP endpoint, turned on if it wasn't. public: true lets a publishable key
call it from a web page, with per-visitor rate limits; public: false requires a secret key
again; leave it out to keep what it is.
The endpoint: its url, whether it's public, and the method to call it with.
WorkflowRun
interface WorkflowRunOne run of a workflow. status is running (a run waiting on an approval or a delay too),
succeeded or failed (error says why). outputs holds what its final steps produced (each
step that finished with nothing after it running), by step name. source is how it started:
api, endpoint, schedule, trigger (an event, like a webhook or an email) or app;
inputs and operationId are set for a run started from code. steps says what each step did,
read with one run (Workflow.getRun); empty in a list.
| id | string | |
| workflowId | string | null | |
| status | WorkflowRunStatus | |
| inputs | JsonObject | |
| outputs | JsonObject | |
| error | string | null | |
| source | string | null | |
| userId | string | null | |
| operationId | string | null | |
| startedAt | Date | null | |
| finishedAt | Date | null | |
| steps | RunStep[] | |
| raw | JsonObject | The response JSON exactly as the API sent it. |
RunStep
interface RunStepWhat one step did in a run: status is succeeded, failed (error says why) or skipped;
output is what it produced, with long lists and text cut short.
| id | string | |
| name | string | |
| status | string | |
| error | string | null | |
| output | unknown |
WorkflowEndpoint
interface WorkflowEndpointThe URL a workflow answers at: send method (POST) with the inputs as a JSON body, and the
run's outputs come back (a run longer than 30 seconds answers 202 with its operation). A
public endpoint also takes a publishable key (nk_pub_...) that lists it, so a web page can
call it; otherwise it needs a secret key.
| url | string | |
| public | boolean | |
| method | string | |
| raw | JsonObject | The response JSON exactly as the API sent it. |
WorkflowBuild
class WorkflowBuild extends OperationA build of a workflow from a description (kind workflow.build). It's an Operation: wait()
resolves to the WorkflowBuildResult, or throws why the build failed.
While it builds, step is building. When the builder needs something it's awaiting_human
(step asking) and question says what: answer it with answer(), or send a person to its
answerUrl. wait() waits through a question until someone answers it; nextQuestion()
resolves as soon as there is one.
- Inherits from Operation.
| workflowId | string | null | |
| question | BuildQuestion | null | What the build waits on ( |
nextQuestion
nextQuestion(options?: { timeoutS?: number }): Promise<BuildQuestion | null>Resolve once the build asks something (its question) or finishes (null: wait() gives the result).
The question to answer, or None once the build is done.
answer
answer(
values?: JsonObject,
options?: { message?: string; skip?: boolean },
): Promise<this>Answer the question the build waits on, by input id; message tells the builder anything
else, skip: true goes on without answering. An input only a person can answer (an account
to connect, secret values) throws InvalidRequest naming answerUrl. Resolves to this build,
running again.
This build, running again.
WorkflowBuildResult
interface WorkflowBuildResultA finished build: what the builder says it did (summary), the workflow's steps as they now
stand, and, when it published the workflow's app, published (state is published,
renamed or unpublished).
| workflowId | string | null | |
| summary | string | null | |
| steps | WorkflowStep[] | |
| appUrl | string | null | |
| published | { state: string; url: string | null } | null | |
| raw | JsonObject | The response JSON exactly as the API sent it. |
WorkflowStep
interface WorkflowStepOne step of a workflow, as the app shows it: its name, its kind (type, like
automation-gmail or trigger-cron) and the operation it does there (null for a step with
one thing to do). Read with one workflow, a step also says whether it's enabled, its settings
(never a secret; long values cut short), its connection (null for a step that takes no
account) and, for a trigger, its trigger state (null for any other step).
| id | string | |
| name | string | |
| type | string | |
| operation | string | null | |
| enabled | boolean | |
| settings | JsonObject | |
| connection | StepConnection | null | |
| trigger | StepTrigger | null |
BuildQuestion
interface BuildQuestionWhat a build waits on. Each of inputs is { id, label, type, description, options? }; answer
them with build.answer({ [id]: value }) where answerableFromCode. An input of type
credential (an account to connect) or env (secret values) needs a person: send them to
answerUrl, and the build goes on once they answer.
| id | string | null | |
| title | string | null | |
| inputs | JsonObject[] | |
| answerUrl | string | null | |
| answerableFromCode | boolean | |
| raw | JsonObject | The response JSON exactly as the API sent it. |