---
title: Uploading files
description: Two ways to get CAD and drawings into ARCNM — one-shot upload-and-quote, or a presigned direct upload you can reuse across calculations.
---

# Uploading files

Every quote starts from a file. ARCNM accepts 3D CAD (STEP/STP, IGES,
STL), 2D drawings (PDF, DXF, PNG/JPEG), and supporting documents, up to
**512 MB** each. There are two ways in.

---

## One-shot: upload and quote

The fastest path — hand the bytes and the costing inputs to
`POST /api/v1/parts/calculations/upload-and-quote` in a single multipart
call, and ARCNM stores the file, creates the part + revision, and
enqueues the calculation. This is the [quickstart](./quickstart.md) path;
use it whenever you're costing a file once.

---

## Reusable: presigned direct upload

When you want to attach a file to several calculations, push large files
straight to storage, or separate ingest from costing, use the
**presign → PUT → confirm** flow on the `/uploads` resource
(`uploads:write`):

```bash
# 1. Ask for a presigned URL.
curl -X POST https://api.arcnm.io/api/v1/uploads/presign \
  -H "X-API-Key: $ARCNM_API_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "bracket.step", "content_type": "application/step", "size_bytes": 184320 }'
# → { "data_source_id": "ds_…", "url": "https://…", "method": "PUT",
#     "headers": { … }, "expires_in": 900 }

# 2. PUT the bytes straight to storage — the payload never touches the API.
curl -X PUT "<url from step 1>" \
  -H "Content-Type: application/step" --data-binary @bracket.step

# 3. Confirm — ARCNM validates the magic bytes and marks the source ready.
curl -X POST https://api.arcnm.io/api/v1/uploads/confirm \
  -H "X-API-Key: $ARCNM_API_KEY" -H "Content-Type: application/json" \
  -d '{ "data_source_id": "ds_…" }'
```

The `data_source_id` is durable: attach it to a revision
(`POST /api/v1/parts/{part_id}/revisions/{revision_id}/datasets`) and
quote that revision as many times as you like.

> **Why presign?** The file bytes go directly to object storage, not
> through the API, so a 512 MB STEP never touches the request path —
> faster uploads, and no JSON body-size ceiling to fight.

---

## Allowed types

| Kind | Content types |
|---|---|
| 3D CAD | `application/step`, `model/step+xml`, `application/iges`, `model/stl`; native CAD (IPT, SLDPRT, X_T) as `application/octet-stream` |
| 2D drawings | `application/pdf`, `image/vnd.dxf`, `image/png`, `image/jpeg` |
| Documents | `application/pdf`, `text/csv`, `text/plain`, Office formats |

`content_type` is required at presign and validated again by magic-byte
sniffing on confirm. Executable / scriptable types (HTML, JavaScript,
SVG) are rejected outright.

---

## Manage uploads

| Operation | Endpoint |
|---|---|
| List your uploads | `GET /api/v1/uploads` |
| Get a download URL | `GET /api/v1/uploads/{id}/download-url` |
| Retry a failed ingest | `POST /api/v1/uploads/{id}/retry` |
| Cancel a pending upload | `POST /api/v1/uploads/{id}/cancel` |
| Bulk retry / cancel | `POST /api/v1/uploads/bulk-retry`, `.../bulk-cancel` |

---

## See also

- [Quickstart](./quickstart.md) — upload-and-quote in five minutes.
- [API → Uploads](./api/uploads.md) — presign, confirm, and the lifecycle routes.
- [API → Parts](./api/parts.md) — attach a data source to a part revision.
