Quickstart
This walks the whole loop once: deploy a solver and its data, create a project from it, ask Aura to solve it, and read the result back.
Before you start
Section titled “Before you start”You need an Aura API key (sk-aura-…). Mint one in the Aura web app under
Company settings → API keys, and put it in your environment:
export AURA_API_KEY="sk-aura-..."1. Install
Section titled “1. Install”npm install @strangeworks/aura-sdkpip install aura-sdknpm install -g @strangeworks/aura-cli2. Deploy your model
Section titled “2. Deploy your model”A deployment is a solver plus its data, uploaded under a name your company can create projects from.
Its layout is fixed: the solver package goes under run/, the dataset under top-level data/.
The solver reads ../data/ at solve time, so the same solver can run against a different
dataset.
Directoryrun/
- pyproject.toml
Directorysrc/
Directorysolver/
- …
Directorydata/
- instances.json
See the layout contract for what the server checks.
import { AuraClient, deployFromFolder } from "@strangeworks/aura-sdk";
const aura = new AuraClient({ apiKey: process.env.AURA_API_KEY! });
await aura.createDeployment("vrp");await deployFromFolder(aura, "vrp", "./my-model/solver", { destPrefix: "run/" });await deployFromFolder(aura, "vrp", "./my-model/data", { destPrefix: "data/" });
const check = await aura.checkDeployment("vrp");if (!check.ok) throw new Error(`Not runnable: ${check.missing.join(", ")}`);import asyncio, osfrom aura_sdk import AuraClient, deploy_from_folder
async def main() -> None: async with AuraClient(api_key=os.environ["AURA_API_KEY"]) as aura: await aura.create_deployment("vrp") await deploy_from_folder(aura, "vrp", "./my-model/solver", dest_prefix="run/") await deploy_from_folder(aura, "vrp", "./my-model/data", dest_prefix="data/")
check = await aura.check_deployment("vrp") if not check.ok: raise RuntimeError(f"Not runnable: {', '.join(check.missing)}")
asyncio.run(main())The CLI reads the deployment’s shape from a [tool.aura.deployment.<name>] table in your
model folder’s pyproject.toml. aura init scaffolds it:
cd my-model/solveraura init # writes [tool.aura.deployment.<name>]aura deploy --dry-run # preview exactly what would uploadaura deployaura deployment checkcheck is the server-side run contract: ok, plus missing and warnings naming what a project
created from this deployment would fail on. Deploying again syncs rather than adds — remote files
no longer present locally are removed, so renames leave nothing stale.
3. Create a project and solve
Section titled “3. Create a project and solve”A project created from a deployment lands directly in run mode, so you can chat with it immediately.
const project = await aura.createProject({ name: "vrp demo", fromDeployment: "acme/vrp", // "<company>/<name>"});
const reply = await aura.chat(project.id, "Solve this and summarize the result.");console.log(reply.content);project = await aura.create_project(name="vrp demo", from_deployment="acme/vrp")
reply = await aura.chat(project.id, "Solve this and summarize the result.")print(reply.content)aura project create acme/vrp --name "vrp demo"# → prints the new project id
aura chat --project <project-id> --message "Solve this and summarize the result."Drop --message for the full-screen interactive TUI.
chat() dispatches your message and polls until that turn finishes, returning the agent’s reply.
It waits for the reply to your message specifically — see
Chat with a project for what that guarantees.
4. Read what the run produced
Section titled “4. Read what the run produced”const [latest] = await aura.listExecutions(project.id);console.log(latest.status, latest.output_summary);
const solution = await aura.readFile( { source: "workspace", projectId: project.id }, "run/output/solution.json",);console.log(JSON.parse(solution.text ?? "{}"));import jsonfrom aura_sdk import WorkspaceFiles
executions = await aura.list_executions(project.id)latest = executions[0]print(latest.status, latest.output_summary)
solution = await aura.read_file( WorkspaceFiles(project_id=project.id), "run/output/solution.json")print(json.loads(solution.text or "{}"))aura snapshot list --project <project-id>
# "solution" resolves to the path that run recordedaura snapshot read <snapshot-id> solution --project <project-id> | jq .objectiveEach completed solve freezes a snapshot, so this reads the run’s own frozen copy rather than a live workspace a later run may have overwritten.
Where to go next
Section titled “Where to go next”-
Core concepts — what deployments, projects, conversations and snapshots each own, so the API stops needing guesses.
-
Deploy a model — the manifest, the include/exclude rules, and the
run/+data/contract in full. -
Errors — the three failure modes of a turn, and which one you are looking at.