Skip to content

API TUTORIAL – IFC TO MOB2 FILE

Intro

This tutorial covers the flow most integrations ask for: send an IFC, generate a MOB v2 machine file, download it.

INFO

The base URL for the produuz.it API V2 is: https://back.produuz.it/api/v2/

There are two ways to do it, and they answer different needs:

  • Mobfile Generator — IFC in, ZIP out. No project, no design, no panel. This is the one to use when you only want the machine file.
  • Full project flow — the IFC becomes a design and a panel inside a project, and the MOB file is a report on it. Use this when the panel has to be tracked, produced and reported on in produuz.it.

Everything below needs an API Account (Company Settings) with the manager or admin role. API accounts authenticate without OTP, which is what makes an unattended integration possible.

Endpoint: POST my_user/token/

json
{
  "username": "your-api-account",
  "password": "your-password"
}
{
  "username": "your-api-account",
  "password": "your-password"
}

Send Authorization: Bearer <access> on every call below.


Four calls. The tool takes the geometry file straight to the generator, using a production line and an IFC parsing setup you name — nothing is stored as a project, a design or a panel.

License

The Mobfile Generator is a licensed module. Its screen is hidden when your company does not have it, so check with your administrator before building on it. See: Mobfile Generator

StepCallWaits for
1POST tools/jobs/
2POST cloudstorage/packages/<input_package_uuid>/presign_for_new_file/ + PUT to GCS
3POST tools/jobs/<job>/submit/
4GET tools/jobs/<job>/status == "ready"
5GET output_file.presigned_url

Step 1: Create the job

Endpoint: POST tools/jobs/

json
{
  "job_type": "mob",
  "meta": {
    "production_line": "b6e25a9c-bf2f-4838-ac1d-a204932a698e",
    "ifcps": "b3f44b0e-2e75-45ad-8a5d-148f70883fe1",
    "dynamic_forms": {
      "7c1f0f21-2b44-4f4e-9c2a-0d2a3c9e77aa": {
        "starting_side": "inside",
        "shift_mode": "command"
      }
    }
  }
}
{
  "job_type": "mob",
  "meta": {
    "production_line": "b6e25a9c-bf2f-4838-ac1d-a204932a698e",
    "ifcps": "b3f44b0e-2e75-45ad-8a5d-148f70883fe1",
    "dynamic_forms": {
      "7c1f0f21-2b44-4f4e-9c2a-0d2a3c9e77aa": {
        "starting_side": "inside",
        "shift_mode": "command"
      }
    }
  }
}
  • job_type — always "mob". The tool switches to mob2 on its own when the line's machines are v2, and the file extension follows.
  • meta.production_linerequired. Its stations' machines are what the file is written for.
  • meta.ifcps — the IFC parsing setup uuid, from GET company/ifc_ps/. Required for .ifc and .btlx inputs.
  • meta.dynamic_forms — the job settings, keyed by machine uuid. Send {} to fall back to the schema defaults, or fill it as the interface does (below).

The response carries the job uuid and, most importantly, input_package_uuid — that is where the IFC goes.

How to fill dynamic_forms the way the interface does
  1. GET factories/production_lines/ → pick the line. It carries stations, a list of station uuids in order.
  2. GET factories/stations/ → for each of those stations, machine_setup is a machine uuid. Stations without one are skipped.
  3. GET factories/machines/ → for each of those machines, take default_jobs.panel_mob2.
  4. Build {"<machine uuid>": <that object>, ...}.

These are the same settings you see under Station Job Options in the Mobfile Generator form.

Step 2: Upload the file

Endpoint: POST cloudstorage/packages/<input_package_uuid>/presign_for_new_file/

json
{
  "name": "D-10001.ifc",
  "short_name": "D-10001",
  "type": "application/octet-stream"
}
{
  "name": "D-10001.ifc",
  "short_name": "D-10001",
  "type": "application/octet-stream"
}

The response gives a url, a method and the headers to use:

