Skip to main content
Goal: Set up a model and get your first answer from the terminal. Use a model Millwork provides, or use your own provider account. Start in an interactive terminal. If this computer does not have a Millwork organization API key yet, configure it privately. Keep the same CLI version for later commands in this setup:
You are done when: the CLI shows your answer and receipt, and the model is selected for your next task. The setup is ready. A receipt records what happened without storing the prompt or output in it.

Before you begin

  • Your organization has private-preview access, and an owner has invited you. The CLI and API call an organization a tenant.
  • You have a Millwork organization API key for the organization you want to use, or can create one when setup opens Millwork. Configure it below.
  • You have Node.js 20 or 22. The local diagnostic checks these two versions.
  • Your organization has room in its run quota. You can add credit in Billing if setup asks for it.

Configure your API key

Open Millwork dashboard → API keys in the organization you want to use. Reuse a key you saved for that organization, or create one. If you do not have access yet, contact Millwork to apply for the preview. In version 0.1.12 and later, a local interactive tenant start opens your normal system browser when it cannot find a key. Keep the terminal command running. Enter the Millwork organization API key on the private local page and choose Save and continue. The CLI checks the key against the intended Millwork API, saves it in $HOME/.millwork/organization-key.json where only your user can read it, and returns to that same command. The command continues a saved setup if one exists; otherwise it shows a plan for your approval. The key is not placed in the URL or terminal output. With --no-browser in an interactive terminal, enter your key at the hidden prompt to check it, save it and return to the command. That prompt writes the same $HOME/.millwork/organization-key.json. Use the private terminal method below with an older CLI, in CI or scripts, or without an interactive terminal; that method writes the older $HOME/.millwork/api_key instead. --json stays non-interactive unless you explicitly add --open-browser. A later millwork command reads either file, so you do not export the key again. The CLI reads $HOME/.millwork/organization-key.json for the Millwork API that checked the key, and reads $HOME/.millwork/api_key only for the default https://api.getmillwork.dev/v1.

Start another setup

Repeating tenant start continues the saved setup for that command and Millwork key. If it is already ready, the CLI says so and shows its application ID, completion time and model. It shows the saved result without starting a new model run. To review a fresh setup instead, run:
Keep --no-browser if you use the hidden key prompt. Add --template byok-open-model to choose your provider and model, or --model-deployment-id to request a particular available catalog deployment. Review the new plan and answer n to stop. The flag does not approve setup or spending. Each --new-setup invocation gets a new setup request key. If a response is lost, keep that key and retry with --idempotency-key "<saved request key>" and the same template and model choices. Once you have an application ID, continue with --application-id. Do not use --new-setup to recover uncertain work. For a script, use tenant start --new-setup --json. It returns the plan, application_key and next_action, then exits 2 without applying it. When the plan is ready, next_action.command holds the exact approval command as an argument array. Run it only after approving that plan’s effects and spend; keep the same request key for retries. Resolve any choices or blockers first if no approval command is returned. The ready-setup response carries the same human information in setup_recovery, including completed_at, model_key and new_setup.command. A time or model unavailable from an older server is null. --new-setup cannot be combined with an application ID, resume action, saved request key, approval digest, --yes, --plan or --dry-run. Those flags inspect, continue or approve an existing request; use the commands above for a new one.

Private terminal fallback

If you already saved that organization’s key in $HOME/.millwork/api_key, load it below. Otherwise run this block in your own Bash or Zsh terminal, paste the key at the hidden prompt and press Enter. It saves the key in a file that only your user can read, then loads it into this terminal without printing it:
SOLVERAPI_API_KEY gives the CLI your Millwork key in this terminal. Setting a key in a hosting service does not configure your computer. For scripts, load it from your secret store. Never commit $HOME/.millwork/api_key or paste its contents into a conversation. Check that the saved file exists and only your user can read it:

Load a saved key

In a new terminal, load the saved key without entering it again:
If you already set the same organization key as MILLWORK_API_KEY for REST, use this instead:
SOLVERAPI_API_KEY takes precedence over the browser-saved CLI key. A saved key is bound to the exact Millwork API base that checked it; changing SOLVERAPI_BASE_URL does not send that key to the new address.

Keep the CLI version for this setup

The npm commands on this page name an exact published version. Save that version with your application ID and use it throughout this setup. The shorter millwork examples mean the same version, either through npm or a matching global installation. If the CLI prints an unversioned npm continuation command, use this page’s pinned npm prefix while preserving its application ID, digest, request key and other arguments. Do not switch versions for a poll or retry. The agent guide also explains how an assistant can resolve the public version once before starting, then retain that exact version for its whole journey.

