ReluAutomate
Guides

Implant planning specifics

Service-specific details for integrating Relu's implant planning & tooth-supported guide service.

Implant planning is Relu Automate's most configurable service. This guide covers what differs from the generic order flow, parameter choices, implant-library filters, the beta service, exports, and billing.

Resources

  • API URL: https://api.automate.relu.ai/
  • Endpoint: POST /orders — the generic order route, the same one every other service uses.

Create implant-planning orders through POST /orders with a service_id, just like any other service. Pass the implant-planning service_id (below) plus the implant-specific input_data and parameter_values documented in this guide. The older dedicated routes (POST /orders/implant-planning and POST /orders/implant-planning-beta) still work but are slated for deprecation — use POST /orders for new integrations. The request body is identical either way.

Which service to use

There are two implant-planning services. Pass the service_id of the one you want:

Serviceservice_id
Production — Implant Planning & Tooth Supported Guide587a7291-66ad-446d-b7fd-4d2c842f3f63
Beta — [BETA] Implant Planning & Tooth Supported Guidef47c8e0c-f1e5-49a4-8e70-42b1ab82cda0

Beta is not for production or medical use

The production service (587a7291-…) is the latest production-ready, certified version — use it for production and any clinical / medical use. The beta service (f47c8e0c-…) always carries the latest improvements ahead of certification, but must not be used for medical purposes or in production; reach for it only to preview and evaluate upcoming changes.

Integration options

Option A: full API order creation

Create the order entirely via the API. You pass every input file, parameter, and implant-library filter. You expose parameter choices in your own UI.

  • Pro: maximum control over the UI.
  • Con: you re-implement the parameter UI and keep it in sync with Relu's changes.

Create a draft order with whatever you already have (typically input files) and let the user complete configuration in Relu's iframe.

  • Pro: smooth UX, no UI to maintain, still handle files on your side.
  • Con: less control over the parameter UI.

See Draft order flow for the walkthrough.

Input data

"input_data": {
  "volume": {
    "external_download_url": "https://.../scan.dcm",
    "extension": ".dcm"
  },
  "upper_jaw": {
    "external_download_url": "https://.../upper.stl",
    "extension": ".stl"
  },
  "lower_jaw": {
    "external_download_url": "https://.../lower.stl",
    "extension": ".stl"
  }
}
  • volume (required), the CBCT scan. .dcm (single DICOM) or .zip (folder of slices).
  • upper_jaw / lower_jaw (optional, but required to generate a surgical guide), intra-oral scans. .stl, 3Shape .dcm, .ply, or .obj.

Output data

"output_data": { "implant_planning": {} }

The output bundle includes segmentations, a surgical report, a patient passport, and (once unlocked) surgical guides and design kits.

Set include_stl_mesh_bundle: true to also receive all unlocked meshes as a single STL zip — see STL mesh bundle.

Parameter reference

Implant library filters

Relu plans around several library components — the implant, the surgical kit, the sleeves, the abutment, and the wax-up. Each has its own filter list that narrows what the AI considers:

"parameter_values": {
  "implant_filters": [
    "folder = 'ETK'",
    "productLine = 'iBone E'"
  ],
  "surgical_kit_filters": [
    "folder = 'ETK'",
    "name = 'iBone Surgical Kit'"
  ],
  "sleeve_filters": [
    "folder = 'ETK'",
    "productLine = 'ETK Full Guided Surgery'",
    "pilot = false"
  ],
  "abutment_filters": [
    "folder = 'ETK'",
    "productLine = 'iBone Abutment'"
  ],
  "waxup_filters": [
    "folder = 'generic'"
  ]
}
  • implant_filters, surgical_kit_filters, sleeve_filters — narrow the implant, surgical kit, and sleeve catalogs respectively. For sleeve_filters specifically, you can omit it and set procedure_type instead — Relu then derives a manufacturer-matched, kit-recommended sleeve automatically (see Sleeve selection from the procedure type).
  • abutment_filters — narrows the abutment product line. Leave it empty (or omit it) for "Any": the engine then picks an abutment per tooth from the catalog's preferredTeeth. Set it only when you want to constrain the AI to a specific abutment line.
  • waxup_filters — narrows the wax-up library (defaults to folder = 'generic').

