Appearance
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.
Route A: Mobfile Generator (recommended)
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
| Step | Call | Waits for |
|---|---|---|
| 1 | POST tools/jobs/ | — |
| 2 | POST cloudstorage/packages/<input_package_uuid>/presign_for_new_file/ + PUT to GCS | — |
| 3 | POST tools/jobs/<job>/submit/ | — |
| 4 | GET tools/jobs/<job>/ | status == "ready" |
| 5 | GET 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 tomob2on its own when the line's machines are v2, and the file extension follows.meta.production_line— required. Its stations' machines are what the file is written for.meta.ifcps— the IFC parsing setup uuid, fromGET company/ifc_ps/. Required for.ifcand.btlxinputs.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
GET factories/production_lines/→ pick the line. It carriesstations, a list of station uuids in order.GET factories/stations/→ for each of those stations,machine_setupis a machine uuid. Stations without one are skipped.GET factories/machines/→ for each of those machines, takedefault_jobs.panel_mob2.- 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:
| Value | Meaning |
|---|---|
draft | created, not submitted |
waiting | queued |
working_42 | generating, 42 % done |
ready | the ZIP is there |
error | generation 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.
| Step | Call | Waits for |
|---|---|---|
| 1 | POST company/projects/ | — |
| 2 | POST constructibles/assembly_designs/ | — |
| 3 | POST cloudstorage/packages/get_or_create/ | — |
| 4 | POST cloudstorage/packages/<pck>/presign_for_new_file/ + PUT to GCS | — |
| 5 | GET constructibles/assembly_designs/<design>/ | meta.analysis == "done" |
| 6 | POST constructibles/batches/ + POST constructibles/assemblies/ | — |
| 7 | POST reports/bulk_launch/ | — |
| 8 | GET reports/reports/<report>/ | last_file.meta.status == "ready" |
| 9 | GET 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:
| Value | Meaning |
|---|---|
waiting | queued, not started |
working | parsing |
done | ready to produce from |
error_bad_setup | parsed, but the panel orientation could not be read — check the IFC parsing setup |
error, error_no_wrapper | the 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 thedynamic_formsblock 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: waiting → working_42 → ready 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 Generator | Full project flow | |
|---|---|---|
| Calls | 4 | 9 |
| Needs a project / design / panel | No | Yes |
| Several files in one run | Yes, one ZIP | Yes, one report |
| Panel tracked in produuz.it | No | Yes |
| Output | ZIP with .mob2 + plots | the machine file |
| Module needed | Mobfile Generator | — |
Related
- Upload and create designs
- Fetch and filter designs
- Generate constructibles
- Reports and machine files
- Mobfile Generator — the same tool in the interface