ARCNM

API reference

Parts & revisions

The Parts API manages parts and their revisions.

The Parts API manages parts and their revisions: create, list, fetch, update, and delete parts, and manage each part's revision history.

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 Parts

GET /api/v1/parts/

Paginated. Pass limit and offset to page through results.

Parameters

Name In Type Required Description
q query string no Substring match
classification_id query string no Identifier of the classification.
limit query integer no Maximum number of results to return.
offset query integer no Number of results to skip before the returned page.

Request

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

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/", {
  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 parts matching the query.
data PartPublic[] The page of parts matching the query.

Example response

{
  "count": 0,
  "data": [
    {
      "attributes": {},
      "base_uom": "EA",
      "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "created_at": "2026-06-01T12:00:00Z",
      "default_currency": "EUR",
      "description": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "lead_time_days": 0,
      "make_or_buy": "make",
      "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "part_number": "BRACKET-001",
      "procurement_type": "in_house",
      "updated_at": "2026-06-01T12:00:00Z"
    }
  ]
}

Create Part

POST /api/v1/parts/

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata for the part.
base_uom string no Base unit of measure for the part (ISO unit code, e.g. EA, KG, M).
classification_id string no ID of the classification category this part belongs to, if any.
default_currency string no Default currency for the part's pricing (ISO 4217 code, e.g. EUR, USD).
description string no Human-readable description of the part.
lead_time_days integer no Expected lead time to obtain the part, in days.
make_or_buy string no Whether the part is manufactured in-house or purchased.
part_number string yes Stable identifier (≈ SAP MATNR). Unique per org.
procurement_type string no How the part is sourced (e.g. in-house production or external supplier).

Request

curl -X POST https://api.arcnm.io/api/v1/parts/ \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "part_number": "BRACKET-001"
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "part_number": "BRACKET-001"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "part_number": "BRACKET-001"
  }),
})
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 for the part.
base_uom string Base unit of measure for the part (ISO unit code, e.g. EA, KG, M).
classification_id string ID of the classification category this part belongs to, if any.
created_at string Timestamp when the part was created (UTC, ISO 8601).
default_currency string Default currency for the part's pricing (ISO 4217 code, e.g. EUR, USD).
description string Human-readable description of the part.
id string Unique identifier of the part.
lead_time_days integer Expected lead time to obtain the part, in days.
make_or_buy string Whether the part is manufactured in-house or purchased.
org_id string ID of the organization that owns the part.
part_number string Stable identifier (≈ SAP MATNR). Unique per org.
procurement_type string How the part is sourced (e.g. in-house production or external supplier).
updated_at string Timestamp when the part was last updated (UTC, ISO 8601).

Example response

{
  "attributes": {},
  "base_uom": "EA",
  "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-06-01T12:00:00Z",
  "default_currency": "EUR",
  "description": "string",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lead_time_days": 0,
  "make_or_buy": "make",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "part_number": "BRACKET-001",
  "procurement_type": "in_house",
  "updated_at": "2026-06-01T12:00:00Z"
}

Delete Part

