ARCNM

API reference

Materials

The Materials API looks up material grades and manages per-tenant overrides.

The Materials API looks up material grades and manages per-tenant overrides: search grades, resolve one by URN, and create, update, or delete cost overrides.

Auto-generated from the public OpenAPI spec — this page never drifts from the running API. Base URL https://api.arcnm.io. Authenticate with the X-API-Key header (see Authentication).

List Grades

GET /api/v1/materials/grades

List the material grades available to you.

That is the standards catalogue plus any grade your organization has registered for itself.

q searches across primary_code, display_code, name, urn AND every alias's code/display_code. A user typing "AISI 304", "SUS304" or "S30400" therefore finds 1.4301 from this single endpoint — no need to fall back to POST /lookup.

Returns the total matching row count (not page size) so the frontend can paginate properly.

Paginated. Pass cursor (from the previous response) to fetch the next page; limit caps the page size.

Parameters

Name In Type Required Description
category query carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other no Filter by material category (e.g. stainless_steel, aluminium).
iso_group query P | M | K | N | S | H no Filter by ISO 513 machining group (P, M, K, N, S, H).
q query string no Free-text search across grade codes, names, URNs, and aliases.
include_inactive query boolean no Include grades your organization has deactivated. They stay out of the list by default; set this to find one again and reactivate it.
cursor query string no Opaque position token from the previous page's next_cursor (or the Link / X-Next-Cursor response header). Omit it for the first page. Keep every other query parameter identical for the whole walk — a cursor replayed against different filters is rejected.
limit query integer no Maximum rows to return in one page.
offset query integer no Rows to skip. Superseded by cursor, which is stable under concurrent writes; kept for existing integrations. Bounded — past the cap, page with cursor.

Request

curl -X GET https://api.arcnm.io/api/v1/materials/grades \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/grades",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
count integer Total number of grades matching the query (not the page size).
data MaterialGradePublic[] The material grades on this page.
has_more boolean Whether more grades match beyond this page.
next_cursor string Position token for the next page — pass it back as cursor. Null on the last page.

Example response

{
  "count": 0,
  "data": [
    {
      "aliases": [
        {}
      ],
      "attributes": {},
      "category": "carbon_steel",
      "created_at": "2026-06-01T12:00:00Z",
      "density_kg_per_m3": 0,
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "is_active": true,
      "iso_machining_group": "P",
      "name": "string",
      "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "primary_code": "string",
      "primary_standard_code": "en10027-1",
      "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "updated_at": "2026-06-01T12:00:00Z",
      "urn": "string"
    }
  ],
  "has_more": false,
  "next_cursor": "string"
}

Create Org Grade

POST /api/v1/materials/grades

Register a material grade private to your organization.

For a material the standards catalogue does not carry — a house designation, an internal blank, a supplier-specific grade. Only your organization can see or resolve it, and it prices exactly like a catalogue grade: give it a €/kg rate on an environment, or let the category default stand until you do.

The designation is fixed once registered, and one that already resolves for you — a catalogue code, a standard alias, or another of your own grades — is refused.

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata: yield_mpa, tensile_mpa, coating, …
category carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other yes Broad material family the grade belongs to (e.g. carbon_steel, aluminium).
density_kg_per_m3 number yes Material density in kilograms per cubic metre — steel is about 7850, aluminium about 2700. Mind the unit: a value in g/cm³ is 1000x too small and is rejected.
designation string yes Your designation for the grade (e.g. 'WS-42-Blank'). Letters, digits, dots and hyphens; rendered as entered, stored URN-safe. Must not collide with a catalogue code.
iso_machining_group P | M | K | N | S | H yes ISO 513 machining group (P/M/K/N/S/H) — required; drives cutting data.
name string yes Human-readable name of the material.

Request

curl -X POST https://api.arcnm.io/api/v1/materials/grades \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "carbon_steel",
    "designation": "string",
    "name": "string",
    "iso_machining_group": "P",
    "density_kg_per_m3": 0
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/materials/grades",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "category": "carbon_steel",
        "designation": "string",
        "name": "string",
        "iso_machining_group": "P",
        "density_kg_per_m3": 0
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "category": "carbon_steel",
    "designation": "string",
    "name": "string",
    "iso_machining_group": "P",
    "density_kg_per_m3": 0
  }),
})
const data = await resp.json()

Responses

Status Description
201 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 201