json
{
  "url": "https://storage.googleapis.com/...&X-Goog-Signature=a1b2c3...",
  "method": "PUT",
  "fields": {},
  "headers": { "Content-Type": "application/octet-stream" }
}
{
  "url": "https://storage.googleapis.com/...&X-Goog-Signature=a1b2c3...",
  "method": "PUT",
  "fields": {},
  "headers": { "Content-Type": "application/octet-stream" }
}

Send the raw file bytes with a PUT to that url, with those headers. The URL expires, so request it right before uploading.

INFO

Accepted inputs: .ifc, .btlx, .btl, .jjs, .wup. Anything else in the package is skipped. Repeat this step for every file you want in the same run — one job takes many files and returns one ZIP holding all of them. No meta.section is needed here, unlike the design upload in route B.

Step 3: Submit

Endpoint: POST tools/jobs/<job-uuid>/submit/

No body. This is what starts the generation.

It answers 400 if no input file was uploaded, and 409 if the job is already running. A finished job can be submitted again after a PATCH tools/jobs/<uuid>/ on its meta — that is how you re-run the same file with different settings.

Step 4: Wait

Endpoint: GET tools/jobs/<job-uuid>/

Read status:

ValueMeaning
draftcreated, not submitted
waitingqueued
working_42generating, 42 % done
readythe ZIP is there
errorgeneration failed

Poll every few seconds.

Step 5: Download

The same response carries output_file, with a presigned_url. Download directly from it — no authentication header needed.

json
{
  "uuid": "...",
  "status": "ready",
  "output_file": {
    "name": "output.zip",
    "presigned_url": "https://storage.googleapis.com/..."
  }
}
{
  "uuid": "...",
  "status": "ready",
  "output_file": {
    "name": "output.zip",
    "presigned_url": "https://storage.googleapis.com/..."
  }
}

The ZIP holds one .mob2 (or .mob) per input file, the isolation CSV when the machine produces one, and a pics/ folder with the plots of each panel.

Presigned URLs expire. They are refreshed automatically, so if one has gone stale just fetch the job again and use the new URL.

WARNING

A file that fails to generate is skipped, and the job still finishes ready with the rest inside the ZIP. Check that the ZIP holds one file per input rather than trusting the status alone.


Route B: Full project flow

Use this when the panel has to exist in produuz.it — planned, produced, reported on. The MOB file is then a report on a real panel.

Two things explain the shape of it:

  • A design is the drawing (the IFC). A constructible (assembly) is one physical panel to be produced from that design. The MOB report is launched on constructibles, so you always create both.
  • The production line is set on the batch, not on the assembly.
StepCallWaits for
1POST company/projects/
2POST constructibles/assembly_designs/
3POST cloudstorage/packages/get_or_create/
4POST cloudstorage/packages/<pck>/presign_for_new_file/ + PUT to GCS
5GET constructibles/assembly_designs/<design>/meta.analysis == "done"
6POST constructibles/batches/ + POST constructibles/assemblies/
7POST reports/bulk_launch/
8GET reports/reports/<report>/last_file.meta.status == "ready"
9GET last_file.presigned_url

Steps 1 to 4: project, design, IFC

These are covered call by call in Upload and create designs. The one thing to get right is the file meta on the presign call:

json
{
  "name": "D-10001.ifc",
  "short_name": "D-10001",
  "type": "application/octet-stream",
  "meta": {
    "section": "assembly_ifc",
    "tipo": "timber_panel",
    "ext": "ifc",
    "status": ["uploaded"],
    "design_name": "D-10001"
  }
}
{
  "name": "D-10001.ifc",
  "short_name": "D-10001",
  "type": "application/octet-stream",
  "meta": {
    "section": "assembly_ifc",
    "tipo": "timber_panel",
    "ext": "ifc",
    "status": ["uploaded"],
    "design_name": "D-10001"
  }
}

WARNING

meta.section must be exactly assembly_ifc (module_ifc for module designs). That is the key the analysis reads. A file uploaded without it is stored, but never parsed.

Step 5: Wait for the analysis