Check this terminal

The CLI uses https://api.getmillwork.dev/v1 by default. Check your local setup:
Expected result: local_configuration_ready is true. This checks local configuration without contacting the API; it does not prove the key is valid. Next, run the setup command at the top of this page. Millwork checks the key before showing a plan. A rejected key needs a local key fix, not another request for access; see API key help.
1

Choose how to connect

The default setup uses a model Millwork provides. Your Millwork organization API key is all you need; Millwork manages the provider connection.To use your own provider account instead:
Setup shows the configured provider and model choices. Choose one when there are several; a single available choice is selected automatically. The plan shows what will be used before you approve it. Setup can reuse a connection you already have.With the CLI installed, inspect providers and saved connections with millwork provider list. For a particular provider, follow Connect a provider account.--yes here lets npm start the CLI without its package-download prompt. Review the plan before approving it. For your provider account, setup and the paid model run have separate approvals.The plan shows the model and spending allowance before you approve it. Millwork uses the models available to your organization; it does not switch between its provider account and yours without your choice.
2

Approve setup

A live run has a platform fee when Millwork accepts it, plus model usage. Use the fee shown in the current prompt; it is separate from the model budget. For a model Millwork provides, both come from your Millwork credit. With your provider account, Millwork charges the platform fee and your provider bills model usage. A model call already running can exceed its budget; the budget stops further calls once recorded spend reaches it. Model access and billing lists the default fee and explains charges and refunds.Review the plan in the terminal, including its effects and costs. Answer y to approve those effects or n to stop. A funded plan for a model Millwork provides can include both the free test and the paid run in this first approval.If setup needs provider access, complete the browser step it shows. OpenRouter asks you to sign in and approve access. For a provider that uses an API key, enter its key on Millwork’s private setup page. For AWS Bedrock, enter a short-term Bedrock API key there. Millwork lists your available system profiles and matches the Bedrock model you selected; STS is an advanced option you select explicitly. Keep provider credentials out of the terminal and chat.Return to the same terminal. It waits for the browser step, tests the connection and continues. If the browser does not open, use the private link printed in your terminal before its displayed expiry. To skip automatic browser opening, add --no-browser to setup. On a remote terminal, open that link on your browser device. If the command stopped, continue with the application ID below.If a coding assistant started setup, it keeps the application ID and opens your normal system browser. Complete the private browser step, then return to the assistant; it continues the same application. Use your own terminal only if the assistant cannot show the private setup step safely. In the browser, check that the Millwork organization matches the one whose key you configured. If it is wrong, sign out and sign in to the intended organization before completing setup.Tell the assistant when you have finished; share the application ID, not the setup link. Finishing the browser step does not start a paid run.Millwork saves the progress as a setup application. Keep the Application: ID so you can continue this setup if the terminal closes.
3

Check access, then approve the model run

Setup first performs a test run (the API calls it Echo). It does not call a model, so it has no platform fee and no model cost. It counts toward your run quota. A test run alone does not finish setup.For your provider account, the CLI then shows the proposed model run and asks for a separate approval. The same applies when setup paused for credit. A run is one task you send to Millwork; the API calls it an execution. Before answering y, check the model and provider, who pays for model usage, the platform fee, model budget, and runtime limit. Also review the data rules for the task.If setup asks for credit, add credit and continue with the same application. Review the new prompt before approving paid work.
4

Read the answer and keep the receipt

On success, the CLI prints First live result ready., your answer, the receipt ID, model usage, platform fee, and remaining credit. It also selects the model for future CLI tasks.Setup is complete when you have a live model result and a receipt naming which model and provider answered.The receipt summary says No check connected. Millwork checked that an answer was present, but did not check whether it was correct. You can finish setup without your own output check.To check future answers against your own rules, follow Connect an output check. Begin with that guide’s installed-client check. If the installed help does not include verifier init, verifier connect, and verifier test --local, stop; that client cannot complete the output-check journey. Do not substitute an older global CLI.The guide supplies the complete public and protected connection commands, checks readiness before retaining the saved check ID, and stops after connection when you do not want a model run. Its later section shows how to select the saved check for a task and confirm its result on the receipt.If credit is shown as unavailable or not visible, the answer and receipt are still retained. Ask an organization owner to check Billing; an unavailable balance does not mean zero credit.

Run your next task