Field Type Description
aliases MaterialGradeAliasPublic[] Cross-references mapping this grade's code across other standards and trade names.
attributes object Free-form key/value metadata for extra mechanical and physical properties.
category carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other Broad material family the grade belongs to (e.g. steel, aluminium, polymer).
created_at string Timestamp when the grade record was created.
density_kg_per_m3 number Material density in kilograms per cubic metre.
id string Unique identifier of the material grade.
is_active boolean Whether the grade is currently active and selectable; false when retired.
iso_machining_group P | M | K | N | S | H ISO 513 machining group (P/M/K/N/S/H) used to gauge machinability.
name string Human-readable name of the material grade.
org_id string Null → platform-catalogue grade shared by every organization; set → this organization's private grade.
primary_code string Standards-compliant cased display code; the same value as display_code.
primary_standard_code en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org URN-safe code of the primary standard (en10027-2, iso1043-1, …). Hydrated by the routes layer so frontends can render a badge without a second round-trip.
primary_standard_id string Identifier of the standard that defines this grade's primary code.
successor_grade_id string Identifier of the grade that supersedes this one; null when still current.
updated_at string Timestamp when the grade record was last updated.
urn string Canonical URN that uniquely and stably identifies this grade across systems.

Example response

{
  "aliases": [
    {
      "code": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "is_canonical": false,
      "is_preferred_display": true,
      "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "standard_code": "en10027-1",
      "standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    }
  ],
  "attributes": {},
  "category": "carbon_steel",
  "created_at": "2026-06-01T12:00:00Z",
  "density_kg_per_m3": 0,
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "iso_machining_group": "P",
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "primary_code": "string",
  "primary_standard_code": "en10027-1",
  "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Delete Org Grade

DELETE /api/v1/materials/grades/{grade_id}

Delete an org-private grade. Refused (409) while environment material prices or calculations still reference it — deactivate it instead (PATCH {is_active: false}) to keep history intact.

Parameters

Name In Type Required Description
grade_id path string yes Identifier of the grade.

Request

curl -X DELETE https://api.arcnm.io/api/v1/materials/grades/{grade_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.delete(
    "https://api.arcnm.io/api/v1/materials/grades/{grade_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades/{grade_id}", {
  method: "DELETE",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
message string Human-readable confirmation that the resource was deleted.

Example response

{
  "message": "string"
}

Get Grade

GET /api/v1/materials/grades/{grade_id}

Parameters

Name In Type Required Description
grade_id path string yes Identifier of the grade.

Request

curl -X GET https://api.arcnm.io/api/v1/materials/grades/{grade_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/grades/{grade_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades/{grade_id}", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
aliases MaterialGradeAliasPublic[] Cross-references mapping this grade's code across other standards and trade names.
attributes object Free-form key/value metadata for extra mechanical and physical properties.
category carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other Broad material family the grade belongs to (e.g. steel, aluminium, polymer).
created_at string Timestamp when the grade record was created.
density_kg_per_m3 number Material density in kilograms per cubic metre.
id string Unique identifier of the material grade.
is_active boolean Whether the grade is currently active and selectable; false when retired.
iso_machining_group P | M | K | N | S | H ISO 513 machining group (P/M/K/N/S/H) used to gauge machinability.
name string Human-readable name of the material grade.
org_id string Null → platform-catalogue grade shared by every organization; set → this organization's private grade.
primary_code string Standards-compliant cased display code; the same value as display_code.
primary_standard_code en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org URN-safe code of the primary standard (en10027-2, iso1043-1, …). Hydrated by the routes layer so frontends can render a badge without a second round-trip.
primary_standard_id string Identifier of the standard that defines this grade's primary code.
successor_grade_id string Identifier of the grade that supersedes this one; null when still current.
updated_at string Timestamp when the grade record was last updated.
urn string Canonical URN that uniquely and stably identifies this grade across systems.

Example response

{
  "aliases": [
    {
      "code": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "is_canonical": false,
      "is_preferred_display": true,
      "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "standard_code": "en10027-1",
      "standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    }
  ],
  "attributes": {},
  "category": "carbon_steel",
  "created_at": "2026-06-01T12:00:00Z",
  "density_kg_per_m3": 0,
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "iso_machining_group": "P",
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "primary_code": "string",
  "primary_standard_code": "en10027-1",
  "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Update Org Grade

PATCH /api/v1/materials/grades/{grade_id}

Partial update of an org-private grade. designation and category are immutable (both are baked into the URN); use is_active: false to retire a grade from pickers without deleting history.

Parameters

Name In Type Required Description
grade_id path string yes Identifier of the grade.

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata attached to the grade.
density_kg_per_m3 number no Material density in kilograms per cubic metre. Mind the unit: a value in g/cm³ is 1000x too small and is rejected.
is_active boolean no Set false to retire the grade from pickers without deleting history.
iso_machining_group P | M | K | N | S | H no ISO 513 machining group (P/M/K/N/S/H).
name string no Human-readable name of the material.

Request

curl -X PATCH https://api.arcnm.io/api/v1/materials/grades/{grade_id} \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "attributes": {},
    "density_kg_per_m3": 0,
    "is_active": true,
    "iso_machining_group": "P",
    "name": "string"
  }'
import requests

resp = requests.patch(
    "https://api.arcnm.io/api/v1/materials/grades/{grade_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "attributes": {},
        "density_kg_per_m3": 0,
        "is_active": True,
        "iso_machining_group": "P",
        "name": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades/{grade_id}", {
  method: "PATCH",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "attributes": {},
    "density_kg_per_m3": 0,
    "is_active": true,
    "iso_machining_group": "P",
    "name": "string"
  }),
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
aliases MaterialGradeAliasPublic[] Cross-references mapping this grade's code across other standards and trade names.
attributes object Free-form key/value metadata for extra mechanical and physical properties.
category carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other Broad material family the grade belongs to (e.g. steel, aluminium, polymer).
created_at string Timestamp when the grade record was created.
density_kg_per_m3 number Material density in kilograms per cubic metre.
id string Unique identifier of the material grade.
is_active boolean Whether the grade is currently active and selectable; false when retired.
iso_machining_group P | M | K | N | S | H ISO 513 machining group (P/M/K/N/S/H) used to gauge machinability.
name string Human-readable name of the material grade.
org_id string Null → platform-catalogue grade shared by every organization; set → this organization's private grade.
primary_code string Standards-compliant cased display code; the same value as display_code.
primary_standard_code en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org URN-safe code of the primary standard (en10027-2, iso1043-1, …). Hydrated by the routes layer so frontends can render a badge without a second round-trip.
primary_standard_id string Identifier of the standard that defines this grade's primary code.
successor_grade_id string Identifier of the grade that supersedes this one; null when still current.
updated_at string Timestamp when the grade record was last updated.
urn string Canonical URN that uniquely and stably identifies this grade across systems.

Example response

{
  "aliases": [
    {
      "code": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "is_canonical": false,
      "is_preferred_display": true,
      "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "standard_code": "en10027-1",
      "standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    }
  ],
  "attributes": {},
  "category": "carbon_steel",
  "created_at": "2026-06-01T12:00:00Z",
  "density_kg_per_m3": 0,
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "iso_machining_group": "P",
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "primary_code": "string",
  "primary_standard_code": "en10027-1",
  "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Get Grade Master

GET /api/v1/materials/grades/{grade_id}/master

The material master record for one grade.

SAP-style split: the grade row is the client-level basic data (canonical catalogue, or your org-private grade), the override is your organization's layer (SKU, trade name, property overrides), and pricing is the plant-level costing view — the €/kg each of your costing environments would actually use today, each entry labelled env_rate (that environment's own material rate wins) or platform_default (the seed fallback applies). Reuses the calc path's own resolver, so display and pricing cannot disagree.

Parameters

Name In Type Required Description
grade_id path string yes Identifier of the grade.

Request

curl -X GET https://api.arcnm.io/api/v1/materials/grades/{grade_id}/master \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/grades/{grade_id}/master",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades/{grade_id}/master", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
effective_properties MaterialPropertyValue[] Merged property view in vocabulary order — your values win over catalogue figures, each entry labelled with its source.
grade MaterialGradePublic The grade record (canonical catalogue or your org-private grade), aliases included.
override OrgMaterialOverridePublic Your organization's override row for this grade; null when none exists.
pricing MaterialMasterPricing Per-environment €/kg with provenance, plus the platform fallback.

Example response

{
  "effective_properties": [
    {
      "basis": "minimum",
      "canonical_value": 0,
      "key": "string",
      "source": "canonical",
      "unit": "string",
      "value": 0
    }
  ],
  "grade": {
    "aliases": [
      {
        "code": "string",
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "is_canonical": false,
        "is_preferred_display": true,
        "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "standard_code": "en10027-1",
        "standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      }
    ],
    "attributes": {},
    "category": "carbon_steel",
    "created_at": "2026-06-01T12:00:00Z",
    "density_kg_per_m3": 0,
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "is_active": true,
    "iso_machining_group": "P",
    "name": "string",
    "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "primary_code": "string",
    "primary_standard_code": "en10027-1",
    "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "updated_at": "2026-06-01T12:00:00Z",
    "urn": "string"
  },
  "override": {
    "attributes": {},
    "created_at": "2026-06-01T12:00:00Z",
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "internal_code": "string",
    "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "notes": "string",
    "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "trade_name": "string",
    "updated_at": "2026-06-01T12:00:00Z",
    "urn": "string"
  },
  "pricing": {
    "default_basis": "category",
    "default_basis_key": "other",
    "default_currency": "EUR",
    "default_price_per_kg": 0,
    "environments": [
      {
        "currency": "EUR",
        "env_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "env_name": "string",
        "env_region": "string",
        "price_per_kg": 0,
        "source": "env_rate",
        "valid_from": "2026-06-01",
        "valid_to": "2026-06-01"
      }
    ]
  }
}

Upsert Grade Override

PUT /api/v1/materials/grades/{grade_id}/override

Upsert your organization's master-data layer for a grade.

Creates the org's override row for the grade when none exists, otherwise updates it in place. Identification fields (internal_code, trade_name, notes) follow patch semantics — only keys present in the body are touched, null clears. properties is validated against the closed vocabulary (yield_mpa, tensile_mpa, hardness_hb, elongation_pct; sanity-ranged); a numeric value overrides the catalogue figure, null clears your override so the catalogue figure applies again.

Property overrides are quoting/display master data — they do NOT change the physics inputs (density, ISO 513 group stay canonical) and they do NOT change €/kg (that lives in the environment rates).

Parameters

Name In Type Required Description
grade_id path string yes Identifier of the grade.

Request body (application/json)

Field Type Required Description
internal_code string no Org-internal SKU / part code for this material; null clears it.
notes string no Free-text notes attached to this material by the organization; null clears them.
properties object no Property overrides keyed by the closed vocabulary (yield_mpa, tensile_mpa, hardness_hb, elongation_pct). A numeric value overrides the catalogue figure; null clears your override so the catalogue figure applies again. Keys not mentioned are left unchanged.
trade_name string no Vendor trade name (e.g. 'Inconel 718'); null clears it.

Request

curl -X PUT https://api.arcnm.io/api/v1/materials/grades/{grade_id}/override \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "internal_code": "string",
    "notes": "string",
    "properties": {},
    "trade_name": "string"
  }'
import requests

resp = requests.put(
    "https://api.arcnm.io/api/v1/materials/grades/{grade_id}/override",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "internal_code": "string",
        "notes": "string",
        "properties": {},
        "trade_name": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades/{grade_id}/override", {
  method: "PUT",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "internal_code": "string",
    "notes": "string",
    "properties": {},
    "trade_name": "string"
  }),
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
attributes object Free-form key/value metadata attached to this material by the organization.
created_at string Timestamp when the override was created.
id string Unique identifier of the override.
internal_code string Org-internal SKU / part code for this material.
material_grade_id string Identifier of the canonical grade this override extends; null when fully org-private.
notes string Free-text notes attached to this material by the organization.
org_id string Identifier of the organization that owns this override.
trade_name string Vendor trade name (e.g. 'Inconel 718').
updated_at string Timestamp when the override was last updated.
urn string Canonical or org-private URN identifying the material.

Example response

{
  "attributes": {},
  "created_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "internal_code": "string",
  "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "notes": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "trade_name": "string",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Get Grade By Urn

GET /api/v1/materials/grades/by-urn/{urn}

Parameters

Name In Type Required Description
urn path string yes Material grade URN to resolve (e.g. urn:material:cen:1.4301).

Request

curl -X GET https://api.arcnm.io/api/v1/materials/grades/by-urn/{urn} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/grades/by-urn/{urn}",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/grades/by-urn/{urn}", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
aliases MaterialGradeAliasPublic[] Cross-references mapping this grade's code across other standards and trade names.
attributes object Free-form key/value metadata for extra mechanical and physical properties.
category carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other Broad material family the grade belongs to (e.g. steel, aluminium, polymer).
created_at string Timestamp when the grade record was created.
density_kg_per_m3 number Material density in kilograms per cubic metre.
id string Unique identifier of the material grade.
is_active boolean Whether the grade is currently active and selectable; false when retired.
iso_machining_group P | M | K | N | S | H ISO 513 machining group (P/M/K/N/S/H) used to gauge machinability.
name string Human-readable name of the material grade.
org_id string Null → platform-catalogue grade shared by every organization; set → this organization's private grade.
primary_code string Standards-compliant cased display code; the same value as display_code.
primary_standard_code en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org URN-safe code of the primary standard (en10027-2, iso1043-1, …). Hydrated by the routes layer so frontends can render a badge without a second round-trip.
primary_standard_id string Identifier of the standard that defines this grade's primary code.
successor_grade_id string Identifier of the grade that supersedes this one; null when still current.
updated_at string Timestamp when the grade record was last updated.
urn string Canonical URN that uniquely and stably identifies this grade across systems.

Example response

{
  "aliases": [
    {
      "code": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "is_canonical": false,
      "is_preferred_display": true,
      "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "standard_code": "en10027-1",
      "standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    }
  ],
  "attributes": {},
  "category": "carbon_steel",
  "created_at": "2026-06-01T12:00:00Z",
  "density_kg_per_m3": 0,
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "iso_machining_group": "P",
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "primary_code": "string",
  "primary_standard_code": "en10027-1",
  "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Lookup

POST /api/v1/materials/lookup

Exact resolve of a material reference to a single canonical grade.

On a near-miss this still 404s (back-compat), but the error now carries up to five ranked candidates in its details so a caller can pick and retry without a second call. For a fuzzy 'did you mean' list that never dead-ends, use POST /materials/suggest instead.

Request body (application/json)

Field Type Required Description
query string yes URN, EN/UNS/AISI/JIS code, trade name, or org internal code.
standard en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org no Optional hint — restrict alias search to this standard.

Request

curl -X POST https://api.arcnm.io/api/v1/materials/lookup \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "string"
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/materials/lookup",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "query": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/lookup", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "query": "string"
  }),
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
grade MaterialGradePublic The canonical material grade the query resolved to.
matched_via urn | legacy_urn | primary_code | alias | org_override | org_private Path the resolver used: urn
standard_used en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org Material standard the match resolved against; null if not standard-specific.

Example response

{
  "grade": {
    "aliases": [
      {
        "code": "string",
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "is_canonical": false,
        "is_preferred_display": true,
        "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "standard_code": "en10027-1",
        "standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      }
    ],
    "attributes": {},
    "category": "carbon_steel",
    "created_at": "2026-06-01T12:00:00Z",
    "density_kg_per_m3": 0,
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "is_active": true,
    "iso_machining_group": "P",
    "name": "string",
    "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "primary_code": "string",
    "primary_standard_code": "en10027-1",
    "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "updated_at": "2026-06-01T12:00:00Z",
    "urn": "string"
  },
  "matched_via": "urn",
  "standard_used": "en10027-1"
}

Lookup Batch

POST /api/v1/materials/lookup/batch

Bulk-resolve up to 100 queries in one round-trip.

Drawing analysis emits N candidate strings per part; the worker and the frontend typeahead both call this endpoint instead of N individual /lookup requests. Misses are returned in-band with result=null so callers can correlate hits/misses by position.

Request body (application/json)

Field Type Required Description
queries string[] yes Material query strings to resolve in one round-trip (1–100).
standard en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org no Optional hint applied to every query in the batch.

Request

curl -X POST https://api.arcnm.io/api/v1/materials/lookup/batch \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queries": [
      "string"
    ]
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/materials/lookup/batch",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "queries": [
            "string"
        ]
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/lookup/batch", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "queries": [
      "string"
    ]
  }),
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
entries MaterialLookupBatchEntry[] One result slot per query, in the order the queries were supplied.
matched_count integer Number of queries in the batch that resolved to a grade.
miss_count integer Number of queries in the batch that did not resolve.