DELETE /api/v1/parts/{part_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.

Request

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

resp = requests.delete(
    "https://api.arcnm.io/api/v1/parts/{part_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/parts/{part_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 Part

GET /api/v1/parts/{part_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.

Request

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

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/{part_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/parts/{part_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
attributes object Free-form key/value metadata for the part.
base_uom string Base unit of measure for the part (ISO unit code, e.g. EA, KG, M).
classification_id string ID of the classification category this part belongs to, if any.
created_at string Timestamp when the part was created (UTC, ISO 8601).
default_currency string Default currency for the part's pricing (ISO 4217 code, e.g. EUR, USD).
description string Human-readable description of the part.
id string Unique identifier of the part.
lead_time_days integer Expected lead time to obtain the part, in days.
make_or_buy string Whether the part is manufactured in-house or purchased.
org_id string ID of the organization that owns the part.
part_number string Stable identifier (≈ SAP MATNR). Unique per org.
procurement_type string How the part is sourced (e.g. in-house production or external supplier).
updated_at string Timestamp when the part was last updated (UTC, ISO 8601).

Example response

{
  "attributes": {},
  "base_uom": "EA",
  "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-06-01T12:00:00Z",
  "default_currency": "EUR",
  "description": "string",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lead_time_days": 0,
  "make_or_buy": "make",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "part_number": "BRACKET-001",
  "procurement_type": "in_house",
  "updated_at": "2026-06-01T12:00:00Z"
}

Update Part

PATCH /api/v1/parts/{part_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata for the part.
base_uom string no Base unit of measure for the part (ISO unit code, e.g. EA, KG, M).
classification_id string no ID of the classification category this part belongs to, if any.
default_currency string no Default currency for the part's pricing (ISO 4217 code, e.g. EUR, USD).
description string no Human-readable description of the part.
lead_time_days integer no Expected lead time to obtain the part, in days.
make_or_buy string no Whether the part is manufactured in-house or purchased.
procurement_type string no How the part is sourced (e.g. in-house production or external supplier).

Request

curl -X PATCH https://api.arcnm.io/api/v1/parts/{part_id} \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "attributes": {},
    "base_uom": "EA",
    "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "default_currency": "string",
    "description": "string",
    "lead_time_days": 0,
    "make_or_buy": "string",
    "procurement_type": "string"
  }'
import requests

resp = requests.patch(
    "https://api.arcnm.io/api/v1/parts/{part_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "attributes": {},
        "base_uom": "EA",
        "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "default_currency": "string",
        "description": "string",
        "lead_time_days": 0,
        "make_or_buy": "string",
        "procurement_type": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}", {
  method: "PATCH",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "attributes": {},
    "base_uom": "EA",
    "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "default_currency": "string",
    "description": "string",
    "lead_time_days": 0,
    "make_or_buy": "string",
    "procurement_type": "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 for the part.
base_uom string Base unit of measure for the part (ISO unit code, e.g. EA, KG, M).
classification_id string ID of the classification category this part belongs to, if any.
created_at string Timestamp when the part was created (UTC, ISO 8601).
default_currency string Default currency for the part's pricing (ISO 4217 code, e.g. EUR, USD).
description string Human-readable description of the part.
id string Unique identifier of the part.
lead_time_days integer Expected lead time to obtain the part, in days.
make_or_buy string Whether the part is manufactured in-house or purchased.
org_id string ID of the organization that owns the part.
part_number string Stable identifier (≈ SAP MATNR). Unique per org.
procurement_type string How the part is sourced (e.g. in-house production or external supplier).
updated_at string Timestamp when the part was last updated (UTC, ISO 8601).

Example response

{
  "attributes": {},
  "base_uom": "EA",
  "classification_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-06-01T12:00:00Z",
  "default_currency": "EUR",
  "description": "string",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lead_time_days": 0,
  "make_or_buy": "make",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "part_number": "BRACKET-001",
  "procurement_type": "in_house",
  "updated_at": "2026-06-01T12:00:00Z"
}

Part Preview Url

GET /api/v1/parts/{part_id}/preview-url

Engine-agnostic GLB preview for a Part.

Resolves the part's most-recent revision's primary CAD dataset and hands back a presigned URL for its glTF/GLB. The frontend uses this on the parts overview and part detail pages so the 3D model is surfaced before any calculation has run.

Returns {url, status} (status semantics match /parts/datasets/{ds_id}/preview-url). The frontend treats the same payload identically across all surfaces — that is the "globally unified" 3D preview contract.

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.

Request

curl -X GET https://api.arcnm.io/api/v1/parts/{part_id}/preview-url \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/{part_id}/preview-url",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/preview-url", {
  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
data_source_id string Identifier of the resolved CAD file; null when no dataset was found.
status string Preview readiness state (e.g. ok, pending, failed, no_dataset).
url string Presigned URL to the GLB preview; null unless status is 'ok'.

Example response

{
  "data_source_id": "string",
  "status": "string",
  "url": "string"
}

List Revisions

GET /api/v1/parts/{part_id}/revisions

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.

Request

curl -X GET https://api.arcnm.io/api/v1/parts/{part_id}/revisions \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions", {
  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
count integer Total number of revisions matching the query.
data PartRevisionPublic[] The page of revisions matching the query.

Example response

{
  "count": 0,
  "data": [
    {
      "attributes": {},
      "created_at": "2026-06-01T12:00:00Z",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "parent_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "part_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "revision_code": "string",
      "updated_at": "2026-06-01T12:00:00Z"
    }
  ]
}

Create Revision

POST /api/v1/parts/{part_id}/revisions

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.

Request body (application/json)

Field Type Required Description
attributes object no Free-form key/value metadata for the revision.
change_request_id string no ID of the change request that triggered this revision, if any.
parent_revision_id string no ID of the revision this one was derived from, recording its lineage.
revision_code string yes Customer-facing revision label (A, B, 01, 02, …).

Request

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

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "revision_code": "string"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "revision_code": "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.
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 201

Field Type Description
attributes object Free-form key/value metadata for the revision.
created_at string Timestamp when the revision was created (UTC, ISO 8601).
id string Unique identifier of the revision.
parent_revision_id string ID of the revision this one was derived from, recording its lineage.
part_id string ID of the part this revision belongs to.
revision_code string Customer-facing revision label (A, B, 01, 02, …).
updated_at string Timestamp when the revision was last updated (UTC, ISO 8601).

Example response

{
  "attributes": {},
  "created_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "parent_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "part_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "revision_code": "string",
  "updated_at": "2026-06-01T12:00:00Z"
}

Delete Revision

DELETE /api/v1/parts/{part_id}/revisions/{revision_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.

Request

curl -X DELETE https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.delete(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_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/parts/{part_id}/revisions/{revision_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 Revision

GET /api/v1/parts/{part_id}/revisions/{revision_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.

Request

curl -X GET https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_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/parts/{part_id}/revisions/{revision_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
attributes object Free-form key/value metadata for the revision.
created_at string Timestamp when the revision was created (UTC, ISO 8601).
id string Unique identifier of the revision.
parent_revision_id string ID of the revision this one was derived from, recording its lineage.
part_id string ID of the part this revision belongs to.
revision_code string Customer-facing revision label (A, B, 01, 02, …).
updated_at string Timestamp when the revision was last updated (UTC, ISO 8601).

Example response

{
  "attributes": {},
  "created_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "parent_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "part_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "revision_code": "string",
  "updated_at": "2026-06-01T12:00:00Z"
}

Update Revision

PATCH /api/v1/parts/{part_id}/revisions/{revision_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.

Request body (application/json)

Field Type Required Description
attributes object no Free-form metadata to merge onto the revision, as a JSON object.

Request

curl -X PATCH https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id} \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "attributes": {}
  }'
import requests

resp = requests.patch(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "attributes": {}
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}", {
  method: "PATCH",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "attributes": {}
  }),
})
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 for the revision.
created_at string Timestamp when the revision was created (UTC, ISO 8601).
id string Unique identifier of the revision.
parent_revision_id string ID of the revision this one was derived from, recording its lineage.
part_id string ID of the part this revision belongs to.
revision_code string Customer-facing revision label (A, B, 01, 02, …).
updated_at string Timestamp when the revision was last updated (UTC, ISO 8601).

Example response

{
  "attributes": {},
  "created_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "parent_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "part_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "revision_code": "string",
  "updated_at": "2026-06-01T12:00:00Z"
}

List Datasets

GET /api/v1/parts/{part_id}/revisions/{revision_id}/datasets

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.

Request

curl -X GET https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets", {
  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.

Attach Dataset

POST /api/v1/parts/{part_id}/revisions/{revision_id}/datasets

Attach an existing DataSource row to a revision.

For a fresh file upload, prefer POST .../datasets/upload which creates the DataSource + link in one shot.

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.

Request body (application/json)

Field Type Required Description
attributes object no Free-form metadata for the attachment, as a JSON object.
data_source_id string yes Identifier of the uploaded data source to attach to the revision.
is_primary boolean no Whether this dataset is the primary one for the revision.
role string no Role of the file on the revision (e.g. cad_3d for a 3D CAD model, drawing_2d for a 2D drawing).

Request

curl -X POST https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data_source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  }'
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "data_source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "data_source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  }),
})
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.
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 201