To use the shorter millwork commands below, install the CLI:
Check millwork --version --json before using an existing global installation. If it differs from the version saved for your setup, use the exact npm command from Keep the CLI version for this setup. If your shell says millwork: command not found, see Use the CLI without a global install. Read your current model and its preset, the saved data and budget settings used during setup:
Use the value on its Preset: line for another public-data task:
Review the paid-run prompt before approving. A model Millwork provides uses pooled-open-model-public-v1; your connected provider model uses byok-open-model-public-v1. The preset must match your current model. The command prints the answer, run status, receipt ID, and the receipt’s model usage and platform fee on separate lines. Run millwork tenant show again to read your current Millwork credit.

Change your model

Read your current selection with millwork tenant show, then list the choices:
Each row names a model, its provider, its deployment ID and who bills usage. Copy the model key and deployment ID from the same row. The deployment ID distinguishes routes when more than one provider serves a model:
Review the provider, payer and cost before approving. Changing models can need a new paid test; the CLI selects the replacement only after setup succeeds. Then run millwork tenant show and use its current preset for the next task. Declining or failing setup keeps your previous selection. If a choice is refused, check model availability.

Use the CLI without a global install

A successful global install can leave millwork outside your shell’s PATH. You can keep using the CLI through npm:
Use the exact version you saved for this setup. The same npm prefix works for the other CLI commands on this page, including printed continuation commands. To use the shorter command on macOS or Linux, run npm prefix --global and add the bin directory inside that path to your shell’s PATH. Open a new terminal and run millwork --version --json to confirm it is found.

Disconnect your provider account

To stop Millwork using a connected provider account, disconnect it:
The connection and its dependent saved models become disabled. Disabling a saved model alone does not disconnect the provider account. See Rotate or revoke a connection. Check the provider’s own controls to remove any credential there as well.

Continue an interrupted setup

Saved-application responses can include a private setup link. If an assistant runs the JSON commands below, it must capture stdout and stderr privately before reading selected non-secret fields, as the agent guide describes. Keep raw responses out of chat and shared logs. Read progress without continuing any work:
When you are ready to continue, use the same application:
In a terminal this can resume browser consent, refresh the spending proposal, or ask for paid approval. A completed setup returns its retained result and receipt. Do not create a new application to recover an uncertain run. If an automatically generated request key conflicts with an earlier approved request, the CLI saves a replacement key before retrying once. It keeps that key after success and uses it when you return to the same setup. Keys you supply with --idempotency-key and keys from --new-setup are not replaced. If that retry cannot finish, JSON output returns application_key and a next_action.command. After an uncertain response, the command continues the same approved request. After a refusal, such as an expired approval or another key conflict, it inspects the saved request without changing it. Read the reported problem before continuing; do not repeat a rejected approval. Keep the key. Once you have an application ID, continue by that ID. If local recovery data is unavailable, use your saved key or application ID.

Continue without a terminal

With --json, or anywhere there is no terminal to answer a prompt, that same command presents saved progress. It does not consume a finished browser approval or authorize a paid run. An already queued or running live execution can still be polled to its result and receipt. To consume browser approval, name that step explicitly:
poll_consent takes up a browser approval that has already finished, moving setup on to its connection test and model sync. If your application sits at consent_pending while the approval is done, this is the step that was missing. Starting the paid run is separate. Continue only when next_action.type is authorize_byok_live_proof or authorize_pool_live_proof and the application has a current proposal. Otherwise follow its returned next action. The live-proof digest is not the plan digest you approved at the start. The plan digest approves its listed effects, which can include paid work for a model Millwork provides. The later live-proof digest approves a separate proposed run with its current fee and model-usage budget. Read these from the application before you authorize: The difference between the combined allowance and model budget is Millwork’s fee. The allowance is not a final charge or guaranteed cap: a model call already running can exceed its budget. Pass the digest exactly as you read it; an expired digest is refused rather than renewed. If any of these values is missing, keep the application and ask for the missing spending details. After you explicitly approve this proposal, submit its digest:
The other steps take the same shape: retry_consent for a fresh browser approval on the same setup, retry_connection_test and retry_deployment_sync after a provider-side failure, and refresh_byok_readiness or refresh_pool_readiness to re-check before authorizing. Each needs its own --idempotency-key. Use a new key for a new observation or action; keep the same key when retrying the exact request after a lost response. Reusing a previous poll’s key returns its old observation. If you started without provider/model filters or a custom request key, and the CLI did not replace the request key, look up that template with the same Millwork key:
Use byok-open-model for your provider account, or starter for a free test. If you supplied a request key, include it with --idempotency-key. If the CLI returned a replacement application_key, use that value instead. Once you have an application ID, use --application-id. A request key identifies one operation across retries. For provider connect or a start with source/model filters, this unfiltered lookup may find a different setup or none at all. Use the application ID from the original terminal output. If you lost it and did not choose a request key, contact support before starting again. Repeating tenant start can continue work; use tenant show when you only want to inspect it.