Example response

{
  "entries": [
    {
      "query": "string",
      "result": {
        "grade": {},
        "matched_via": "urn",
        "standard_used": "en10027-1"
      }
    }
  ],
  "matched_count": 0,
  "miss_count": 0
}

List Overrides

GET /api/v1/materials/overrides

Request

curl -X GET https://api.arcnm.io/api/v1/materials/overrides \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/overrides",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/overrides", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Create Override

POST /api/v1/materials/overrides

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata attached to this material by the organization.
internal_code string no Org-internal SKU / part code for this material.
material_grade_id string no Canonical grade this override extends. NULL → fully org-private material not in the global catalogue (requires urn populated).
notes string no Free-text notes attached to this material by the organization.
trade_name string no Vendor trade name (e.g. 'Inconel 718').
urn string no Canonical or org-private URN (urn:arc:mat:…:…).

Request

curl -X POST https://api.arcnm.io/api/v1/materials/overrides \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "attributes": {},
    "internal_code": "string",
    "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "notes": "string",
    "trade_name": "string",
    "urn": "string"
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/materials/overrides",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "attributes": {},
        "internal_code": "string",
        "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "notes": "string",
        "trade_name": "string",
        "urn": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/overrides", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "attributes": {},
    "internal_code": "string",
    "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "notes": "string",
    "trade_name": "string",
    "urn": "string"
  }),
})
const data = await resp.json()

