文档/系统集成

系统集成与数据交换

材料目录、机床费率与计价规则可以由现有系统提供,也可以将整份价目表导出回去。

目录可以来自其他系统

MetronQ 把一家工厂的整份价目表存为一份配置:采购的材料、运行的机床、出售的表面处理,以及计价引擎所用的参数。这份配置可以在面板之外读取和写入。如果这些数字已经存在于 ERP、CRM 或表格里,就不必再输入第二遍,也不必靠人工去让两份副本保持一致。

  • 材料 - 名称、EN 与 DIN 牌号、密度、每公斤价格、粗加工与车削金属去除率、精加工速率、毛坯余量、切削速度。
  • 机床 - 名称、工艺、小时费率、行程范围、轴数、主轴功率与最高转速、刀位数、最小批量,以及制造商、型号、数控系统、出厂年份、序列号和资产编号。
  • 表面处理与热处理 - 名称、类型、每公斤成本、每平方分米成本、每批固定费用,以及它给交期增加的工作日。
  • 计价规则 - 利润率、装夹与操作分钟数、最短循环时间、交期、加急系数、运费、税率,以及公差等级、几何等级和表面粗糙度的系数表。

格式有两种,选用哪一种取决于另一端是什么系统。每个目录一份表格:这是多数 ERP 导出的形式,也便于人工直接修改。将全部内容放入一份 JSON 文档,则适用于由另一个系统自动保持 MetronQ 数据最新的场景。

在哪里操作

  1. 1在面板中打开「报价规则」标签页。
  2. 2在左侧导航中选择导入与导出。
  3. 3导出生成下文所述格式的文件,导入则接收同样格式的文件。
提示

即便只打算导入,也建议先做一次导出。导出的文件已经带有准确的列名和本厂自己的目录键,因此在 ERP 侧最简单的映射方式,就是填写我们自己的导出文件。

表格格式

每个目录一个文件 - 材料、机床、表面处理。第一行是列名,在任何语言下都是英文标识符:外部系统里的映射是针对它们编写的,导入时 MetronQ 读回的也是它们。

  • 行仅按 key 列匹配。MetronQ 已知的键会被更新,未知的键会被新增。
  • 只读取文件中实际带有的列。省略某一列,该字段在每一行都保持原值。
  • 空单元格的含义是保持原样,而不是清空。部分导出 - 只含当前有库存的材料,只含本季度的费率 - 是常态而非例外。
  • 导入不会删除任何内容。删除材料或机床需要在面板中手动完成。
  • 小数点符号与列分隔符成对出现:分号配逗号小数(1234,56),逗号配点号小数(1234.56)。两者都能读取,导出则遵循账号上的分隔符设置。
  • 带或不带 BOM 的 UTF-8,以及 Windows 版 Excel 所写的中欧代码页,都可接受。
  • 单个文件最多 20 000 行,大小不超过 2 MB。

机床的刀具库有意不放进表格:一整套铣刀清单无法放进一行。因此从表格导入的机床会保留原有的刀具库,经由表格导入也就不会无声地改变这台机床可加工的范围。

整份配置作为一个文档

JSON 导出就是完整的计价配置,与面板存储的形式完全一致,并且可以原样导回。它包含三个目录,以及全部计价参数、人工审核关卡设置、机床与毛坯选择策略和币种。因此,它适合那些自行保存一份价目表副本的系统。

  • 合并是默认方式,只应用文档中确实写明的内容。一个带有三种材料和一个利润率的文件,就只改这三种材料和这一个利润率;它没有提到的一切,都保留原先设定的值。
  • 替换则完全以该文档为准,包括删除 - 适用于另一个系统本就应当作为权威数据源,而不仅仅是数据来源的情形。
  • 目录按表格所用的同一个 key 列合并,两种格式对什么算同一种材料的理解因此完全一致。

在预览显示结果之前,不会应用任何内容