Field Type Description
attributes object Free-form key/value metadata for the file attachment.
content_type string MIME type of the uploaded file (e.g. application/pdf).
created_at string Timestamp when the file was attached (UTC, ISO 8601).
data_source_id string ID of the underlying stored file this attachment points to.
filename string Original filename of the uploaded file.
id string Unique identifier of the uploaded file attached to the revision.
is_active boolean Whether this is the current file; superseded re-uploads are marked inactive.
is_primary boolean Whether this is the primary CAD file used for analysis on the revision.
part_revision_id string ID of the revision this file is attached to.
role string The file's role on the revision (e.g. 3D CAD, 2D drawing, spec).
size_bytes integer Size of the uploaded file in bytes.

Example response

{
  "attributes": {},
  "content_type": "string",
  "created_at": "2026-06-01T12:00:00Z",
  "data_source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "filename": "bracket.step",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "is_primary": true,
  "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "role": "primary",
  "size_bytes": 204800
}

Detach Dataset

DELETE /api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_id}

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.
dataset_link_id path string yes Identifier of the dataset link.

Request

curl -X DELETE https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
import requests

resp = requests.delete(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_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/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_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 dataset was detached.

Example response

{
  "message": "string"
}

Update Dataset

PATCH /api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_id}

Edit a dataset link.