Responses

Status Description
201 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 201

Field Type Description
attributes object Free-form key/value metadata attached to this material by the organization.
created_at string Timestamp when the override was created.
id string Unique identifier of the override.
internal_code string Org-internal SKU / part code for this material.
material_grade_id string Identifier of the canonical grade this override extends; null when fully org-private.
notes string Free-text notes attached to this material by the organization.
org_id string Identifier of the organization that owns this override.
trade_name string Vendor trade name (e.g. 'Inconel 718').
updated_at string Timestamp when the override was last updated.
urn string Canonical or org-private URN identifying the material.

Example response

{
  "attributes": {},
  "created_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "internal_code": "string",
  "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "notes": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "trade_name": "string",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Delete Override

DELETE /api/v1/materials/overrides/{override_id}

Parameters

Name In Type Required Description
override_id path string yes Identifier of the override.

Request

curl -X DELETE https://api.arcnm.io/api/v1/materials/overrides/{override_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.delete(
    "https://api.arcnm.io/api/v1/materials/overrides/{override_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/overrides/{override_id}", {
  method: "DELETE",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
message string Human-readable confirmation that the resource was deleted.

Example response

{
  "message": "string"
}

Update Override

PATCH /api/v1/materials/overrides/{override_id}

Partial update. Only fields explicitly present in the body are applied — pass null to clear a field, omit to leave unchanged.

Parameters

Name In Type Required Description
override_id path string yes Identifier of the override.

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata attached to this material by the organization.
internal_code string no Org-internal SKU or part code for this material.
material_grade_id string no Identifier of the canonical grade this override extends; null when fully org-private.
notes string no Free-text notes attached to this material by the organization.
trade_name string no Vendor trade name for this material (e.g. 'Inconel 718').
urn string no Canonical or org-private URN identifying the material.

Request

curl -X PATCH https://api.arcnm.io/api/v1/materials/overrides/{override_id} \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "attributes": {},
    "internal_code": "string",
    "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "notes": "string",
    "trade_name": "string",
    "urn": "string"
  }'
import requests

resp = requests.patch(
    "https://api.arcnm.io/api/v1/materials/overrides/{override_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "attributes": {},
        "internal_code": "string",
        "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "notes": "string",
        "trade_name": "string",
        "urn": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/overrides/{override_id}", {
  method: "PATCH",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "attributes": {},
    "internal_code": "string",
    "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "notes": "string",
    "trade_name": "string",
    "urn": "string"
  }),
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
404 not_found A referenced resource doesn't exist or isn't visible to your organisation.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
attributes object Free-form key/value metadata attached to this material by the organization.
created_at string Timestamp when the override was created.
id string Unique identifier of the override.
internal_code string Org-internal SKU / part code for this material.
material_grade_id string Identifier of the canonical grade this override extends; null when fully org-private.
notes string Free-text notes attached to this material by the organization.
org_id string Identifier of the organization that owns this override.
trade_name string Vendor trade name (e.g. 'Inconel 718').
updated_at string Timestamp when the override was last updated.
urn string Canonical or org-private URN identifying the material.