每次导入都先试运行。在写入任何一个值之前,面板会显示将新增多少条、更新多少条,现有价目表与该文件将留下的价目表之间逐字段的差异,每一行读不出来的数据,以及每一个 MetronQ 未能识别的列。

  • 价目表拒绝的行 - 缺少密度、价格不是数字 - 会让整个文件被驳回。绝不会出现只导入一半的情况,因为导入了一半的价目表会给出错误价格,而且没有人看得出错在哪里。
  • 未识别的列会按名称列出。正是它能拦下列位置错位的导出文件,以及表头中的错字:否则这类文件会以毫无改动的方式导入,看上去与一次成功的导入毫无区别。
  • 如果预览打开期间有人保存了价目表,导入会被拒绝,需要重新执行一次:屏幕上的差异已经不再描述真正会发生的事。

每一次确认的导入都会逐字段记入设置变更历史,并标注为导入,因此任何变动过的价格,都能追溯到让它变动的那个文件。

直接对接系统

以上所有操作也可以在无人打开面板的情况下完成:工厂可以签发 API 密钥,交给自己的 ERP、CRM 或自动化工具。访问权限由我们与每家工厂单独商定 - 来信说明所用的系统即可 - 因为集成取决于另一端是什么系统,而不是一个勾选项。密钥属于工厂而不属于某个人,因此创建它的人不在时,它仍照常工作。

  1. 1在面板中打开 设置 > 系统集成。仅账号所有者可见。
  2. 2点击新建密钥,按持有它的系统命名,并勾选它可执行的操作。
  3. 3立即复制密钥。它只显示一次,我们不会保存;一旦遗失,请撤销并新建一个。

第一次对接,分步进行

六个调用,按通常编写的顺序排列。它们使用同一个请求头,能写通第一个就能写通其余全部。基础地址是 https://app.metronq.com,凡路径不以 .csv 结尾的,响应都是 JSON。

1. 检查密钥。whoami 不需要任何权限,会返回密钥属于哪个工厂、它能做什么、还能用多少。这一个调用通了,其余的就只是路径问题。

curl
curl https://app.metronq.com/api/v1/integration/whoami \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "tenant": { "name": "示例精密机械有限公司", "slug": "shili-jingmi", "currency": "CNY" },
  "key": {
    "name": "ERP sync",
    "prefix": "a1b2c3d4",
    "scopes": ["config:read", "quotes:read"],
    "expires_at": "2027-09-16T10:12:00+00:00"
  },
  "rate_limit": {
    "requests_per_minute": 120,
    "requests_per_day": 20000,
    "day_resets": "00:00 UTC",
    "requests_total": 400,
    "requests_total_used": 3,
    "requests_total_remaining": 397
  }
}

2. 读取目录。每个目录一个调用 - materials、machines 或 treatments - 或者用 GET /config 一次取回整份价格文档。

curl
curl https://app.metronq.com/api/v1/integration/catalog/materials \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "catalog": "materials",
  "count": 12,
  "items": [
    {
      "key": "alu_6061",
      "name": "6061 铝",
      "kind": "metal",
      "en_number": "EN AW-6061",
      "din_number": "3.3211",
      "density_g_cm3": 2.7,
      "price_per_kg": 6.4,
      "mrr_rough_cm3_min": 50.0,
      "mrr_turning_cm3_min": 60.0,
      "finishing_rate_cm2_min": 90.0,
      "stock_allowance_mm": 3.0,
      "cutting_speed_m_min": 250.0
    }
  ]
}

3. 轮询新的询价。请求比你已持有的最新 created_at 更晚的全部记录;我们这边不需要维护任何游标。limit 取 1 到 200,offset 翻阅其余部分。

curl
curl "https://app.metronq.com/api/v1/integration/quotes?since=2026-09-16T00:00:00Z&limit=50" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "items": [
    {
      "id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
      "number": 1042,
      "status": "priced",
      "created_at": "2026-09-16T08:41:12+00:00",
      "filename": "bracket.step",
      "material_key": "alu_6061",
      "quantity": 25,
      "unit_price": 330.0,
      "total_price": 8250.0,
      "currency": "CNY",
      "customer_email": "caigou@example.com",
      "external_ref": "",
      "source": "widget"
    }
  ],
  "limit": 50,
  "offset": 0
}

4. 读取分析测得的内容 - 在你需要的是零件而不是价格的时候。每份报价一个调用。

