Assets API

CRUD operations, search, checkout/checkin, QR codes, and CSV import/export for assets. All endpoints are tenant-scoped via the Host header.

Base URL depends on the tenant

All asset endpoints below should be called against the tenant's subdomain — e.g. https://acme.atechsolutions.org/api/assets. Calling against the root domain returns a scope error for non-MSP users.

List assets

http
GET /api/assets Authorization: Bearer {token} # Query parameters (all optional): # q - search term (asset tag, name, serial, model, manufacturer) # status - filter: available | deployed | maintenance | retired # category_id - filter by category ID # location_id - filter by location ID # sort - column to sort by (default: asset_tag) # order - asc | desc (default: asc) # tenant - MSP only: slug to scope to a specific tenant from root domain
json
[ {{ "id": 42, "asset_tag": "IT-0042", "name": "MacBook Pro 16", "manufacturer": "Apple", "model": "M3 Max", "serial": "C02XL123456", "status": "deployed", "category": {{"id": 1, "name": "Laptop"}}, "location": {{"id": 2, "name": "Head Office"}}, "assigned_to": {{"id": 7, "name": "Sarah Chen"}}, "purchase_date": "2024-01-15", "purchase_cost": "3499.00", "warranty_expiry": "2027-03-01", "notes": "" }} ]

Get asset

http
GET /api/assets/{id} Authorization: Bearer {token}

Create asset

http
POST /api/assets Authorization: Bearer {token} Content-Type: application/json {{ "asset_tag": "IT-0043", "name": "Dell Latitude 7440", "manufacturer": "Dell", "model": "7440", "serial": "5CG0XY9876", "status": "available", "category_id": 1, "location_id": 2, "purchase_date": "2024-03-01", "purchase_cost": 1450, "warranty_expiry": "2027-06-12", "notes": "" }}

Returns the created asset object. In SaaS mode, returns 402 if the asset limit is reached.

Update asset

http
PUT /api/assets/{id} Authorization: Bearer {token} Content-Type: application/json # Same body as create — all fields must be provided

Delete asset

http
DELETE /api/assets/{id} Authorization: Bearer {token} # Returns: 200 OK on success # Note: also deletes all checkout history for this asset

Check out

http
POST /api/assets/{id}/checkout Authorization: Bearer {token} Content-Type: application/json {{ "employee_id": 7, "note": "Assigned for new hire onboarding" }} # Returns the updated asset # Fails with 400 if asset is not in "available" status

Check in

http
POST /api/assets/{id}/checkin Authorization: Bearer {token} Content-Type: application/json {{ "note": "Returned in good condition" }} # Returns the updated asset # Fails with 400 if asset is not in "deployed" status

Checkout history

http
GET /api/assets/{id}/history Authorization: Bearer {token} # Returns: [ {{ "action": "checkout", "employee_name": "Sarah Chen", "performed_by": "MSP Admin", "note": "Assigned for new hire onboarding", "timestamp": "2024-01-15T09:30:00Z" }}, {{ "action": "checkin", "employee_name": "Sarah Chen", "performed_by": "MSP Admin", "note": "Returned in good condition", "timestamp": "2024-06-01T17:15:00Z" }} ]

QR code

http
GET /api/assets/{id}/qr # No authentication required # Returns: image/png (200x200px)

Export CSV

http
GET /api/assets/export/csv Authorization: Bearer {token} # Optional filters same as list endpoint # Returns: text/csv attachment

Import CSV

http
POST /api/assets/import/csv Authorization: Bearer {token} Content-Type: multipart/form-data # Form field: file = (CSV file bytes) # Returns: {{ "created": 8, "updated": 2, "errors": [ {{"row": 4, "error": "Invalid status 'in use'"}} ] }}
Last updated: May 2026