Uploading files

Attaching a file to a part is a three-step flow:

  1. Request a signed upload URL from Fieldnode.
  2. Upload the bytes directly to that URL.
  3. Attach the upload to the part under a file group.

The bytes go straight to blob storage, never through this API. It only mints the URL in step 1 and records the attachment in step 3.

Before you start

Step 1 — Request a signed upload URL

POST /v1/uploads with the file name. Set public: true only for something that should be served without authentication, such as a preview image.

curl https://api.fieldnode.app/v1/uploads \
  -X POST \
  -H "Authorization: Bearer $FIELDNODE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "name": "drawing.pdf", "public": false }'
{
  "id": "01J8...",
  "method": "PUT",
  "signedUrl": "https://...blob.core.windows.net/...?sig=...",
  "expireTime": "2026-06-09T12:34:56Z",
  "headers": { "x-ms-blob-type": "BlockBlob" }
}

Keep the id — that is the upload id step 3 needs. The signedUrl is single-use and expires at expireTime.

Step 2 — Upload the bytes

Send the file to signedUrl using the method and headers from the response. Do not add your token: the signed URL carries its own credential, and attaching a bearer token to a request that already authenticates itself only risks leaking it to another host.

curl --upload-file ./drawing.pdf \
  -X PUT \
  -H 'x-ms-blob-type: BlockBlob' \
  -H 'Content-Type: application/pdf' \
  'https://...blob.core.windows.net/...?sig=...'

A successful upload returns 201 or 200 with an empty body. If the URL has expired, start again from step 1 — a signed URL cannot be renewed.

Step 3 — Attach the upload to the part

PATCH /v1/parts/{id}/files with the upload id and the group to file it under:

curl https://api.fieldnode.app/v1/parts/{partId}/files \
  -X PATCH \
  -H "Authorization: Bearer $FIELDNODE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "add": [ { "group": "document", "uploadId": "01J8..." } ] }'

A successful response is 204 No Content.

File groups

Group Use for
preview Thumbnail or preview image shown in part listings
document General attachments — drawings, datasheets, PDFs
ip IP-restricted files, visible only to the part's owner
partDevelopment Development files attached during part design, owner-only
development Additional development assets

ip and partDevelopment are withheld from everyone but the part's owning organization, on both GET /v1/parts/{id}/files and the get_part MCP tool. Putting a file in either group is how you keep it out of a published part's public attachments.

Verifying

curl https://api.fieldnode.app/v1/parts/{partId}/files \
  -H "Authorization: Bearer $FIELDNODE_TOKEN"

Each item carries id, name, group, url, and — for non-public files — short-lived signedUrl and signedDownloadUrl you can fetch the bytes back with.

Removing files

The same endpoint removes them. Pass file ids, not upload ids:

curl https://api.fieldnode.app/v1/parts/{partId}/files \
  -X PATCH \
  -H "Authorization: Bearer $FIELDNODE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "remove": ["01J9..."] }'

add and remove may be combined in one request.