Scoutmon REST API
The Scoutmon API lets you read and manage your IT assets, users, vendors, and locations programmatically. All endpoints are scoped to your company — you can only access data that belongs to your account.
All requests and responses use JSON. Timestamps are ISO 8601 in UTC. UUIDs are used for all resource identifiers.
Authentication
The API uses Bearer token authentication via API keys. Generate an API key from your Settings → API Keys page.
Pass your key in the Authorization header on every request:
# Replace sk_... with your actual API key curl https://scoutmon.com/api/assets \ -H "Authorization: Bearer sk_your_api_key_here"
API Key format
Keys follow the format sk_ followed by 56 hex characters. The first 10 characters form the key prefix used for rate limiting.
Scopes
Each API key has one or more scopes. Request the minimum scope needed for your integration.
| Scope | Description |
|---|---|
| read | Read-only access to all resources in your company |
| write | Create, update, and delete resources (includes read) |
What API keys can't do
Keys are for working with your asset data. Anything that changes who can get into your account needs a person signed in to Scoutmon, so these return 403 with "code": "api_key_not_allowed" even for a write key:
- inviting, changing or removing users, and changing permissions
- creating or revoking API keys
- creating, changing or deleting webhooks (listing them is fine)
- changing company settings
Expiry
When you create a key you choose when it expires: 30, 90, 180 or 365 days, or never. An expired key, or a key whose creator has been deactivated, returns 401.
Rate Limits
Rate limits are applied per API key. If you exceed a limit, requests return 429 Too Many Requests.
After the limit resets, requests proceed normally. For bulk operations, use the limit and offset query parameters to page through results rather than fetching everything repeatedly.
Errors
The API returns standard HTTP status codes. Error responses include a JSON body with an error field describing what went wrong.
| Status | Meaning |
|---|---|
| 200 | Success |
| 201 | Resource created |
| 400 | Bad request — check request body / query params |
| 401 | Unauthorized — missing or invalid API key |
| 402 | Subscription lapsed — the account is read-only. GET requests still work; writes return "code": "subscription_required" |
| 403 | Forbidden — insufficient scope, a read-only key, or an action API keys can't perform |
| 404 | Resource not found, or no such endpoint (always JSON) |
| 409 | Conflict — e.g. duplicate email |
| 429 | Rate limit exceeded |
| 500 | Server error |
{
"error": "Asset not found"
}
Pagination & Filtering
All list endpoints support limit and offset for pagination, plus endpoint-specific filter parameters. The total count of matching records is returned in the X-Total-Count response header.
Common query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | integer | 500 | Records per page. Max 1000. |
| offset | integer | 0 | Number of records to skip. |
| search | string | — | Text search across name and other key fields (endpoint-specific). |
Example — paginate through assets
# Page 1 curl "https://scoutmon.com/api/assets?limit=50&offset=0" \ -H "Authorization: Bearer sk_..." # Page 2 curl "https://scoutmon.com/api/assets?limit=50&offset=50" \ -H "Authorization: Bearer sk_..."
The X-Total-Count header tells you how many records match the current filter, so you can compute the number of pages as Math.ceil(total / limit).
Assets
Returns a list of assets for your company, including joined location, vendor, owner, and classification names.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| search | string | Filter by name, asset tag, or serial number (case-insensitive). |
| status | string | Filter by status: active, checked-out, checked-in, retired, etc. |
| category | string | Filter by category (exact match). E.g. Laptop, SaaS. |
| location_id | uuid | Filter by location. |
| owner_id | uuid | Filter by owner (user). |
| assigned_user_id | uuid | Filter by the user an asset is checked out to. |
| classification_id | uuid | Filter by data classification. |
| sort_by | string | name | created_at | status | category | value | asset_tag. Default: created_at. |
| sort_dir | string | asc or desc. Default: desc. |
| limit | integer | Default 500, max 1000. |
| offset | integer | Default 0. |
curl "https://scoutmon.com/api/assets?status=checked-out&sort_by=name&sort_dir=asc&limit=25" \ -H "Authorization: Bearer sk_..."
[
{
"id": "a1b2c3d4-...",
"asset_tag": "IT-0042",
"name": "MacBook Pro 16\"",
"category": "Laptop",
"status": "checked-out",
"value": "2499.00",
"location_name": "Sydney HQ",
"vendor_name": "Apple Inc.",
"assigned_user_name": "Alice Smith",
"created_at": "2025-11-01T09:00:00.000Z"
}
]
The response header X-Total-Count contains the total number of matching assets (before pagination).
Returns a single asset by ID. Use GET /api/assets/:id/decrypt (admin-only) to retrieve encrypted serial/notes fields.
curl https://scoutmon.com/api/assets/a1b2c3d4-... \
-H "Authorization: Bearer sk_..."
Finds a single asset by its asset tag or serial number: the lookup you want when scanning a label. Returns the same shape as GET /api/assets/:id, or 404 if nothing in your company matches.
curl https://scoutmon.com/api/assets/by-tag/SM-0042 \
-H "Authorization: Bearer sk_..."
Photos aren't included in single-asset or list responses; has_photo tells you whether one exists.
Creates a new asset. If asset_tag is omitted and auto-increment is configured, a tag is generated automatically.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Display name for the asset. |
| category | string | optional | Asset category (e.g. Laptop, Monitor, SaaS). |
| status | string | optional | Default: active. |
| asset_tag | string | optional | Custom tag. Auto-generated if omitted. |
| serial_number | string | optional | Device serial number. |
| value | number | optional | Purchase price (numeric). |
| purchase_date | date | optional | ISO 8601 date string (YYYY-MM-DD). |
| warranty_expiry | date | optional | ISO 8601 date string (YYYY-MM-DD). |
| location_id | uuid | optional | Location UUID. |
| vendor_id | uuid | optional | Vendor UUID. |
| assigned_user_id | uuid | optional | User UUID to assign immediately. |
| manufacturer | string | optional | e.g. Apple, Dell. |
| model | string | optional | Device model. |
| notes | string | optional | Free-text notes. |
curl -X POST https://scoutmon.com/api/assets \ -H "Authorization: Bearer sk_..." \ -H "Content-Type: application/json" \ -d '{ "name": "MacBook Pro 16\"", "category": "Laptop", "manufacturer": "Apple", "model": "MacBook Pro 16\" M3", "value": 2499, "purchase_date": "2025-10-15", "warranty_expiry": "2028-10-15" }'
Replaces all fields on an asset. Send all fields (including unchanged ones) — this is a full update, not a partial patch. Accepts the same body parameters as POST /api/assets.
Permanently deletes an asset. This action cannot be undone.
{ "ok": true }
Checks an asset out to a user. Sets status to checked-out and records the assignment.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
| assigned_user_id | uuid | required | UUID of the user to check out to. |
| expected_return | date | optional | Expected return date (YYYY-MM-DD). |
Checks an asset back in. Sets status to checked-in and clears the assigned user.
Users
Returns all users in your company. Includes role, status, department, and last login timestamp.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| search | string | Filter by name or email (case-insensitive). |
| role | string | user or admin. |
| status | string | active or inactive. |
| limit | integer | Default 500, max 1000. |
| offset | integer | Default 0. |
curl "https://scoutmon.com/api/users?role=admin" \ -H "Authorization: Bearer sk_..."
[
{
"id": "u1b2c3d4-...",
"name": "Alice Smith",
"email": "[email protected]",
"role": "admin",
"status": "active",
"department": "Engineering",
"last_login": "2026-03-28T14:22:00.000Z",
"created_at": "2025-09-01T08:00:00.000Z"
}
]
Returns all hardware assets and license seats currently assigned to a specific user.
{
"assets": [ /* hardware assets assigned to this user */ ],
"seats": [ /* software license seats assigned to this user */ ]
}
Vendors
Returns all vendors for your company with risk rating, compliance status, and contact details.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| search | string | Filter by vendor name. |
| category | string | Filter by category (e.g. ICT / Cloud & Hosting). |
| risk_rating | string | Low, Medium, or High. |
| limit | integer | Default 500, max 1000. |
| offset | integer | Default 0. |
Creates a new vendor record.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Vendor name. |
| category | string | optional | Vendor category. |
| website | string | optional | Vendor website URL. |
| risk_rating | string | optional | Low, Medium, or High. |
| compliance_status | string | optional | Compliant, Non-Compliant, or Not Reviewed. |
| primary_contact_name | string | optional | |
| primary_contact_email | string | optional | |
| notes | string | optional | Free-text notes. |
Full update of a vendor record. Accepts the same fields as POST /api/vendors.
Returns all active assets associated with a vendor.
Locations
Returns all locations for your company.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| search | string | Filter by location name. |
| type | string | Filter by type (e.g. Office, Warehouse, Remote). |
| limit | integer | Default 500, max 1000. |
| offset | integer | Default 0. |
[
{
"id": "loc1b2c3-...",
"name": "Sydney HQ",
"type": "Office",
"address": "123 Pitt St, Sydney NSW 2000",
"lat": -33.8688,
"lng": 151.2093
}
]
Creates a new location.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Location name. |
| type | string | optional | Default: Office. |
| address | string | optional | Street address. |
| lat | number | optional | Latitude (decimal degrees). |
| lng | number | optional | Longitude (decimal degrees). |
Webhooks
Webhooks send an HTTPS POST to your endpoint when something happens. Set them up in Settings → Webhooks (a signed-in admin is needed; API keys can list them but not change them).
Events
| Event | When |
|---|---|
| asset.created | An asset is added |
| asset.updated | An asset is changed |
| asset.checked_out | An asset is checked out to someone |
| asset.checked_in | An asset is checked back in |
| warranty.expiring | Daily: assets whose warranty ends in the next 30 days |
| licence.expiring | Daily: licences and SaaS reaching end of life in the next 30 days |
| audit.due | Daily: assets due a physical audit in the next 7 days, or already overdue |
{
"event": "asset.checked_out",
"delivered_at": "2026-10-05T03:12:44.120Z",
"data": { … }
}
Verifying the signature
Each request carries X-Scoutmon-Event and X-Scoutmon-Signature: sha256=<hex>, an HMAC-SHA256 of the raw request body using your webhook's secret (shown once, when you create it). Compute the same HMAC over the exact bytes you received and compare in constant time.
// Node.js
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-scoutmon-signature']));
Delivery
Endpoints must be public https:// addresses; private and internal addresses are refused, and redirects aren't followed. Each event is attempted once, with an 8-second timeout. The last response status is shown against the webhook in Settings, and Send test sends a signed ping. There are no automatic retries yet, so use the daily events or the API to reconcile if your endpoint was down.
Search
Global search across assets, users, and vendors. Returns up to 5 results per category.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| q | string | required | Search query. Minimum 2 characters. |
curl "https://scoutmon.com/api/search?q=macbook" \ -H "Authorization: Bearer sk_..."
{
"assets": [
{ "id": "...", "name": "MacBook Pro 16\"", "asset_tag": "IT-0042", "category": "Laptop", "status": "checked-out" }
],
"users": [],
"vendors": []
}