Skip to content

Document lifecycle

/doc/* wraps its body in "Argument" rather than an ID-keyed "Assign", so these are plain functions rather than resource classes.

Most of the destructive surface is here

/doc/NEW discards unsaved work. /doc/OPEN replaces the open document. Every path resolves on the machine running NX, not the one running your script. See Destructive operations and recovery.

midas_nx.doc

/doc/* — document lifecycle.

Source: MIDAS-API manual repo, docs/manual/01_DOC.md (items 1-11). POST-only; every body is wrapped in an "Argument" key (not ID-keyed, so these are plain functions rather than DbResource subclasses).

⚠️ Every path in this API belongs to the machine running NX. Calls reach the product through MIDASIT's relay, so it may be on a different computer than the one running this code — that is a normal deployment, not an edge case. It applies to open_project/save_as/import_*/export_* here, and equally to EXPORT_PATH on result tables, design reports and view captures. Derive the path from MidasClient.verify_connection()["user"] rather than from your own environment; see :func:save_as for the pattern and the failure mode, which is silent.

new_project(client=None)

docs/manual/01_DOC.md #1 — /doc/NEW — New Project.

⚠️ Live-tested 2026-07-26: this can raise MIDAS's own "save changes?" dialog, and any dialog blocks the whole API session until a human dismisses it — not just this call. Your next request then fails or times out for reasons that have nothing to do with it; a solve started behind that dialog came back {"message": "... Analysis failed."}.

It is not predictable from the API side. In one session it prompted on a document opened from disk and then did not prompt on any of the several scratch documents /doc/NEW had itself created. Assume it may prompt: don't run this unattended against a session you can't see.

🛑 This call has crashed Gen NX outright. On 2026-07-26, one /doc/NEW against Gen NX 2026 (v2.1, build 06/23/2026) holding a real 710-node analyzed model produced the "Failed to disconnect the work session" license dialog and killed the application; the API answered 404 Client Disconnected. The license stays checked out until the process is terminated properly, which affects other machines. The same call ran a dozen times that day against small scratch documents with no incident, so the open document's size or state looks like the factor — one occurrence, so that is a hypothesis, not a cause.

Point this at a session whose contents you are willing to lose and whose process you are willing to restart. docs/live_verification_notes.md has the full history, including the same crash signature under two other triggers.

open_project(path, client=None)

docs/manual/01_DOC.md #2 — /doc/OPEN — Open Project.

close_project(client=None)

docs/manual/01_DOC.md #3 — /doc/CLOSE — Close Project.

save(client=None)

docs/manual/01_DOC.md #4 — /doc/SAVE — Save.

save_as(path, client=None)

docs/manual/01_DOC.md #5 — /doc/SAVEAS — Save As.

⚠️ path is resolved on the machine running NX, which is not necessarily the machine running this code — calls go through MIDASIT's relay, so the product may be on another computer entirely. A path built from your own %USERPROFILE% or os.path.expanduser is a common way to get this wrong.

Build it from the server instead::

user = client.verify_connection()["user"]      # "someone@midasit.com"
path = f"C:/Users/{user.split('@')[0]}/Documents/model.mgbx"

A rejected path raises MIDAS's own "invalid path" dialog on that machine and blocks the session until a human dismisses it — while this call still answers {"message": "... command complete"}, exactly as a successful save does. Live-tested 2026-07-26: the only difference visible from here was latency (58s blocked vs 0.4s saved). os.path.exists() locally proves nothing; :func:open_project on the same path is the check that asks the right filesystem.

Note also that the manual's example still uses the pre-NX .mcb extension; Gen NX 2026 writes .mgbx and Civil NX .mcbx.

stage_as(stage_step, export_path=None, client=None)

docs/manual/01_DOC.md #6 — /doc/STAGAS — Save Current Stage As.

stage_step (Required): the plain construction-stage NAME (e.g. "CS7", matching /db/STAG's own "NAME" field) — NOT the qualified "STAGE:step(last)" format used by post/TABLE's own STAGE_STEP parameter (e.g. "CS7:001(last)"). Live-tested 2026-07-31: the qualified format fails with "Please specify the correct stage name"; the plain stage name succeeds. Matches the manual's own worked example exactly (STAGE_STEP: "Fase1") — this is a case of the SDK's own docstring inviting the wrong guess by naming the parameter the same as the differently-shaped post/TABLE one, not a manual/live discrepancy.

export_path (Optional): file path to save to — must use the legacy .mcb extension (live-tested 2026-07-31: .mcbx fails with "Please check the file name or extension"), unlike save_as() which wants the current NX-native extension.

import_json(path, client=None)

docs/manual/01_DOC.md #7 — /doc/IMPORT — Import to JSON.

import_mxt(path, client=None)

docs/manual/01_DOC.md #8 — /doc/IMPORTMXT — Import to mct/mgt.

export_json(path, client=None)

docs/manual/01_DOC.md #9 — /doc/EXPORT — Export to JSON.

export_mxt(path, client=None)

docs/manual/01_DOC.md #10 — /doc/EXPORTMXT — Export to mct/mgt.

analyze(analysis_type=None, client=None)

docs/manual/01_DOC.md #11 — /doc/ANAL — Perform Analysis.

analysis_type (Optional): e.g. "PUSHOVER" for a pushover run; omit for a general analysis run.

⚠️ Live-tested 2026-07-26: a failed solve is reported as HTTP 200 with {"message": "MIDAS CIVIL NX Analysis failed."} — the same key a successful call uses for "... command complete", and with no error object. This function raises :class:MidasResultError on it rather than returning a dict that reads as success; every result table would otherwise come back empty with nothing pointing at the cause. A model the solver rejects up front (e.g. no boundary conditions) is reported the other way, as a normal {"error": ...} body, and raises from the client.

⚠️ Live-tested: on a large model (4000+ nodes), this call legitimately took longer than a 90s client timeout to solve — a MidasConnectionError/read-timeout here does not necessarily mean the request failed, it can mean the solve is still running server-side. MidasClient(timeout=...) defaults to 30s; pass a larger value for big models rather than treating a timeout as a hard failure. See docs/live_verification_notes.md for the full context (this is a separate, milder finding from the confirmed CC-ANAL stuck-dialog bug — plain long-running analysis, not a stall).