Each filter is a list of field = 'value' clauses combined together; omit a filter to use its default. The field names (folder, productLine, name, pilot, …) and their allowed values come from the live library — see below.

Per-implant filters

By default a filter list applies to every requested implant. To plan different teeth from different libraries, pass a per-tooth object keyed by FDI tooth number instead of a flat list. This works on any of implant_filters, sleeve_filters, surgical_kit_filters, abutment_filters, and waxup_filters:

"parameter_values": {
  "teeth_with_implant": { "tooth14": "always", "tooth24": "always" },

  "implant_filters": {
    "tooth14": ["folder = 'BIOHORIZONS'", "productLine = 'Tapered Internal'"],
    "tooth24": ["folder = 'ETK'", "productLine = 'iBone E'"]
  },

  "sleeve_filters": ["folder = 'generic'"],

  "abutment_filters": {
    "tooth24": ["folder = 'ETK'", "productLine = 'iBone Abutment'"]
  }
}
  • List = global — the same filter for every implant (the default, unchanged).
  • Object = per-tooth — each key is an FDI tooth ("tooth14", same notation as teeth_with_implant) mapping to that tooth's filter clauses.
  • The form is chosen independently per filter: you can keep sleeve_filters global while making implant_filters per-tooth (a mix), as above.
  • A requested tooth not listed in a per-tooth object falls back to that filter's engine default — a field is either global or per-tooth, never both, so list only the teeth you want to override.
  • Tooth keys are validated; use the same FDI notation as the teeth_* fields.

Use the live library

Call GET /implant-library/lists to get the current list of supported manufacturers, product lines, surgical kits, sleeves, and abutments. Relu adds libraries regularly, don't hardcode; re-fetch.

Implant locations

Tooth numbers use FDI notation only

All teeth_* fields use FDI / ISO 3950 two-digit numbers (11–48 for permanent teeth, 51–85 for deciduous). The API treats every value as FDI and does not detect Universal numbering — and the two systems share number ranges that map to different teeth (e.g. FDI 14 is an upper-right premolar, Universal 14 is an upper-left second molar). If your system uses Universal, it's your responsibility to convert to FDI before calling the API.

"parameter_values": {
  "teeth_to_extract": ["tooth11", "tooth21"],
  "teeth_with_implant": {
    "tooth11": "always",
    "tooth21": "always",
    "tooth12": "never"
  },
  "teeth_with_waxup": {
    "tooth11": "always"
  }
}

Per tooth:

  • "predict" (default), the AI places an implant only if there's space. We recommend against this default, it can surprise users with unrequested implants.
  • "never", never place an implant here.
  • "always", always place an implant here. If a tooth is present, it's extracted.

teeth_to_extract explicitly schedules extractions. teeth_with_waxup works the same way for wax-ups.

Subcrestal placement depth

"parameter_values": {
  "subcrestal_length_override": 1.5
}

subcrestal_length_override sets how deep the implant platform sits below the bone crest, in mm. It is an advanced parameter. Leave it out unless the manufacturer's protocol or the clinician asks for a specific depth.

  • Omitted or null (default), each implant keeps the subcrestal depth defined for it in the implant library.
  • 0, the platform sits at the bone crest.
  • A value above 0, the platform sits that many mm below the crest.

The value applies to every implant in the order. It has no per-tooth form, unlike the library filters. Negative values are invalid.

0 is not the same as leaving it out

0 is a real depth: it moves every implant to the crest, even when the library defines a deeper placement for that implant. To keep the library depth, omit the key or send null. Don't send 0 as an "unset" default.

Per-tooth temporary crowns

"parameter_values": {
  "teeth_with_implant": { "tooth14": "always" },
  "teeth_with_temp_crown": ["tooth14"]
}

For each FDI tooth ID in teeth_with_temp_crown, the engine produces a tempCrown mesh output. Each listed tooth costs 3 credits at creation, refunded automatically if the order fails.