curl
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID/metrics \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "quote_id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
  "analyzed_at": "2026-09-16T08:41:29+00:00",
  "file_extension": ".step",
  "status": "priced",
  "gate_status": "instant",
  "gate_reasons": [],
  "complexity": 34.2,
  "material_key": "alu_6061",
  "quantity": 25,
  "tolerance_class": "standard",
  "surface_finish": "as_machined",
  "confirmed_threads": { "8.0": 4 },
  "geometry_metrics": {
    "bounding_box": { "x": 120.0, "y": 80.0, "z": 18.0 },
    "volume": 74210.5,
    "surface_area": 31890.2,
    "face_count": 46,
    "holes": [
      { "diameter": 8.2, "depth": 18.0, "through": true, "direction": [0, 0, 1] }
    ],
    "pockets": [
      { "depth": 6.0, "floor_area": 1840.0, "corner_radius": 5.0, "open": false }
    ],
    "min_wall_thickness": 3.1,
    "derived": { "volume_ratio": 0.43, "area_ratio": 1.71 }
  },
  "parts": []
}

5. 回写你自己的编号,并按车间实际进度推进订单。只有你发送的字段会被改动。

curl
curl -X PATCH https://app.metronq.com/api/v1/integration/orders/ORDER_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "WO-2026-0912", "status": "in_production"}'
json
{
  "id": "1b7a44c0-9d2e-4e51-8a10-64d1f0a2e777",
  "quote_id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
  "status": "in_production",
  "payment_status": "unpaid",
  "external_ref": "WO-2026-0912",
  "quantity": 25,
  "unit_price": 330.0,
  "total_price": 8250.0,
  "currency": "CNY",
  "customer": { "name": "张三", "email": "caigou@example.com", "city": "上海" }
}

6. 从 ERP 更新价目表 - 两个调用:预览与提交。预览不写入任何内容,并返回一个 base_hash,提交时必须原样带回。

密钥的权限

  • config:read - 读取目录与计价规则。
  • config:write - 更新它们,走的是与面板相同的先预览后应用流程。
  • quotes:read - 读取报价与订单:零件、材料、数量、价格和分析读数。它不再包含客户联系方式 - 那由下面的 customers:read 负责。持有该作用域的密钥可以读取工厂接过的每一条询价,因此只授予确实需要这些任务数据的系统。
  • customers:read - 读取询价与订单上的客户联系方式。它是 quotes:read 的附加项,而非独立作用域:没有它,记录照常返回,只是 customer_email、整个 customer 块以及客户备注为 null。若某系统只需要零件、数量和价格,请不要勾选 - 读不到姓名的密钥,也带不走客户名单。
  • quotes:write - 回写自己的编号,并推进订单状态。不能报价,也不能审批。

任何密钥都不能创建另一个密钥、撤销密钥或更改密钥权限。这些只能由已登录的所有者操作,因此被盗的密钥无法自行延长有效期。除非另行选择,密钥一年后过期;撤销自下一次请求起立即生效。

API 可以读取什么

面板中关于本工厂自己的目录和自己的询价的全部内容,不包含任何其他工厂的数据。每个问题对应一个接口:

  • 材料 - 整个目录:工程师使用的牌号(EN 编号与 Werkstoffnummer)、密度、每公斤单价、金属去除率和切削速度。GET /catalog/materials
  • 机床 - 设备清单:工艺、小时费率、行程、轴数、主轴功率与最高转速、刀库位数、最大工件重量,以及旁边的铭牌信息(制造商、型号、系统、年份、资产编号)。GET /catalog/machines
  • 刀具 - 刀具库的扁平列表,每行标明所属机床以及引擎由此推导出的内圆角半径。GET /tools
  • 切削数据 - 按材料给出报价所依据的切削速度与去除率,按机床给出缩放这些速率的主轴参数。GET /cutting-data
  • 表面处理 - 表面与热处理,含费用和交期。GET /catalog/treatments
  • 询价与订单 - GET /quotes 和 GET /orders,按时间倒序,可用 since= 轮询。单条报价包含价格拆解,订单包含开票与发货的客户信息。
  • 文件的读数 - 分析测得的内容:外形尺寸、重量、孔、型腔、螺纹、面与公差,装配体则逐件给出。GET /quotes/{id}/metrics