Currently supports two fields:

  • filename: rename the underlying DataSource.
  • is_primary: promote/demote within the parent revision. The "exactly one primary" invariant is maintained server-side: when promoting, every other link on the same revision is demoted in the same transaction so concurrent primaries can't co-exist.

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.
dataset_link_id path string yes Identifier of the dataset link.

Request body (application/json)

Field Type Required Description
filename string no New original filename for the uploaded file.
is_primary boolean no Set true to make this the primary CAD file for analysis on the revision.

Request

curl -X PATCH https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_id} \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "bracket.step",
    "is_primary": true
  }'
import requests

resp = requests.patch(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "filename": "bracket.step",
        "is_primary": True
    },
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/{dataset_link_id}", {
  method: "PATCH",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "filename": "bracket.step",
    "is_primary": true
  }),
})
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 for the file attachment.
content_type string MIME type of the uploaded file (e.g. application/pdf).
created_at string Timestamp when the file was attached (UTC, ISO 8601).
data_source_id string ID of the underlying stored file this attachment points to.
filename string Original filename of the uploaded file.
id string Unique identifier of the uploaded file attached to the revision.
is_active boolean Whether this is the current file; superseded re-uploads are marked inactive.
is_primary boolean Whether this is the primary CAD file used for analysis on the revision.
part_revision_id string ID of the revision this file is attached to.
role string The file's role on the revision (e.g. 3D CAD, 2D drawing, spec).
size_bytes integer Size of the uploaded file in bytes.

Example response

{
  "attributes": {},
  "content_type": "string",
  "created_at": "2026-06-01T12:00:00Z",
  "data_source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "filename": "bracket.step",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "is_primary": true,
  "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "role": "primary",
  "size_bytes": 204800
}

Upload Dataset

POST /api/v1/parts/{part_id}/revisions/{revision_id}/datasets/upload

Upload a file directly onto a revision, in one shot.

Stores the file and links it to the revision. No calculation is enqueued — use /parts/calculations/upload for the calculate-on-upload flow.

Parameters

Name In Type Required Description
part_id path string yes Identifier of the part.
revision_id path string yes Identifier of the revision.
role query string no Role of the file on the revision (e.g. cad_3d for a 3D model, drawing_2d for a 2D drawing).
is_primary query boolean no Whether this dataset becomes the primary one for its role on the revision.

Request body (multipart/form-data)

Field Type Required Description
file string yes The CAD model or drawing file to attach to the revision.

Request

curl -X POST https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/upload \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -F "[email protected]"
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/upload",
    headers={"X-API-Key": "YOUR_API_KEY"},
    files={
        "file": open("file.bin", "rb"),
    },
)
resp.raise_for_status()
print(resp.json())
const form = new FormData()
form.append("file", file) // a File or Blob

const resp = await fetch("https://api.arcnm.io/api/v1/parts/{part_id}/revisions/{revision_id}/datasets/upload", {
  method: "POST",
  headers: { "X-API-Key": process.env.ARCNM_API_KEY! },
  body: form,
})
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.
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 201

Field Type Description
attributes object Free-form key/value metadata for the file attachment.
content_type string MIME type of the uploaded file (e.g. application/pdf).
created_at string Timestamp when the file was attached (UTC, ISO 8601).
data_source_id string ID of the underlying stored file this attachment points to.
filename string Original filename of the uploaded file.
id string Unique identifier of the uploaded file attached to the revision.
is_active boolean Whether this is the current file; superseded re-uploads are marked inactive.
is_primary boolean Whether this is the primary CAD file used for analysis on the revision.
part_revision_id string ID of the revision this file is attached to.
role string The file's role on the revision (e.g. 3D CAD, 2D drawing, spec).
size_bytes integer Size of the uploaded file in bytes.

Example response

{
  "attributes": {},
  "content_type": "string",
  "created_at": "2026-06-01T12:00:00Z",
  "data_source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "filename": "bracket.step",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_active": true,
  "is_primary": true,
  "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "role": "primary",
  "size_bytes": 204800
}