Add credit and continue

Open Billing, add credit, and confirm the updated balance. Then continue the same application with the command above. Adding credit does not approve a paid run; review its new spending prompt. If you cannot open Billing, ask an organization owner to help.

Refresh a stale plan

A plan can stop matching before it expires if your credit, model choice, or organization settings change. If you have an application ID, continue that application to get the current proposal. If you have only a plan, request a new one with --plan --json and review it before applying its new digest. An error naming digest means the plan needs another review, not a new API key. If a request may already have started work, inspect its application and run first. Do not start a second application to find out what happened.

Provider access expired

An expired browser link needs a fresh browser step on the same saved application. A spending proposal has its own expiry and needs a new review. If the provider has revoked or expired your credentials, replace access on the existing connection before another model call. AWS access has its own deadline: renew the key or STS session on the same connection. A new setup link or spending approval does not extend that access. Renewal keeps the connection’s existing method.

Model not ready for setup

If setup refuses a model from your catalog, keep your current selection and read the reason. The model may not be available for setup through the chosen provider account, or the provider may be unable to serve it. Choose another available model or contact support with the model key and safe error details. Connecting your own account is a separate choice that changes who bills model usage.

Manage your provider connections

Run millwork provider list to see available providers separately from your existing connections and their saved models. Use a source ID to set up a provider, or a connection ID to manage access you already saved. Rotation and disconnect act on the named connection. They do not approve a paid run or choose another model. The TypeScript SDK exposes the corresponding API operations through sourceConnections.

If your organization cannot start

Use a coding assistant or script

Approve a plan in a script

In a non-interactive session, planning and applying are two separate commands. First save the plan locally; this does not create a setup application:
Review its model, payer, effects, digest, issued_at, and expires_at. request_policy.budget.max_cost_usd is the model budget. maximum_spend_usd combines that allowance with the configured platform fee; it is not a final quote or a guaranteed spending cap. Applying the digest approves the effects listed in that exact plan, including paid work when listed. Apply only a current, unexpired plan you have approved:
For your provider account, add --template byok-open-model to both commands. Keep the returned application_id and follow its next_action. --json changes the output format; it does not make the command read-only. Browser setup remains a separate step. With --json, the CLI leaves browser launch to you unless you request --open-browser. That flag opens a current setup link; it does not poll for consent or approve a paid run. It cannot be combined with --no-browser. The assistant keeps the application and its response private, opens your normal system browser, and continues after you finish. Use the explicit JSON steps to consume consent and, after your approval, authorize the later paid proposal. Use a coding assistant explains the private-terminal fallback if the browser step cannot be shown safely.

Choose a provider and model in a script

First read the available choices without creating a connection:
New AWS setup uses a Bedrock API key by default. For advanced STS, add --source-id aws_bedrock --auth-scheme aws_sts_sigv4 to that first command. Keep --auth-scheme aws_sts_sigv4 on both the exact plan and apply commands below; continuing an existing setup keeps its selected method. Read byok_offerings for the source, authentication method and model choices. Pick source_id and served_variant_id from the same offering and check its auth_scheme, then request its exact plan:
Review that plan before applying it. Repeat the same choices and use its digest and issued_at:
For an existing catalog deployment, you can use --model-deployment-id. Repeat it when applying; any source or model filters you add must match it. --served-variant-id requires --source-id, and both apply only to byok-open-model. A plan command cannot open a browser or apply changes. For scripts, choose and save an --idempotency-key when applying the plan. Keep it for that setup. It lets you look up the application with tenant show --template byok-open-model --idempotency-key "<original key>" --json. Without a custom key, the CLI derives one from the template and source/model filters. After setup starts, save its application ID and use the continuation command. Changing a key to investigate a lost response can start another setup. Setup writes no project files unless you add --write after reviewing the plan’s file_manifest. Existing files are never overwritten. For local diagnostics, run millwork --version --json, millwork docs --json, or millwork doctor --json. They do not call the API or print your key. doctor exits with status 1 if a key is not configured or a local check fails. Prefer direct API calls? Run a model walks through choosing a catalog model and reading its result and receipt.