teeth_with_temp_crown is opt-in, the default (empty list / omitted) produces no temp crown outputs and no per-tooth charges. The list is independent of teeth_with_implant, listing a tooth here does not also schedule an implant.

Behavior change

Earlier versions of the API generated a temporary crown mesh for every implanted tooth automatically, at no extra charge. Temp crowns are now opt-in and each listed tooth adds a 3-credit upfront charge. Existing integrations that relied on the implicit behavior should pass teeth_with_temp_crown with the teeth they want crowns for.

Procedure type

"parameter_values": {
  "procedure_type": "Pilot guide"
}

Surgical procedure style. Controls whether a guide is generated, which sleeve system applies, and the upfront cost:

  • "Free-handed", no guide, no sleeves. No surcharge on top of the base order price.
  • "Pilot guide", pilot-only guide. +15 credits at creation; the surgical guide export is unlocked automatically (no separate unlock fee).
  • "Fully guided", fully-guided guide. +15 credits at creation; the surgical guide export is unlocked automatically.
  • "2Ingis guide", 2Ingis-specific sleeve plan, no printable guide mesh. No surcharge; the surgical guide export is unlocked automatically.

Omit procedure_type to keep the legacy behavior, the guide is generated whenever an IOS scan is present, no procedure surcharge is added at creation, and the surgical guide export is unlocked separately via PUT /orders/{order_id}/purchase_addon (or pre-charged via unlocked_addons on the create call). Existing integrations that don't pass this field keep working unchanged.

Prefer setting it explicitly

Setting procedure_type on new integrations makes the total order cost predictable at creation, and "Free-handed" is the only way to express "skip the guide" at order time (the legacy path always generates a guide when an IOS scan is present). Stick with omitting it only if your existing flow already handles guide unlocks post-completion.

Sleeve selection from the procedure type

You no longer have to hand-build sleeve_filters. When you set procedure_type and leave sleeve_filters unset (or at its default), Relu derives the sleeve filter for you — scoped to the implant's own manufacturer and preferring the surgical kit's recommended sleeve product line:

procedure_typeDerived sleeve
"Free-handed"the manufacturer's pilot sleeve
"Pilot guide"the manufacturer's pilot sleeve
"Fully guided"the manufacturer's guided sleeve (falls back to a pilot sleeve if a guided one can't be placed on the guide)
"2Ingis guide"the 2Ingis sleeve

This is the recommended default for new integrations: set procedure_type, omit sleeve_filters, and let Relu pick a sleeve that matches the implant system and surgical kit. Sleeves from other manufacturers and universal (cross-system) sleeve lines are intentionally excluded from this default — select one explicitly if you need it.

Overriding is always available (non-breaking)

Passing an explicit sleeve_filters (e.g. ["folder = 'ETK'", "productLine = 'ETK Full Guided Surgery'"]) always wins and is sent to the planner unchanged, on every procedure_type. The derivation only fills the unset case — existing integrations that already build sleeve_filters behave exactly as before.

Guide settings

"parameter_values": {
  "guide_thickness": 2.3,
  "printer_offset": 0.15,
  "sleeve_printer_offset": 0.1,
  "text_to_print": "engrave_order_name",
  "guide_bar": "None",
  "engrave_method": "engraved",
  "window_positioning": "Next to implants",
  "glue_holes": "disabled"
}
  • guide_thickness, guide thickness in mm.
  • printer_offset, offset between the guide and the jaw.
  • sleeve_printer_offset, offset between sleeves and the guide.
  • text_to_print, text to engrave. "engrave_order_name" uses the order name; "" disables engraving.
  • guide_bar, None, Print, or Palatal.
  • engrave_method, "engraved" (default) or "embossed".
  • window_positioning, "Next to implants" (default) or "One in front, two in back".
  • glue_holes, "disabled" or "enabled".

Finding your defaults

The easiest way to find your lab's right defaults is to create a few orders through the Relu UI, then inspect the order-creation network call in your browser dev tools to see the parameter_values the UI sent.

Advanced guide settings

