API reference
Import
The Import API bulk-loads your machine fleet and cutting-tool library from a file, with a preview call that validates every row before anything is written.
The Import API bulk-loads your machine fleet and cutting-tool library from a file, with a preview call that validates every row before anything is written.
Auto-generated from the public OpenAPI spec — this page never drifts from the running API. Base URL
https://api.arcnm.io. Authenticate with theX-API-Keyheader (see Authentication).
Import Machines
POST /api/v1/import/machines
Import your machine park from CSV. Machines are created with their class's standard capabilities (your envelope / spindle columns override them) at the rate you state, and attached to the target environment. Re-uploading the same file is safe: existing machines are recognised by name and never duplicated.
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
csv |
string | yes | The machine list as CSV text (headered; comma, semicolon or tab separated). Columns: name, class, hourly_rate_eur — plus optional operator_eur_per_h, envelope_x_mm / envelope_y_mm / envelope_z_mm, spindle_power_kw and priority. Header spellings are matched tolerantly; at most 500 data rows. |
env_id |
string | no | Costing environment the machines join; omit for your default environment. |
Request
curl -X POST https://api.arcnm.io/api/v1/import/machines \
-H "X-API-Key: $ARCNM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csv": "string"
}'
import requests
resp = requests.post(
"https://api.arcnm.io/api/v1/import/machines",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"csv": "string"
},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/import/machines", {
method: "POST",
headers: {
"X-API-Key": process.env.ARCNM_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
"csv": "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 |
|---|---|---|
applied |
boolean | False for a preview (nothing written); true for a commit. |
attached |
integer | Rows that attach (or would attach) an existing item. |
created |
integer | Rows that create (or would create) a new item. |
env_id |
string | The costing environment the import targets; null in a preview when your organization has no default environment yet. |
errored |
integer | Rows with errors; nothing happens for them. |
rows |
ImportRowPublic[] | Per-row detail, in file order. |
skipped |
integer | Rows skipped as already present. |
total_rows |
integer | Data rows read from the file. |
Example response
{
"applied": true,
"attached": 0,
"created": 0,
"env_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errored": 0,
"rows": [
{
"action": "create+attach",
"errors": [
"string"
],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"parsed": {},
"row": 0
}
],
"skipped": 0,
"total_rows": 0
}
Preview Machine Import
POST /api/v1/import/machines/preview
Preview a machine-park import: per row, the values as read, any errors, and what the import would do — create the machine and attach it, attach a machine you already have under that name, or skip one already in the environment. Nothing is written.
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
csv |
string | yes | The machine list as CSV text (headered; comma, semicolon or tab separated). Columns: name, class, hourly_rate_eur — plus optional operator_eur_per_h, envelope_x_mm / envelope_y_mm / envelope_z_mm, spindle_power_kw and priority. Header spellings are matched tolerantly; at most 500 data rows. |
env_id |
string | no | Costing environment the machines join; omit for your default environment. |
Request
curl -X POST https://api.arcnm.io/api/v1/import/machines/preview \
-H "X-API-Key: $ARCNM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csv": "string"
}'
import requests
resp = requests.post(
"https://api.arcnm.io/api/v1/import/machines/preview",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"csv": "string"
},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/import/machines/preview", {
method: "POST",
headers: {
"X-API-Key": process.env.ARCNM_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
"csv": "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 |
|---|---|---|
applied |
boolean | False for a preview (nothing written); true for a commit. |
attached |
integer | Rows that attach (or would attach) an existing item. |
created |
integer | Rows that create (or would create) a new item. |
env_id |
string | The costing environment the import targets; null in a preview when your organization has no default environment yet. |
errored |
integer | Rows with errors; nothing happens for them. |
rows |
ImportRowPublic[] | Per-row detail, in file order. |
skipped |
integer | Rows skipped as already present. |
total_rows |
integer | Data rows read from the file. |
Example response
{
"applied": true,
"attached": 0,
"created": 0,
"env_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errored": 0,
"rows": [
{
"action": "create+attach",
"errors": [
"string"
],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"parsed": {},
"row": 0
}
],
"skipped": 0,
"total_rows": 0
}
Import Tools
POST /api/v1/import/tools
Import your tool crib from CSV. Tools are created with their kind-specific properties validated (a saw blade needs its kerf and construction; rotating cutters need nothing extra) and attached to your default environment. Re-uploading the same file is safe: existing tools are recognised by name and kind, never duplicated.
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
csv |
string | yes | The tool list as CSV text (headered). Columns: name, kind — plus optional diameter_mm, teeth, cutting_material, price_eur, tool_life_min, vendor, item_no, coating, notes, and any kind-specific property as its own column (e.g. kerf_mm, blade_type and format for a saw blade, life_quantity for non-rotating tools). At most 1000 data rows. |
Request
curl -X POST https://api.arcnm.io/api/v1/import/tools \
-H "X-API-Key: $ARCNM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csv": "string"
}'
import requests
resp = requests.post(
"https://api.arcnm.io/api/v1/import/tools",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"csv": "string"
},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/import/tools", {
method: "POST",
headers: {
"X-API-Key": process.env.ARCNM_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
"csv": "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 |
|---|---|---|
applied |
boolean | False for a preview (nothing written); true for a commit. |
attached |
integer | Rows that attach (or would attach) an existing item. |
created |
integer | Rows that create (or would create) a new item. |
env_id |
string | The costing environment the import targets; null in a preview when your organization has no default environment yet. |
errored |
integer | Rows with errors; nothing happens for them. |
rows |
ImportRowPublic[] | Per-row detail, in file order. |
skipped |
integer | Rows skipped as already present. |
total_rows |
integer | Data rows read from the file. |
Example response
{
"applied": true,
"attached": 0,
"created": 0,
"env_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errored": 0,
"rows": [
{
"action": "create+attach",
"errors": [
"string"
],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"parsed": {},
"row": 0
}
],
"skipped": 0,
"total_rows": 0
}
Preview Tool Import
POST /api/v1/import/tools/preview
Preview a tool-crib import: per row, the values as read (including the kind-specific properties), any errors, and what the import would do. Nothing is written.
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
csv |
string | yes | The tool list as CSV text (headered). Columns: name, kind — plus optional diameter_mm, teeth, cutting_material, price_eur, tool_life_min, vendor, item_no, coating, notes, and any kind-specific property as its own column (e.g. kerf_mm, blade_type and format for a saw blade, life_quantity for non-rotating tools). At most 1000 data rows. |
Request
curl -X POST https://api.arcnm.io/api/v1/import/tools/preview \
-H "X-API-Key: $ARCNM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csv": "string"
}'
import requests
resp = requests.post(
"https://api.arcnm.io/api/v1/import/tools/preview",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"csv": "string"
},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.arcnm.io/api/v1/import/tools/preview", {
method: "POST",
headers: {
"X-API-Key": process.env.ARCNM_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
"csv": "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 |
|---|---|---|
applied |
boolean | False for a preview (nothing written); true for a commit. |
attached |
integer | Rows that attach (or would attach) an existing item. |
created |
integer | Rows that create (or would create) a new item. |
env_id |
string | The costing environment the import targets; null in a preview when your organization has no default environment yet. |
errored |
integer | Rows with errors; nothing happens for them. |
rows |
ImportRowPublic[] | Per-row detail, in file order. |
skipped |
integer | Rows skipped as already present. |
total_rows |
integer | Data rows read from the file. |
Example response
{
"applied": true,
"attached": 0,
"created": 0,
"env_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errored": 0,
"rows": [
{
"action": "create+attach",
"errors": [
"string"
],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"parsed": {},
"row": 0
}
],
"skipped": 0,
"total_rows": 0
}