Example response

{
  "attributes": {},
  "created_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "internal_code": "string",
  "material_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "notes": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "trade_name": "string",
  "updated_at": "2026-06-01T12:00:00Z",
  "urn": "string"
}

Pricing Coverage

GET /api/v1/materials/pricing-coverage

What every grade costs, and which environments set that price.

One round-trip for the master-data list: entries carries the €/kg of each grade an environment has its own rate for, and defaults carries the platform price per category that every other grade is charged at. Uses the same effective-dating / currency predicates as the calculation path, so the prices shown can never disagree with the price actually charged.

Request

curl -X GET https://api.arcnm.io/api/v1/materials/pricing-coverage \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/pricing-coverage",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/pricing-coverage", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
defaults MaterialCategoryDefaultPrice[] The platform price per kilogram for every material category — what a grade costs wherever no environment rate applies.
entries MaterialPricingCoverageEntry[] One entry per grade that has at least one active environment rate.
environments MaterialCoverageEnvironment[] Your organization's costing environments.

Example response

{
  "defaults": [
    {
      "basis": "category",
      "basis_key": "string",
      "category": "carbon_steel",
      "currency": "EUR",
      "price_per_kg": 0
    }
  ],
  "entries": [
    {
      "grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "priced_env_ids": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "prices": [
        {}
      ]
    }
  ],
  "environments": [
    {
      "currency": "EUR",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string"
    }
  ]
}