其中两项需要各补一句。刀具属于某台机床 - 它是那台主轴能拿到的东西 - 所以每行都标明所属机床;刀具也是目录表格唯一无法承载的内容,因为一行装不下一个列表。而切削数据并非切削参数表:MetronQ 中没有每齿进给,也没有切深,因为工时模型基于每种材料的去除率。该接口公开的是价格背后的全部数字 - 工厂自己的,加上引擎由它们推导出的两个 - 使接入系统对材料的认知与报价引擎保持一致。

每个字段的含义

凡可能产生歧义之处,单位都写在字段名里:_mm、_kg、_cm3_min、_m_min。所有内容都是普通的 JSON 数字或字符串,没有任何已格式化的金额;每个价格都以工厂自己的货币计,该货币由 whoami 返回。

材料(GET /catalog/materials):

  • key - 报价中以 material_key 引用的标识符。你的系统和我们的系统靠它就材料达成一致;改动它是新增一种材料,而不是改名。
  • name - 工厂自己的客户在报价插件和报价单上看到的名称。这是工厂的措辞,因此不作翻译。
  • kind - metal 或 plastic。它决定会提供哪些公差、配合与表面处理。
  • en_number、din_number - 标准牌号(EN AW-6061、1.0503)。给工程师看的;引擎从不参与计算。
  • density_g_cm3 - 密度,单位 g/cm3。零件重量以及由此而来的材料成本都来源于它。
  • price_per_kg - 每公斤采购价,以工厂货币计。这是 ERP 最常写入的字段。
  • mrr_rough_cm3_min - 粗加工去除率,单位 cm3/min,基于 15 kW 的基准主轴。它决定了不同材料加工快慢的差别。
  • mrr_turning_cm3_min - 车削的同一指标。null 表示:使用粗加工去除率。
  • finishing_rate_cm2_min - 精加工走刀覆盖表面的速度,单位 cm2/min。
  • stock_allowance_mm - 选择毛坯时在零件每一侧增加的余量,单位 mm。
  • cutting_speed_m_min - 切削速度 vc,单位 m/min。null 表示由粗加工去除率推导;GET /cutting-data 会给出实际使用的数值。

机床(GET /catalog/machines)- 决定价格或拒绝的字段:

  • key、name - 标识符与车间里使用的名称。
  • technology - milling、turning、bar_turning 或 mill_turn。它决定机床可以接哪些零件,以及适用哪种去除率。
  • hourly_rate - 机时费率,以工厂货币计。我们的目录导入从不写入这一项:这是工厂必须能够解释的数字。
  • envelope_mm - 加工范围。铣床为三个数字(x、y、z);车床则第一个是车削直径,第二个是车削长度。
  • axes - 轴数,铣削为 3 到 5。超过 3 轴时零件所需装夹次数更少。
  • spindle_power_kw - 主轴功率。低于基准 15 kW 时去除率按比例下调;高于基准不会上调,因此填写功率只可能让报价更贵。
  • max_spindle_rpm - 最高转速。仅在小刀具上起作用,即达不到切削速度所需转速的场合。
  • min_tool_radius_mm - 这台机床能留下的最小内圆角。一旦机床有了刀具库,这个值就不再被读取:改由最小的刀具决定。
  • tool_stations、max_workpiece_kg、through_spindle_coolant - 刀库位数、工作台承重、主轴中心内冷。
  • datasheet - maker、model、control、year、serial、inventory_no、notes。仅用于标识;该块中的任何内容都不会进入引擎。

刀具(GET /tools):

json
{
  "count": 2,
  "items": [
    {
      "key": "e12",
      "kind": "endmill",
      "name": "12 mm 硬质合金,4 刃",
      "diameter_mm": 12.0,
      "nose_radius_mm": null,
      "flute_length_mm": 45.0,
      "designation": "",
      "machine_key": "dmu50",
      "machine_name": "DMU 50",
      "cut_radius_mm": 6.0
    }
  ]
}
  • machine_key、machine_name - 该刀具所在的机床。刀具总是属于某一台。
  • kind - drill、endmill、tap、thread_mill、reamer 或 turning_insert。
  • diameter_mm - 切削直径。钻头与铰刀指其加工出的孔;立铣刀指刀具本身;丝锥指螺纹公称直径。
  • nose_radius_mm - 车削刀片的刀尖圆角半径,即它在车削轮廓上能留下的最小圆角。
  • flute_length_mm - 可用切削长度,单位 mm。null 表示未给出限制,引擎也不会施加任何限制。
  • cut_radius_mm - 由我们算出的该刀具能留下的最小内圆角:直径的一半,或刀片的刀尖圆角。一台机床上其中的最小值,就是这台机床实际的内角限制。