"parameter_values": {
  "window_distance_to_implants": 2,
  "sleeve_gingiva_penetration_limit_mm": 0.5,
  "min_support_teeth_per_side": 3,
  "guide_tooth_coverage_mm": 5.0,
  "allow_guided_sleeve_downgrading": true
}

These parameters tune how the guide is built. The example shows the defaults, which suit most integrations. Send a key only when you want to change it.

ParameterTypeDefaultAllowed values
window_distance_to_implantsinteger21 to 3
sleeve_gingiva_penetration_limit_mmnumber0.50 to 1.5
min_support_teeth_per_sideinteger31 to 8
guide_tooth_coverage_mmnumber5.00.5 to 12
allow_guided_sleeve_downgradingbooleantrue
  • window_distance_to_implants, the minimum number of interproximal gaps between a guide window and the nearest implant. 1 puts the window next to the implant.
  • sleeve_gingiva_penetration_limit_mm, the deepest a sleeve may sink into the gingiva, in mm. Sleeve positions that go deeper are discarded. 0 allows no gingiva contact at all.
  • min_support_teeth_per_side, the number of sound teeth the guide needs on each side of the implants before it is long enough to seat. A higher value extends the guide over damaged teeth. A lower value gives a shorter guide.
  • guide_tooth_coverage_mm, how much of each tooth the guide outline covers, in mm, measured up from the gingival margin. A higher value makes the guide grip more of the tooth. A tooth shorter than the value is covered in full.
  • allow_guided_sleeve_downgrading, whether a tooth may fall back to a pilot sleeve when its guided sleeve doesn't seat within the gingiva limit or doesn't clear the neighbouring tooth. This is the fallback described in Sleeve selection from the procedure type. Set it to false to keep the guided sleeve where possible.

Mesh output format

"parameter_values": {
  "mesh_extension": "STL"
}

Controls the file extension used for all mesh outputs of the order, including the surgical guide mesh, the waxed-up model, undercuts, teeth segmentations, and nerves. Pick what your downstream tooling expects:

  • "STL" (default), broadly supported by CAD/CAM and slicer software.
  • "PLY", Stanford polygon format.
  • "OBJ", plain-text mesh, easy to inspect.

This is an advanced parameter, the default "STL" is sufficient for most integrations. Switch to "PLY" or "OBJ" only if your post-processing pipeline needs it. The choice also flows through to the extension field on each mesh entry returned by GET /implant-orders/{order_id}/output-files.

STL mesh bundle

"parameter_values": {
  "include_stl_mesh_bundle": true
}

Off by default. When true, the order produces one extra zip containing every unlocked mesh deliverable as an STL with human-readable filenames (implant_11.stl, waxup_11.stl, mandible.stl, upper_guide.stl, …) — exactly the meshes you'd otherwise fetch individually, so locked exports stay out. A convenience for integrations that prefer a single download over per-mesh fetches; the per-file outputs and the viewer are unaffected.

It comes back alongside the other deliverables as type: "ZippedData", name: "all-meshes-stl-zip", with a signed download_url — see Downloading outputs.

Generated once, at first processing

The bundle is built a single time, when the order's first job completes. It is not regenerated if the case is recomputed or edited and re-saved in the viewer. Fetch it after the initial job; if you need meshes after edits, fetch them individually instead.

Fetching processing status

Polling

POST https://api.automate.relu.ai/orders/job-statuses
Content-Type: application/json

{ "order_ids": ["<order_id>"] }

Check statuses[order_id].main_job.job_status for "Submitted", "Done", "Failed", or "Cancelled". main_job is null until processing starts. Missing and inaccessible orders appear in errors. Send no more than 100 order IDs per request, and don't poll more often than every 10–30 minutes in production.

Webhook

Pass callback_url when creating the order. Event types:

  • order.job_status, processing completed.
  • order.status, approval status changed ("Approved", "Rejected", or "Unapproved").
  • order.outputs_edited, user edited and saved in the viewer.
  • order.unlock, an export was unlocked (creates a billing event).

Each callback body contains event_type, order_id, and order_name.

Use both