Uploading the IFC enqueues the analysis on its own.

Endpoint: GET constructibles/assembly_designs/<design-uuid>/

Read meta.analysis:

ValueMeaning
waitingqueued, not started
workingparsing
doneready to produce from
error_bad_setupparsed, but the panel orientation could not be read — check the IFC parsing setup
error, error_no_wrapperthe analysis failed

INFO

Some companies have automatic analysis switched off. If meta.analysis stays at waiting, trigger it explicitly with POST constructibles/designs/launch_analysis/ and the body {"uuids": ["<design-uuid>"]}.

Step 6: Create the constructible

A constructible always belongs to a batch, and the batch is what carries the production line. One batch per production line per project is the usual setup.

Endpoint: POST constructibles/batches/

json
{
  "project": "0549be70-e2f5-4227-86a1-bfdb229e5460",
  "phase": "Phase_1",
  "name": "BATCH_PL1",
  "production_line": "b6e25a9c-bf2f-4838-ac1d-a204932a698e"
}
{
  "project": "0549be70-e2f5-4227-86a1-bfdb229e5460",
  "phase": "Phase_1",
  "name": "BATCH_PL1",
  "production_line": "b6e25a9c-bf2f-4838-ac1d-a204932a698e"
}

Endpoint: POST constructibles/assemblies/

json
{
  "batch": "94d9c646-8e2d-4ac0-b073-aff1aed2b3d7",
  "design": "340c1149-7f85-4a83-bede-10089e462069",
  "scheduled_prod_date": "2025-10-19",
  "client_order_id": "or863-12"
}
{
  "batch": "94d9c646-8e2d-4ac0-b073-aff1aed2b3d7",
  "design": "340c1149-7f85-4a83-bede-10089e462069",
  "scheduled_prod_date": "2025-10-19",
  "client_order_id": "or863-12"
}

Keep the assembly uuid. That is what the MOB report is launched on. See Generate constructibles for the bulk variant.

Step 7: Launch the MOB2 file

Endpoint: POST reports/bulk_launch/

The body is a list of report payloads, so several files can be launched in one call.

json
[
  {
    "name": "MOB2 - TEST_HOUSE - PL1",
    "document_type": "panel_mob2",
    "project": "0549be70-e2f5-4227-86a1-bfdb229e5460",
    "selected_assemblies": [
      "8f43556f-ee33-4aaf-b0b8-028f3d3d46dd"
    ],
    "meta": {
      "production_line_uuid": "b6e25a9c-bf2f-4838-ac1d-a204932a698e",
      "fill_mob2_defaults": true
    }
  }
]
[
  {
    "name": "MOB2 - TEST_HOUSE - PL1",
    "document_type": "panel_mob2",
    "project": "0549be70-e2f5-4227-86a1-bfdb229e5460",
    "selected_assemblies": [
      "8f43556f-ee33-4aaf-b0b8-028f3d3d46dd"
    ],
    "meta": {
      "production_line_uuid": "b6e25a9c-bf2f-4838-ac1d-a204932a698e",
      "fill_mob2_defaults": true
    }
  }
]
  • selected_assemblies — assembly (constructible) uuids, never design uuids.
  • meta.production_line_uuid — always required for MOB files.
  • meta.fill_mob2_defaults — fills the job settings from the machine setups of that line, so you do not have to send the dynamic_forms block yourself.

One report covers one production line. To write a file per line, send one payload per line in the same list.

Steps 8 and 9: wait and download

Endpoint: GET reports/reports/<report-uuid>/

Read last_file.meta.status: waitingworking_42ready or failed. Once ready, download from last_file.presigned_url.

Full detail in Reports and machine files, including the complete list of document_type values and the auto_mob2 variant.


Which route

Mobfile GeneratorFull project flow
Calls49
Needs a project / design / panelNoYes
Several files in one runYes, one ZIPYes, one report
Panel tracked in produuz.itNoYes
OutputZIP with .mob2 + plotsthe machine file
Module neededMobfile Generator