切削数据(GET /cutting-data)- 引擎推导出的两列,与工厂自己的数字并列:

json
{
  "reference": { "spindle_power_kw": 15.0, "cutting_speed_m_min": 250.0 },
  "materials": [
    {
      "key": "steel_c45",
      "name": "C45 碳钢",
      "kind": "metal",
      "en_number": "1.0503",
      "din_number": "",
      "density_g_cm3": 7.85,
      "cutting_speed_m_min": null,
      "cutting_speed_effective_m_min": 156.2,
      "machinability_factor": 1.6,
      "mrr_rough_cm3_min": 19.5,
      "mrr_turning_cm3_min": null,
      "mrr_turning_effective_cm3_min": 19.5,
      "finishing_rate_cm2_min": 40.0,
      "stock_allowance_mm": 3.0
    }
  ],
  "machines": [
    {
      "key": "dmu50",
      "name": "DMU 50",
      "technology": "milling",
      "spindle_power_kw": 13.0,
      "max_spindle_rpm": 10000.0,
      "spindle_power_factor": 0.867,
      "min_tool_radius_mm": 1.0,
      "tool_radius_effective_mm": 6.0,
      "tool_count": 2
    }
  ]
}
  • reference - 整份价目表所依据的主轴与切削速度:15 kW 和 250 m/min。返回它们是为了让下面的推导可以核算,而不是只能相信。
  • cutting_speed_effective_m_min - 实际使用的切削速度:工厂填过就用工厂的,否则为 reference / machinability_factor。
  • machinability_factor - 这种材料比铝难加工多少:铝为 1.0,普通钢约 1.6,不锈钢约 3。它是与铝基准去除率之比的平方根。
  • mrr_turning_effective_cm3_min - 已套用回退规则后的车削去除率,读者无需自己再套一遍。
  • spindle_power_factor - 去除率在这台机床上的缩放系数:spindle_power_kw / 15,上限 1.0,下限 0.25。
  • tool_radius_effective_mm - 实际生效的内圆角半径:填写的 min_tool_radius_mm,或者在有刀具库时取库中最小的刀具。

询价与订单(GET /quotes、GET /orders):

  • id - 其余所有调用接受的标识符。number 是给人看的编号,工厂看到的是 WYC-1042 这种形式。
  • status - 询价处于哪一步:created、analyzing、priced、approved、rejected、analysis_failed。只有 priced 和 approved 带有价格。
  • unit_price、total_price、currency - 单件与整批价格,以工厂货币计。从未计算过价格的询价此处为 null。
  • material_key、quantity - 客户所选内容。material_key 指向上面的目录。
  • external_ref - 你自己的编号。在你的系统写入之前为空;之后可用 ?external_ref= 再次找到该任务。
  • source - 询价的来源:widget(工厂自己的网站)或 panel(工艺员上传的文件)。启用该字段之前的询价为空。
  • customer_email - 询价所携带的唯一联系方式。关于此人的其余信息要到下单时才出现。
  • customer_email、customer、note - 若密钥不具备 customers:read,则为 null。customer_data_visible 说明属于哪种情况,因为「该密钥无权读取」与「对方没有留下联系方式」是两件不同的事,混淆二者的客户端会去追一个并不存在的客户。
  • 订单另有:status(new、confirmed、in_production、shipped、cancelled)、payment_status(unpaid、paid),以及带完整开票与收货地址的 customer。
  • breakdown - 仅在 GET /quotes/{id} 中:价格背后已保存的成本拆解,也正是需要在自有账目中核对的系统所需要的。