List Standards

GET /api/v1/materials/standards

Request

curl -X GET https://api.arcnm.io/api/v1/materials/standards \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/materials/standards",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/standards", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Suggest

POST /api/v1/materials/suggest

Fuzzy material lookup that never dead-ends on a 404.

Resolves an exact canonical grade when the query is unambiguous, and ALWAYS returns ranked candidates — so a partial code ('S3040'), a trade name, or a generic term ('Stahl', 'stainless') gets a 'did you mean' list to pick from. Pass a candidate's urn back as material_ref to price against it.

Request body (application/json)

Field Type Required Description
category carbon_steel | alloy_steel | stainless_steel | tool_steel | cast_iron | aluminium | copper_alloy | nickel_alloy | titanium_alloy | magnesium_alloy | zinc_alloy | thermoplastic | thermoset | elastomer | composite | other no Optional category filter for the candidates.
limit integer no Maximum ranked candidates to return.
query string yes Free-form material text: a code, partial code, trade name, or generic term.
standard en10027-1 | en10027-2 | en10025 | en10083 | en10084 | en10088 | en10346 | en-iso-4957 | en573-1 | en573-2 | en1412 | din17007 | en1560 | en1561 | en1563 | iso1043-1 | iso1043-2 | iso18064 | uns | aisi-sae | jis | astm | eclass | unspsc | org no Optional standard hint applied to the exact-match pass.