Webhooks lower load on both sides. But poll at low frequency (e.g., every 30 minutes) as a safety net in case a webhook is missed.

Progress percentage

Use POST /orders/progress only for UIs that need progress bars. Use POST /orders/job-statuses to check for completion.

Approval & exports

Users must approve the treatment in the viewer before exports can be unlocked. Approval is toggleable; each change fires order.status.

Integrations can set the same status without the viewer:

PUT /orders/{order_id}/status?status=Approved

The request has no JSON body. Use Rejected to reject the result and Unapproved to reset the decision. The API key needs update:orders scope, and the API user needs order:approve permission on the completed order.

Available exports

  1. Surgical report & patient passport, included free with the planning.
  2. Segmentations, the anatomical meshes.
  3. Surgical guide (+ IOS model with a base for fit testing).
  4. Guide design kit, design the guide in external software.
  5. Crown design kit, design crowns in external software.
  6. Surgical navigation export, for XNav and similar systems.

Each export has an unlock cost. Once unlocked, it's free to re-download.

Billing

The cost is billed to the owner of the order, not whoever unlocks it. Whether to let end users unlock exports themselves, or do it from your backend, is your choice.

The surgical report and patient passport PDFs embed your organization's logo at the top, when one is set. The logo used is the one belonging to the organization that owns the order (the org of the API user who created it), not the end user who downloads the PDF — so it only needs to be set once, per integrating organization.

Two ways to set it:

  • From the Relu dashboard, an organization admin can open Settings → Organization → General and upload an image from the Logo card.

  • From the API, an org admin (or system admin) uses a two-step presigned-upload flow:

    POST https://api.automate.relu.ai/organizations/{organization_id}/logo/upload-url
    POST https://api.automate.relu.ai/organizations/{organization_id}/logo

    Step 1 with { "extension": ".png", "size_bytes": 12345 } returns a presigned upload_url and an s3_file_id. PUT the raw image bytes to upload_url with the matching Content-Type header, then commit with step 2 ({ "s3_file_id": "...", "file_name": "logo.png" }). DELETE /organizations/{organization_id}/logo removes the current logo.

Accepted formats: .png, .jpg / .jpeg, .svg, .webp. Max size: 5 MB.

Set the logo before placing orders

The logo is embedded into the surgical report and patient passport when the PDFs are first generated; once generated, the embedded logo doesn't change. Upload your logo before placing your first order, and re-upload ahead of time if you rebrand.

Unlocking from the backend

PUT https://api.automate.relu.ai/orders/{order_id}/purchase_addon

Unlocks a specific export bundle, lets you control spend without exposing unlock buttons to end users.

Downloading outputs

GET https://api.automate.relu.ai/implant-orders/{order_id}/output-files

Returns the deliverable artifacts for the order, each with a time-limited download_url. The response is filtered: only deliverables that are either included by default OR whose export bundle is unlocked are returned. Internal / intermediate engine outputs (per-tooth info JSON files, contour XYZ files, viewer-only mesh variants, ...) are not included.

[
  {
    "id": "...",
    "name": "surgical_report",
    "type": "surgical_report",
    "download_url": "https://.../abc.pdf",
    "options": {}
  },
  {
    "id": "...",
    "name": "fused_tooth75",
    "type": "meshes",
    "download_url": "https://.../def.stl",
    "options": { "extension": ".stl", "structures": ["fused_tooth75"] }
  }
]

Always returned (no unlock required)

typeWhat it is
surgical_report, patient_passport, drilling_protocolPDFs generated post-approval. Embed your org logo if set before order creation.
meshes (bones + per-tooth)Segmentation meshes shown in the implant viewer step: mandible, maxillary / skull, plus per-tooth (tooth<FDI> from the CBCT, or fused_tooth<FDI> if an IOS was registered). The structure is in options.structures[0].
WaxupMeshCrown waxup STLs for every tooth flagged with a waxup.
panoramic_archPanoramic arch curve used to render the panoramic view from the CBCT.
registration_matrix_lower, registration_matrix_upper4×4 rigid transform aligning the IOS to the CBCT (JSON). Only present when an IOS was uploaded.