文件的读数(GET /quotes/{id}/metrics)- 生产准备:

  • geometry_metrics.bounding_box - 外形尺寸,单位 mm。derived.bbox_sorted_dims 是同样三个数字的排序结果,可行性正是据此判定的。
  • geometry_metrics.volume、surface_area - 零件体积(mm3)与表面积(mm2)。derived.volume_ratio 为体积除以包围盒:比值低意味着要去除大量材料。
  • holes[] - 每个被计入的孔:直径、深度、是否通孔及其轴向。孔之所以被计入,是因为它是一个完整的圆,而不是因为它大。
  • pockets[] - 深度、底面面积、内圆角半径,以及型腔是否敞开或通透。
  • min_wall_thickness - 找到的最薄壁厚,单位 mm;若未测得足够薄的部位则为 null。
  • gate_status、gate_reasons - 该报价能否自动完成,若不能则给出原因:code:machine:field:actual:limit,并附上拒绝背后的实测值。

全部调用与示例

基础地址 https://app.metronq.com,密钥放在 Authorization: Bearer 请求头中;除路径以 .csv 结尾者外,请求与响应均为 JSON。每行旁边的权限是密钥必须具备的作用域;whoami 不需要任何权限。

GET /whoami - 无需权限。密钥属于谁、能做什么、还能用多少。这是最先写的调用,也是把日后的 403 变成一句话的调用。

curl
curl https://app.metronq.com/api/v1/integration/whoami \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /config - config:read。整份价格文档:三个目录、全部计价参数、安全闸门、选择策略与货币。导入接受的正是它 - 可以直接把该文档原样回传,无需外层包装。而 replace 模式(会删除文档未列出的项)需要单独声明:{"config": ..., "mode": "replace"}。

curl
curl https://app.metronq.com/api/v1/integration/config \
  -H "Authorization: Bearer mq_live_YOUR_KEY" > pricing.json

GET /catalog/{name} - config:read。以 JSON 返回一个目录,{name} 为 materials、machines 或 treatments。响应为 {catalog, count, items}。

curl
curl https://app.metronq.com/api/v1/integration/catalog/materials \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /catalog/{name}.csv - config:read。同一个目录,形式是面板导出按钮生成的表格:带 Excel 所需 BOM、工厂自己的分隔符、每条一行。机床在这里会失去刀具列表 - 一行装不下。

curl
curl https://app.metronq.com/api/v1/integration/catalog/machines.csv \
  -H "Authorization: Bearer mq_live_YOUR_KEY" > machines.csv
csv
key;name;technology;hourly_rate;min_quantity;envelope_mm.1;envelope_mm.2;...
dmu50;DMU 50;milling;280,00;1;500,0;450,0;400,0;...

GET /tools - config:read。工厂拥有的全部刀具,扁平列表,每行标明所属机床。?machine= 可缩小到一台。

curl
curl https://app.metronq.com/api/v1/integration/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
curl "https://app.metronq.com/api/v1/integration/tools?machine=dmu50" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /machines/{key}/tools - config:read。一台机床的刀具库,以及由此得出的内圆角半径。

curl
curl https://app.metronq.com/api/v1/integration/machines/dmu50/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "machine_key": "dmu50",
  "machine_name": "DMU 50",
  "count": 3,
  "min_tool_radius_mm": 1.0,
  "tool_radius_effective_mm": 3.4,
  "items": [
    {
      "key": "e12",
      "kind": "endmill",
      "name": "12 mm 硬质合金",
      "diameter_mm": 12.0,
      "nose_radius_mm": null,
      "flute_length_mm": 45.0,
      "designation": "",
      "machine_key": "dmu50",
      "machine_name": "DMU 50",
      "cut_radius_mm": 6.0
    },
    { "key": "d6.8", "kind": "drill", "diameter_mm": 6.8, "cut_radius_mm": 3.4, "...": "..." },
    { "key": "m8", "kind": "tap", "diameter_mm": 8.0, "designation": "M8", "...": "..." }
  ]
}

PUT /machines/{key}/tools - config:write。整体替换刀具库。幂等,因此同步方可以直接发送自己持有的列表,无需知道此前是什么。同一 key 出现两次会返回 422 duplicate_tool_key。

curl
curl -X PUT https://app.metronq.com/api/v1/integration/machines/dmu50/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tools": [
        {"key": "e12", "kind": "endmill", "name": "12 mm 硬质合金",
         "diameter_mm": 12.0, "flute_length_mm": 45.0},
        {"key": "d6.8", "kind": "drill", "diameter_mm": 6.8},
        {"key": "m8", "kind": "tap", "diameter_mm": 8.0, "designation": "M8"}
      ]}'