Request

curl -X POST https://api.arcnm.io/api/v1/materials/suggest \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "string"
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/materials/suggest",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "query": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/materials/suggest", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "query": "string"
  }),
})
const data = await resp.json()

Responses

Status Description
200 Successful Response
422 Validation Error

Errors

Standard error responses — see the Errors catalog for the full envelope, request_id, and retry-safety table.

Status Code When
401 invalid_api_key Missing, malformed, or revoked API key.
403 insufficient_scope The key is valid but lacks a scope this endpoint requires.
409 conflict A conflicting change, or an Idempotency-Key reused with a different body.
429 rate_limited Per-key or per-org rate limit exceeded — back off with jitter and retry.

Response body 200

Field Type Description
candidates MaterialCandidate[] Ranked near-matches, best first; empty only when nothing in the catalogue is close.
query string The query string, echoed back.
resolved MaterialLookupResult The exact canonical grade when the query resolves unambiguously; null on a fuzzy-only match.

Example response

{
  "candidates": [
    {
      "category": "carbon_steel",
      "grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "matched_on": "string",
      "name": "string",
      "primary_code": "string",
      "score": 0,
      "urn": "string"
    }
  ],
  "query": "string",
  "resolved": {
    "grade": {
      "aliases": [
        {}
      ],
      "attributes": {},
      "category": "carbon_steel",
      "created_at": "2026-06-01T12:00:00Z",
      "density_kg_per_m3": 0,
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "is_active": true,
      "iso_machining_group": "P",
      "name": "string",
      "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "primary_code": "string",
      "primary_standard_code": "en10027-1",
      "primary_standard_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "successor_grade_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "updated_at": "2026-06-01T12:00:00Z",
      "urn": "string"
    },
    "matched_via": "urn",
    "standard_used": "en10027-1"
  }
}