Returned only when the matching export bundle is unlocked

AddontypeWhat it is
EXPORT_GUIDESguideMesh, upper_guide_model, lower_guide_modelPrintable surgical guide STL(s).
EXPORT_TEMP_CROWN_<FDI> (per tooth)tempCrownTemporary crown STL for the specified tooth. Identify the tooth via the name (TempCrownMesh_tooth<FDI>).
EXPORT_MANDIBULAR_NERVE, EXPORT_SINUSES, EXPORT_AIRWAYmeshesExtra anatomy meshes (nerves, sinuses, airway). Identify via options.structures[0].
EXPORT_UPPER_CLOSED_CROWNS, EXPORT_LOWER_CLOSED_CROWNSmeshesClosed-crown variants from the IOS.
EXPORT_REGISTERED_FACIAL_SCANmeshesFacial scan registered into CBCT space.

Common fields

  • type — see the tables above for the meaningful values for implant orders.
  • name — human-readable identifier. Per-tooth artifacts include the FDI tooth number (e.g. WaxupMesh_tooth11, TempCrownMesh_tooth13); per-jaw artifacts include the jaw (e.g. GuideMesh_lowerjaw, GuideModel_upperjaw).
  • options.extension — for mesh outputs, reflects the format you picked via mesh_extension (.stl by default, or .ply / .obj).
  • options.structure — the tooth FDI (tooth15) or jaw (lowerjaw / upperjaw) the row belongs to. Mirror of the suffix on name, also available on meshes rows as options.structures (a list).
  • download_url — expires after a while; re-fetch the order for fresh URLs.

Stable response shape

Integrations that already rely on surgical_report, patient_passport, guideMesh and meshes rows continue to work — those type values and their options shape are preserved. Intermediate engine outputs that used to leak into the response (per-tooth WaxupInfo, transformation, marginLine, guideOutline, ...) are now filtered out.

Consumables info

GET https://api.automate.relu.ai/implant-orders/{order_id}/planning-info

Returns which implants, abutments, and components were used, use this to create ordering records for the physical parts.

Billing

Implant orders cost 15 credits at creation, plus the surcharges driven by parameter_values: +15 credits when procedure_type is "Pilot guide" or "Fully guided", and +3 credits per tooth listed in teeth_with_temp_crown. Per-tooth temp-crown charges are refunded if the order fails. Other exports cost more on unlock. Volume discounts kick in at configured thresholds. Usage is billed monthly.

For refunds when an order produced no clinical value, see Submit feedback & request refunds.

Full example

A complete POST /orders body. Swap service_id for the beta service ID to run the beta version.

{
  "service_id": "587a7291-66ad-446d-b7fd-4d2c842f3f63",
  "order_name": "Patient #1234",
  "input_data": {
    "volume": {
      "external_download_url": "https://.../scan.dcm",
      "extension": ".dcm"
    },
    "lower_jaw": {
      "external_download_url": "https://.../lower.stl",
      "extension": ".stl"
    },
    "upper_jaw": {
      "external_download_url": "https://.../upper.stl",
      "extension": ".stl"
    }
  },
  "output_data": { "implant_planning": {} },
  "parameter_values": {
    "guide_thickness": 2.3,
    "printer_offset": 0.15,
    "sleeve_printer_offset": 0.1,
    "text_to_print": "",
    "guide_bar": "None",
    "glue_holes": "disabled",
    "teeth_to_extract": ["tooth11", "tooth21"],
    "teeth_with_implant": { "tooth11": "always", "tooth21": "always" },
    "teeth_with_waxup": { "tooth11": "always", "tooth21": "always" },
    "implant_filters": ["folder = 'ETK'", "productLine = 'iBone E'"],
    "surgical_kit_filters": ["folder = 'ETK'", "name = 'iBone Surgical Kit'"],
    "sleeve_filters": [
      "folder = 'ETK'",
      "productLine = 'ETK Full Guided Surgery'"
    ]
  },
  "callback_url": "https://your-app.com/relu-webhook"
}

On this page