POST /machines/{key}/tools - config:write。新增一把刀具,或替换该 key 下已有的一把。适用于只报告单条变更、而不是重发两百条的系统。

curl
curl -X POST https://app.metronq.com/api/v1/integration/machines/dmu50/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key": "r8h7", "kind": "reamer", "diameter_mm": 8.0}'

DELETE /machines/{key}/tools/{tool} - config:write。删除一把刀具。若该 key 不存在则返回 404,使同步方能区分「确实删除」与「自己映射里写错了」。

curl
curl -X DELETE https://app.metronq.com/api/v1/integration/machines/dmu50/tools/r8h7 \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
提示

写入刀具库会改变这台机床能报什么价。库中最小的立铣刀(车床上则为车削刀片)将成为该机床能留下的最小内圆角,填写的 min_tool_radius_mm 不再被读取;钻头与丝锥不留内圆角,在这里不会产生影响 - 因此只用 12 mm 铣刀描述的设备,会不再接以前能接的零件。正因如此,这里每个响应都返回 tool_radius_effective_mm。空列表会让机床回到它填写的数值。

GET /cutting-data - config:read。按材料给出计价所依据的切削速度与去除率,按机床给出用于缩放这些速率的主轴参数。这不是切削参数表 - 见上文。

curl
curl https://app.metronq.com/api/v1/integration/cutting-data \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

POST /config/import/preview - config:write。这张表格会做什么。不写入任何内容,返回结果文档、新增与更新的键、无法读取的行、未识别的列,以及 base_hash。

curl
curl -X POST https://app.metronq.com/api/v1/integration/config/import/preview \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"catalog\": \"materials\", \"csv_base64\": \"$(base64 -w0 materials.csv)\"}"

POST /config/import/preview-json - config:write。对整份文档同理。merge 只应用文档明确写出的内容;replace 则让它完全生效,包括删除。

curl
curl -X POST https://app.metronq.com/api/v1/integration/config/import/preview-json \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "merge", "config": {"materials": [ ... ], "machines": [ ... ]}}'

POST /config/import - config:write。应用预览返回的内容,并带上随附的 base_hash。若期间有人保存了价目表,返回 409 config_changed。响应为已保存的文档。

curl
curl -X POST https://app.metronq.com/api/v1/integration/config/import \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d @commit.json      # {"config": ..., "base_hash": "..."} from the preview
json
{
  "materials": [ { "key": "alu-6061", "price_per_kg": 32.0, "...": "..." } ],
  "machines": [ "..." ],
  "treatments": [ "..." ],
  "params": { "margin_pct": 30.0, "...": "..." },
  "gates": { "mode": "review_all", "...": "..." },
  "machine_selection": "cheapest",
  "stock_selection": "cheapest",
  "currency": "PLN"
}

GET /quotes - quotes:read。询价,按时间倒序。since= 用于轮询;status=、external_ref=、limit(1-200)与 offset 负责其余部分。若无 customers:read,联系方式字段为 null。

curl
curl "https://app.metronq.com/api/v1/integration/quotes?since=2026-09-16T00:00:00Z&status=priced&limit=50&offset=0" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /quotes/{id} - quotes:read。单条询价,含价格背后已保存的成本拆解。

curl
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /quotes/{id}/metrics - quotes:read。分析测得的内容。文件仍在读取时返回 409 not_analysed - 意思是「稍后再问」,不是「标识符错误」。

curl
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID/metrics \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /orders - quotes:read。订单,按时间倒序,筛选参数相同。工厂移入回收站的订单不在其中。若无 customers:read,联系方式字段为 null。

curl
curl "https://app.metronq.com/api/v1/integration/orders?since=2026-09-16T00:00:00Z&external_ref=WO-2026-0912" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "items": [
    {
      "id": "1b7a44c0-9d2e-4e51-8a10-64d1f0a2e777",
      "quote_id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
      "status": "confirmed",
      "payment_status": "unpaid",
      "created_at": "2026-09-16T09:12:40+00:00",
      "paid_at": null,
      "quantity": 25,
      "unit_price": 330.0,
      "total_price": 8250.0,
      "currency": "CNY",
      "external_ref": "WO-2026-0912",
      "customer": {
        "name": "张三",
        "email": "caigou@example.com",
        "company": "示例机械有限公司",
        "phone": "+86 21 0000 0000",
        "address": "示例路 12 号",
        "postcode": "200000",
        "city": "上海"
      },
      "note": ""
    }
  ],
  "limit": 100,
  "offset": 0
}

