CAD Blocks API
Read a project's CAD units and the CAD tag catalog, and manage the library of AutoCAD blocks and which block each product and category uses.
A CAD block is an AutoCAD block saved as a DWG file. Your company keeps one library of blocks; each product can name its own block for each view, and each device category a default. This page is the contract an AutoCAD plugin works from: one read gives it every unit of a project with the values to fill into its block and the block to place. For how blocks work in the app, see Device Tags.
Writing a plugin of your own? The AutoCAD Plugin guide shows what AVstackr's plugin does with this contract and the CAD Drawings API, step by step from the drafter's side.
Signing In from a Desktop Plugin
Every endpoint here takes the same Authorization: Bearer header as the rest of the API. A desktop plugin can get its token in either of two ways, and both work today:
- An API key: the user creates one under Settings → API Keys and pastes it into the plugin once. It starts with
avs_ and does not expire; see Authentication.
- OAuth: the authorization code flow with PKCE (
S256) and a loopback redirect such as http://127.0.0.1:53682/callback. Register the client with POST /oauth/register; the endpoints are listed at /.well-known/oauth-authorization-server. An access token lasts 1 hour, and a refresh token lasts 30 days, with each refresh returning a new one.
Either token carries the user's role: a Read-only user can make every read on this page, and each write answers 403 READ_ONLY_ACCESS.
Where the Other CAD Endpoints Are
| Task | Endpoint | Documented in |
| Set a product's own block per view | PUT /api/v1/products/{id}/cad-blocks | Products API |
| Set a category's default block per view | PUT /api/v1/cad-categories (cadBlocks on each item) | Device Tags API |
| Create a project's missing units and tag them | POST /api/v1/projects/{projectId}/device-tags/assign | Projects API |
| Map an attribute key to a CAD tag and choose how it syncs | PUT /api/v1/line-item-attribute-keys/{id} | Line Item Attributes API |
| Link a drawing, list its placements, and sync it with the project | /api/v1/projects/{projectId}/cad/drawings | CAD Drawings API |
Views and Block Rules
- A view is written
plan, ceiling, elevation or schematic, in any case: a floor plan, a reflected ceiling plan, a wall or rack elevation, and a line or schematic sheet. A number is not accepted as a view.
- For each view, a unit uses its product's own block, else its category's default, else
generic. A generic block has no file: draw a box from the unit's dimensions. An archived block counts as no block.
name, the display name, is 1 to 100 characters and unique among your live blocks, ignoring letter case.
blockName, the AutoCAD block definition name, is trimmed, then 1 to 255 characters with none of < > / \ " : ; ? * | , = ` and no control character. It is unique among all your blocks, archived ones included, ignoring letter case.
- The file is a DWG of 1 byte to 5 MB (5,242,880 bytes) that starts with
AC10 and two digits, as every DWG from AutoCAD R13 on does. A DXF or any other content is refused with INVALID_FILE, whatever the file is called. An upload request over 6,000,000 bytes in all is refused before it reaches AVstackr's checks, with a 400 that is not in the usual error format.
attributeTags are stored as sent apart from trimming and upper-casing, in order, duplicates dropped; characters such as - and . are kept. A tag over 255 characters or with a control character is refused with INVALID_TAG. A tag is supported when it is a built-in tag or exactly an active attribute key's CAD tag (both listed by GET /api/v1/cad/tags), and unmapped otherwise.
visibilityStates are a dynamic block's state names, trimmed, in order, duplicates and blanks dropped, at most 255 characters each; empty for a block that is not dynamic.
insertionUnits is the block's AutoCAD INSUNITS code: 0 unitless, 1 inches, 2 feet, 4 millimeters, 5 centimeters or 6 meters. It is stored and returned as sent.
- Blocks are archived, never deleted. An archived block keeps its file, block name and assignments, and can still be read, downloaded and replaced.
GET /api/v1/projects/{projectId}/cad/units
Returns every unit of the project's active version, across its rooms that are not archived, with what a plugin needs to place and fill a block for one view. Read-only: it never creates a unit or assigns a tag. When linesWithoutUnits is above zero, call POST /api/v1/projects/{projectId}/device-tags/assign and read again.
Path Parameters
| Field | Type | Required | Description |
projectId | integer | Yes | The project ID |
Query Parameters
| Field | Type | Required | Description |
view | string | Yes | plan, ceiling, elevation or schematic. Blocks are resolved for this view. |
roomId | integer | No | One room of the active version. Only its units are returned; rooms still lists every room. |
includeNonDrawable | boolean | No | Default false, which leaves out units whose category is not drawable, such as cable and labor. Units with no category are always included. |
Example Request
GET /api/v1/projects/12/cad/units?view=plan
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": {
"projectId": 12,
"projectName": "Northwind HQ",
"versionId": 3,
"versionName": "V2",
"view": "plan",
"generatedAt": "2026-10-12T15:04:05Z",
"rooms": [
{ "roomId": 7, "roomKey": "0b6f3c2e-5a1d-4c3b-9e2f-7d8a1b4c6e90", "name": "Conference Room A", "abbreviation": "CON" }
],
"units": [
{
"instanceId": 501,
"instanceKey": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
"deviceTag": "DISP-003",
"unitNumber": 3,
"room": { "roomId": 7, "name": "Conference Room A" },
"line": { "productProjectRoomId": 88, "quantity": 3, "order": 2 },
"product": { "productId": 41, "make": "Samsung", "model": "QM85C", "part": "LH85QMCEBGCXZA", "description": "85-inch 4K display", "imageUrl": null },
"category": { "id": 2, "name": "Display", "abbreviation": "DISP", "isDrawable": true, "expectedOn": ["plan", "elevation"] },
"system": { "id": 1, "name": "Audio Visual", "abbreviation": "AV" },
"dimensions": {
"shape": "rectangular",
"widthIn": 75.2,
"depthIn": 2.1,
"heightIn": 43,
"diameterIn": null,
"rackMountable": false,
"rackUnits": null,
"weightLbs": 95,
"isEstimated": false
},
"attributes": {
"AVSTACKR_ID": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
"DEVICETAG": "DISP-003",
"MANUFACTURER": "Samsung",
"MODEL": "QM85C",
"PARTNUMBER": "LH85QMCEBGCXZA",
"DESCRIPTION": "85-inch 4K display",
"CATEGORY": "Display",
"LOCATION": "Conference Room A",
"SYSTEM": "Audio Visual",
"UNIT": "3",
"QTY": "3",
"HEIGHT": "43",
"WIDTH": "75.2",
"DEPTH": "2.1",
"WEIGHT": "95",
"PROJECT": "Northwind HQ",
"SERIAL_NUMBER": "SN-4471"
},
"block": {
"source": "product",
"id": 9,
"name": "Display wall",
"blockName": "AVS_DISP_WALL",
"fileSha256": "0851e2bd40f2303d1b0ebbda0027df40f7bdb02d6065d629ec8785594221da0b",
"attributeTags": ["AVSTACKR_ID", "DEVICETAG", "MANUFACTURER", "MODEL", "SERIAL_NUMBER"],
"insertionUnits": 1,
"visibilityState": "TOP"
},
"rackPlacement": null,
"fingerprint": "ec5e72b17d52f207ec87aaaaf1c27d84998755b6295427db8294070a16ec2ba7",
"placements": [
{ "drawingId": 4, "drawingName": "L1-AV", "view": "plan", "placementId": 17, "handle": "2F3A", "lastPushedFingerprint": "ec5e72b17d52f207ec87aaaaf1c27d84998755b6295427db8294070a16ec2ba7" }
]
}
],
"linesWithoutUnits": 2,
"unitsSkipped": { "nonDrawable": 14, "otherRooms": 0 }
},
"message": null,
"timestamp": "2026-10-12T15:04:05Z"
}
A unit with no product or category block has "block": { "source": "generic", "id": null, "name": null, "blockName": null, "fileSha256": null, "attributeTags": [], "insertionUnits": null, "visibilityState": null }. A racked unit has "rackPlacement": { "rackId": 3, "rackName": "Rack A", "startRu": 12, "ruSpan": 2 }.
Unit Fields
| Field | Type | Description |
instanceId | integer | The unit's ID |
instanceKey | string (UUID) | The unit's permanent identity, the same in every version. AVSTACKR_ID carries it in the same form. |
deviceTag | string or null | The unit's device tag; null while it has none |
unitNumber | integer | The unit's number among the room's units of the same make and model |
room, line, product | object | The room the unit is in, the equipment line that owns it, and the line's make, model, part and description as the line shows them |
category, system | object or null | The product's device category and the line's system; null when the product is unclassified or the line unassigned |
dimensions | object | In inches and pounds, the same for every view. shape is rectangular or circular; for a circular product widthIn and depthIn are its diameter. isEstimated is true when the product has no usable size, and widthIn and depthIn are then a 24-inch placeholder. |
attributes | object | The block attribute values, keyed by upper-case CAD tag. See below. |
block | object | The block resolved for view, always present. source is product, category or generic; attributeTags and insertionUnits repeat the block's, so no second call is needed. visibilityState is the state to set after inserting a dynamic block, null for its default state. |
rackPlacement | object or null | Where the unit sits in one of the project's racks: rackId, rackName, startRu (the lowest rack unit, from the bottom; null on a shelf) and ruSpan. null when it is in no rack. |
fingerprint | string | A SHA-256 of the unit's attributes, its block's ID and its block's file hash. It changes when an attribute value changes, the unit resolves to another block, or that block's file is replaced, so a plugin can compare it with the one it last wrote. A change of visibility state alone leaves it as it was. |
placements | array of object | The blocks that draw the unit on the project's linked drawings, one per drawing, of every view, in drawing order; empty when no drawing places it. Each has drawingId, drawingName, view, placementId, the block's handle in that drawing and lastPushedFingerprint, the unit's fingerprint for that view when the placement was recorded. A unit whose fingerprint for that view now differs has changed since; a submit of the drawing gives the exact values to rewrite. See the CAD Drawings API. |
linesWithoutUnits counts the lines in the response's rooms whose units have not all been created yet. unitsSkipped.nonDrawable counts the units of the requested rooms left out because their category is not drawable, and unitsSkipped.otherRooms the units left out by roomId.
Attributes
- The built-in tags are filled from the unit and its line:
AVSTACKR_ID is instanceKey; CATEGORY, LOCATION and SYSTEM are names, not abbreviations (the abbreviations are in the device tag); UNIT is the unit number and QTY the line's quantity. RACKUNITS is sent only for a rack-mountable product.
HEIGHT, WIDTH, DEPTH and WEIGHT are plain decimals in inches and pounds, such as 75.2, and are left out when isEstimated is true.
- Each active attribute key with a CAD tag adds that tag, filled from the unit's own entry, else the line's. That includes a key that syncs
pull, so a new block starts with the project's value.
- A tag with no value is left out, never sent empty.
Error Responses
| Status | Code | Description |
| 400 | INVALID_INPUT | view is missing or is not a view name |
| 404 | PROJECT_NOT_FOUND | The project is not one of yours |
| 404 | ROOM_NOT_FOUND | roomId is not a room of the project's active version, or the room is archived |
GET /api/v1/cad/tags
Returns the CAD tag catalog: the built-in tags, filled from each unit's own details, and your attribute keys that carry a CAD tag, active and deactivated. A block's attribute tag is supported when it is one of the built-in tags or the tag of an active key.
Example Request
GET /api/v1/cad/tags
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": {
"canonical": [
{ "tag": "AVSTACKR_ID", "source": "canonical", "description": "The unit's permanent AVstackr ID, which links the block back to the unit", "hidden": true },
{ "tag": "DEVICETAG", "source": "canonical", "description": "The unit's device tag, such as DISP-003", "hidden": false }
],
"tenant": [
{ "tag": "SERIAL_NUMBER", "source": "tenant", "keyId": 14, "keyName": "Serial Number", "isActive": true }
]
},
"message": null,
"timestamp": "2026-10-12T15:04:05Z"
}
canonical lists every built-in tag in the order below; hidden: true marks AVSTACKR_ID, which a block should define as an invisible attribute. tenant lists the keys with a CAD tag in key order; only active ones are filled.
| Tag | Filled with |
AVSTACKR_ID | The unit's permanent AVstackr ID, which links the block back to the unit |
DEVICETAG | The unit's device tag, such as DISP-003 |
MANUFACTURER | The manufacturer on the equipment line |
MODEL | The model on the equipment line |
PARTNUMBER | The part number on the equipment line |
DESCRIPTION | The description on the equipment line |
CATEGORY | The product's device category name, such as Display |
LOCATION | The room the unit is in |
SYSTEM | The equipment line's system name, such as Audio Visual |
UNIT | The unit's number among the room's units of the same make and model |
QTY | The quantity on the equipment line |
RACKUNITS | The rack units the device takes up, for rack-mountable devices |
HEIGHT | The device's height in inches |
WIDTH | The device's width in inches |
DEPTH | The device's depth in inches |
WEIGHT | The device's weight in pounds |
PROJECT | The project name |
GET /api/v1/cad/blocks
Returns the block library ordered by name, each block with its views, visibility states, tags and usage.
Query Parameters
| Field | Type | Required | Description |
view | string | No | plan, ceiling, elevation or schematic: only the blocks that list that view |
includeArchived | boolean | No | Default false. true adds archived blocks. |
Example Request
GET /api/v1/cad/blocks?view=plan
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": [
{
"id": 9,
"name": "Display wall",
"blockName": "AVS_DISP_WALL",
"viewTypes": ["plan", "elevation"],
"visibilityStates": ["FRONT", "TOP"],
"attributeTags": ["AVSTACKR_ID", "DEVICETAG", "MANUFACTURER", "MODEL", "SERIAL-NO"],
"supportedTags": ["AVSTACKR_ID", "DEVICETAG", "MANUFACTURER", "MODEL"],
"unmappedTags": ["SERIAL-NO"],
"insertionUnits": 1,
"fileName": "AVS_DISP_WALL.dwg",
"fileSizeBytes": 184320,
"fileSha256": "0851e2bd40f2303d1b0ebbda0027df40f7bdb02d6065d629ec8785594221da0b",
"fileUpdatedAt": "2026-10-12T14:20:00Z",
"description": "Flat panel on a wall mount",
"isArchived": false,
"createdAt": "2026-10-12T14:20:00Z",
"updatedAt": "2026-10-12T14:20:00Z",
"createdBy": "8d3e5c1a-2f4b-4e6d-9a7c-1b2d3e4f5a6b",
"usage": [
{ "view": "plan", "products": 4, "categories": 1 },
{ "view": "elevation", "products": 2, "categories": 0 }
]
}
],
"message": null,
"timestamp": "2026-10-12T15:04:05Z"
}
Block Fields
| Field | Type | Description |
id | integer | The block's ID |
name | string | The display name |
blockName | string | The AutoCAD block definition name to insert |
viewTypes | array of string | The views the block suits, in view order |
visibilityStates | array of string | A dynamic block's visibility states; empty otherwise |
attributeTags | array of string | Every attribute tag the block defines, in its order |
supportedTags | array of string | The tags AVstackr fills: built-in tags and active attribute keys' CAD tags |
unmappedTags | array of string | The tags nothing fills |
insertionUnits | integer | The block's INSUNITS code |
fileName | string | The name of the file last uploaded |
fileSizeBytes | integer | The file's size |
fileSha256 | string | The file's SHA-256 in lower-case hex; it changes on every replace. A plugin holding a file with this hash can skip the download. |
fileUpdatedAt | string (ISO 8601) | When the file was uploaded or last replaced |
description | string or null | Up to 500 characters |
isArchived | boolean | true once archived |
createdAt | string (ISO 8601) | When the block was first uploaded |
updatedAt | string (ISO 8601) | When the block last changed |
createdBy | string or null | The user ID of the person who uploaded the block |
usage | array of object | For each view the block lists or is used on: view, products (products using it as their own block) and categories (categories using it as their default). A product using the block on two views counts on both, so the counts do not add up to a number of products. |
Error Responses
| Status | Code | Description |
| 400 | INVALID_INPUT | view is not a view name |
GET /api/v1/cad/blocks/{id}
Returns one block, archived or not, with the fields above.
Path Parameters
| Field | Type | Required | Description |
id | integer | Yes | The block ID |
Example Request
GET /api/v1/cad/blocks/9
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": { "id": 9, "name": "Display wall", "blockName": "AVS_DISP_WALL", ... },
"message": null,
"timestamp": "2026-10-12T15:04:05Z"
}
Error Responses
| Status | Code | Description |
| 404 | BLOCK_NOT_FOUND | The block is not one of yours |
GET /api/v1/cad/blocks/{id}/file
Returns a link to download the block's DWG, valid for 15 minutes. The link points at file storage, not at the API, and needs no token.
Path Parameters
| Field | Type | Required | Description |
id | integer | Yes | The block ID |
Example Request
GET /api/v1/cad/blocks/9/file
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": {
"url": "https://…",
"expiresAt": "2026-10-12T15:19:05Z",
"fileName": "AVS_DISP_WALL.dwg",
"fileSha256": "0851e2bd40f2303d1b0ebbda0027df40f7bdb02d6065d629ec8785594221da0b"
},
"message": null,
"timestamp": "2026-10-12T15:04:05Z"
}
Error Responses
| Status | Code | Description |
| 404 | BLOCK_NOT_FOUND | The block is not one of yours |
POST /api/v1/cad/blocks
Uploads a new block as multipart/form-data with two parts: the DWG and its details as JSON. The signed-in user is recorded as the uploader.
Form Parts
| Field | Type | Required | Description |
file | file | Yes | The DWG, at most 5 MB. Its file name is stored for display. |
metadata | string (JSON) | Yes | The block's details, an object with the fields below |
Metadata Fields
| Field | Type | Required | Description |
name | string | Yes | The display name |
blockName | string | Yes | The AutoCAD block definition name in the file |
viewTypes | array of string | Yes | The views the block suits, at least one |
visibilityStates | array of string | No | A dynamic block's visibility states, in its order |
attributeTags | array of string | No | The attribute tags the block defines, in its order |
insertionUnits | integer | Yes | The block's INSUNITS code |
description | string | No | Up to 500 characters |
Any other metadata field is refused with 400 UNKNOWN_FIELDS. The rules for each field are under Views and Block Rules above.
Example Request
curl -X POST https://avstackr.com/api/v1/cad/blocks \
-H "Authorization: Bearer avs_YOUR_API_KEY" \
-F "file=@AVS_DISP_WALL.dwg" \
-F 'metadata={"name":"Display wall","blockName":"AVS_DISP_WALL","viewTypes":["plan","elevation"],"visibilityStates":["FRONT","TOP"],"attributeTags":["AVSTACKR_ID","DEVICETAG","MANUFACTURER","MODEL","SERIAL-NO"],"insertionUnits":1,"description":"Flat panel on a wall mount"}'
Response (201 - Created)
{
"success": true,
"data": { "id": 9, "name": "Display wall", "blockName": "AVS_DISP_WALL", ... },
"message": "Block 'Display wall' created",
"timestamp": "2026-10-12T14:20:00Z"
}
data is the new block with the fields of GET /api/v1/cad/blocks, and the Location header points at GET /api/v1/cad/blocks/{id}.
Error Responses
| Status | Code | Description |
| 400 | INVALID_INPUT | The file or metadata part is missing, metadata is not a JSON object, a view name is unknown, insertionUnits is missing or not a listed code, or a name, block name, view list, visibility state or description breaks its rule |
| 400 | UNKNOWN_FIELDS | metadata names a field not listed above |
| 400 | INVALID_FILE | The file is empty, over 5 MB, not as long as sent, or not a DWG |
| 400 | INVALID_TAG | An attribute tag is over 255 characters or has a control character |
| 403 | READ_ONLY_ACCESS | The caller has read-only access |
| 409 | NAME_IN_USE | A live block already has the name |
| 409 | BLOCK_NAME_IN_USE | A block, archived or not, already has the block name. To update that block, replace its file. |
PUT /api/v1/cad/blocks/{id}/file
Replaces the block's DWG in place, as multipart/form-data. The name, block name and views stay; products and categories keep using the block, and drawings that already hold it are not changed. An assignment whose visibility state the new file no longer has goes back to the block's default state and is listed in resetAssignments. An archived block can be replaced too.
Path Parameters
| Field | Type | Required | Description |
id | integer | Yes | The block ID |
Form Parts
| Field | Type | Required | Description |
file | file | Yes | The new DWG, at most 5 MB |
metadata | string (JSON) | No | What the new file holds, an object with the fields below |
Metadata Fields
| Field | Type | Required | Description |
visibilityStates | array of string | No | The new file's visibility states |
attributeTags | array of string | No | The new file's attribute tags |
insertionUnits | integer | No | The new file's INSUNITS code |
A field left out keeps the block's current value; an empty array clears it. Any other field is refused with 400 UNKNOWN_FIELDS.
Example Request
curl -X PUT https://avstackr.com/api/v1/cad/blocks/9/file \
-H "Authorization: Bearer avs_YOUR_API_KEY" \
-F "file=@AVS_DISP_WALL.dwg" \
-F 'metadata={"visibilityStates":["FRONT"],"attributeTags":["AVSTACKR_ID","DEVICETAG","MANUFACTURER","MODEL","SERIAL_NUMBER"]}'
Response (200 - Success)
{
"success": true,
"data": {
"id": 9,
"name": "Display wall",
"visibilityStates": ["FRONT"],
"fileSha256": "fe6541d23549a9733784f5dbd30092534f77715e31d199cad9e0f79be652e9d9",
...,
"resetAssignments": [
{ "assignmentId": 31, "view": "plan", "productId": 123, "categoryId": null, "previousState": "TOP" }
]
},
"message": "Block file replaced; 1 assignment(s) reset to the block's default visibility state",
"timestamp": "2026-10-12T16:02:00Z"
}
data is the block with the fields of GET /api/v1/cad/blocks, plus resetAssignments: each assignment the replace reset, with assignmentId, view, the productId or categoryId that owns it, and its previousState. When none was reset, the list is empty and the message is Block file replaced.
Error Responses
| Status | Code | Description |
| 400 | INVALID_INPUT | The file part is missing, metadata is not a JSON object, or insertionUnits or a visibility state breaks its rule |
| 400 | UNKNOWN_FIELDS | metadata names a field not listed above |
| 400 | INVALID_FILE | The file is empty, over 5 MB, not as long as sent, or not a DWG |
| 400 | INVALID_TAG | An attribute tag is over 255 characters or has a control character |
| 403 | READ_ONLY_ACCESS | The caller has read-only access |
| 404 | BLOCK_NOT_FOUND | The block is not one of yours |
PUT /api/v1/cad/blocks/{id}
Renames a block or changes its description or views. A field left out keeps its value; send at least one.
Path Parameters
| Field | Type | Required | Description |
id | integer | Yes | The block ID |
Request Body
| Field | Type | Required | Description |
name | string | No | The new display name |
description | string | No | The new description; an empty string clears it |
viewTypes | array of string | No | The views the block suits, replacing the current list; at least one. A view that products or categories use the block for cannot be removed. |
Example Request
{
"name": "Display, wall mount",
"viewTypes": ["plan", "ceiling", "elevation"]
}
Response (200 - Success)
{
"success": true,
"data": { "id": 9, "name": "Display, wall mount", "viewTypes": ["plan", "ceiling", "elevation"], ... },
"message": "Block updated",
"timestamp": "2026-10-12T16:10:00Z"
}
Error Responses
| Status | Code | Description |
| 400 | INVALID_INPUT | The body is missing or names none of the three fields, a view name is unknown, or a field breaks its rule |
| 400 | UNKNOWN_FIELDS | The body names a field not listed above |
| 403 | READ_ONLY_ACCESS | The caller has read-only access |
| 404 | BLOCK_NOT_FOUND | The block is not one of yours |
| 409 | NAME_IN_USE | Another live block has the name |
| 409 | VIEW_IN_USE | viewTypes drops a view that products or categories use the block for; the message counts them per view |
POST /api/v1/cad/blocks/{id}/archive
Archives a block. It leaves the lists and pickers and is no longer resolved, so products and categories that use it fall back to the next step; its file, block name and assignments stay. Archiving an archived block changes nothing.
Path Parameters
| Field | Type | Required | Description |
id | integer | Yes | The block ID |
Example Request
POST /api/v1/cad/blocks/9/archive
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": { "id": 9, "name": "Display wall", "isArchived": true, ... },
"message": "Block archived",
"timestamp": "2026-10-12T16:20:00Z"
}
Error Responses
| Status | Code | Description |
| 403 | READ_ONLY_ACCESS | The caller has read-only access |
| 404 | BLOCK_NOT_FOUND | The block is not one of yours |
POST /api/v1/cad/blocks/{id}/unarchive
Brings an archived block back into use. Unarchiving a live block changes nothing.
Path Parameters
| Field | Type | Required | Description |
id | integer | Yes | The block ID |
Example Request
POST /api/v1/cad/blocks/9/unarchive
Authorization: Bearer avs_YOUR_API_KEY
Response (200 - Success)
{
"success": true,
"data": { "id": 9, "name": "Display wall", "isArchived": false, ... },
"message": "Block unarchived",
"timestamp": "2026-10-12T16:25:00Z"
}
Error Responses
| Status | Code | Description |
| 403 | READ_ONLY_ACCESS | The caller has read-only access |
| 404 | BLOCK_NOT_FOUND | The block is not one of yours |
| 409 | NAME_IN_USE | A live block now has the block's name |
Block Error Codes
The block library's own codes, here and on the product and category endpoints:
| Code | Status | Meaning |
INVALID_INPUT | 400 | A field or part breaks its rule; the message names it |
INVALID_FILE | 400 | The file is empty, over 5 MB, not as long as sent, or not a DWG |
INVALID_TAG | 400 | An attribute tag is over 255 characters or has a control character |
VIEW_MISMATCH | 400 | An assignment uses a view the block does not list |
INVALID_VISIBILITY_STATE | 400 | An assignment names a visibility state the block does not have |
BLOCK_ARCHIVED | 400 | A new or changed assignment names an archived block |
BLOCK_NOT_FOUND | 404 | No block of yours has the ID |
NAME_IN_USE | 409 | A live block already has the display name |
BLOCK_NAME_IN_USE | 409 | A block, archived or not, already has the block name |
VIEW_IN_USE | 409 | An update removes a view that assignments still use |
MCP clients read the units with get_cad_units, list the library with list_cad_blocks and set a product's block with set_product_cad_block; see the MCP Server page. Blocks cannot be uploaded through MCP.