GET /orders/{id} - quotes:read。单个订单,含开票与收货的客户信息。

curl
curl https://app.metronq.com/api/v1/integration/orders/ORDER_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

PATCH /quotes/{id} - quotes:write。在询价上写入自己的编号,仅此而已:价格与审批属于引擎和工艺员。

curl
curl -X PATCH https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "RFQ-2026-0455"}'

PATCH /orders/{id} - quotes:write。自己的编号、状态与付款标记。只改动请求体中出现的字段。confirmed 与 shipped 会向工厂的客户发送邮件。

curl
curl -X PATCH https://app.metronq.com/api/v1/integration/orders/ORDER_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "WO-2026-0912", "status": "in_production",
       "payment_status": "paid"}'

一把密钥可用多少请求

API 访问权限由我们与每家工厂单独商定,限额同样如此 - 它们属于同一份约定,而不是公开的资费表。已商定的集成按每分钟 120 次请求、每天 20 000 次运行,自 UTC 00:00 起计算。每小时同步一次目录、每分钟轮询一次报价,远远用不完;若贵方系统需要更多,请告诉我们,我们会设定合适的数值。工厂也可以在创建时,把某一把自己的密钥限得比其他密钥更严。

为试用签发的密钥则带有第三个数字:整个测试期间共 400 次请求,它们不会在第二天恢复。这就是免费测试的规模:足以据此构建一套集成 - 通读整个接口约三十次调用,上面的分步指南六次 - 但不足以长期运行一套集成,那是已商定集成的用途。面板在设置 - 集成中显示该额度以及已用量,whoami 以 requests_total 返回。用完后返回 429 与 total_quota_exceeded,且不带 Retry-After:没有某个时刻它会自行恢复。

每个响应都会告知当前剩余,使客户端能在触及上限之前调整节奏,而不是之后。最后两行仅在试用总额生效期间出现:

http
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 41
X-RateLimit-Quota: 20000
X-RateLimit-Quota-Remaining: 19863
X-RateLimit-Quota-Reset: 51240
X-RateLimit-Total: 400
X-RateLimit-Total-Remaining: 347

拒绝的含义

每个错误都在响应体中给出一个简短代码,可以据此采取行动的正是它 - 仅凭 HTTP 状态码无法判断下一步该做什么。

  • 429 rate_limited - 分钟窗口已满。稍后同一请求即可成功;Retry-After 给出秒数。
  • 429 daily_quota_exceeded - 当日额度用尽。Retry-After 倒数至 UTC 00:00。
  • 429 total_quota_exceeded - 试用总额用尽。不带 Retry-After,因为等待改变不了什么。
  • 401 invalid_api_key - 密钥未知、已吐销、已过期,或账户的 API 访问已关闭。故意对所有情况给出同一答案:区分它们对窃取密钥的人有价值,对密钥所有者没有。
  • 403 missing_scope - 密钥有效,但不具备此接口所需的权限。重试无效,换一把权限正确的密钥才有效。
  • 404 not_found、unknown_catalog、unknown_machine - 该账户下没有这条报价、订单、目录或机床。
  • 409 config_changed - 在预览与提交之间有人保存了价目表,因此所提交的文档已不再描述实际会发生的变更。请重新读取配置、重新预览、重新提交。
  • 409 not_analysed - 报价存在,但尚无读数。文件仍在分析中,稍后再请求。
  • 422 - 表格或文档被拒绝,且未写入任何内容。响应体说明原因,预览则列出背后的行与列。
提示

请把 mq_live_ 这一模式加入贵团队使用的密钥扫描工具,这样误提交的密钥会像其他凭据一样被发现。

谁可以操作

导入与导出遵循「报价规则」权限,因此所有者以及任何获得该标签页权限的员工都可以使用。导出是在已登录会话中的普通下载;除此之外,没有任何文件会离开账号。

本页没有涵盖的需求 - 定时同步,或者让报价在生成时就推送到加工厂自己的系统 - 可以写信到 contact@metronq.com 并说明所用的系统;我们据此决定下一步做什么。