v4 REST API
The v4 REST API is plain HTTPS over JSON. Every route lives under https://ai.growrk.com/v4 and is authenticated with a user-bound API key.
Authentication
Send your key (prefix grk_sk_) in the X-API-KEY header on every request:
curl https://ai.growrk.com/v4/me \
-H "X-API-KEY: grk_sk_your_key_here"
A missing or invalid key returns 401 Unauthorized. See Authentication & API keys to mint one and choose its capabilities.
Postman collection
Rather than building requests by hand, import the ready-made collection:
Download the GroWrk v4 Client API collection (Postman Collection v2.1.0, 27 requests across 8 folders).
In Postman, choose File → Import and drop the file in. No Postman account or workspace access is needed.
It arrives already wired up:
- Authentication is set at the collection level to the
X-API-KEYheader, reading a collection variable. Paste yourgrk_sk_key into theapiKeyvariable once and every request inherits it. baseUrlis a variable too (https://ai.growrk.com), so you can point the whole collection at another environment by editing one value.- Each request documents the capability it needs, so a
403tells you which scope to add to your key.
The collection is generated from the same route table and tool schemas that back the API itself, so it cannot drift out of sync with the endpoints documented below.
Resources
| Resource | Endpoints |
|---|---|
| Orders | GET /v4/orders · GET /v4/orders/{id} · POST /v4/orders · POST /v4/orders/purchase · GET /v4/orders/{id}/history · GET /v4/orders/{id}/tracking · GET /v4/orders/{id}/sla · POST /v4/orders/validate · POST /v4/orders/{id}/accessories |
| Employees | GET /v4/employees · GET /v4/employees/{id} · POST /v4/employees · PATCH /v4/employees/{id} · GET /v4/employees/{id}/devices · GET /v4/employees/countries |
| Teams | GET /v4/teams · GET /v4/teams/{id} · POST /v4/teams · PATCH /v4/teams/{id} |
| Inventory / devices | GET /v4/inventory · GET /v4/devices/options · GET /v4/devices/suggestions |
| Products | GET /v4/products/{id} · POST /v4/products/pin-code |
| Company | GET /v4/company/addresses · POST /v4/company/addresses |
| Identity | GET /v4/me |
Each write endpoint requires the matching capability on your key (mcp:orders:write, mcp:employees:write); read endpoints require the matching read capability. GET /v4/me needs no scope.
Two endpoints do not follow the obvious mapping:
POST /v4/orders/validateis aPOSTbut is read-only: it requiresmcp:orders:read, not:write.GET /v4/employees/{id}/devicessits under Employees but requiresmcp:inventory:read, notmcp:employees:read.
Lists: pagination & filtering
GET /v4/orders and GET /v4/employees accept these query parameters:
| Parameter | Applies to | Description |
|---|---|---|
query | orders, employees | Free-text search |
email | employees | Exact email match (case-insensitive). An equality filter, not a search. Use it to resolve one known employee |
status | orders, employees | Filter by status (orders accept multiple status values) |
type | orders | Filter by order type (multiple allowed) |
country | employees | Filter by country (ISO 3166-1 alpha-2, e.g. US, BR) |
page | orders, employees | Page number, 0-indexed, default 0 |
limit | orders, employees | Page size, default 20, maximum 50 |
sort | orders, employees | Field to sort by |
sortDirection | orders, employees | asc or desc (default: desc for orders, asc for employees) |
There is no "return everything" mode. limit is capped at 50, so page through large result sets with page.
GET /v4/inventory filters with query, category, country, status, inStock, and limit (default 20, max 50). GET /v4/devices/options caps limit at 25 (default 10) and GET /v4/devices/suggestions at 15 (default 5). Repeat a parameter to pass multiple values, e.g. ?status=shipped&status=delivered.
Response format
On success the API returns the operation's result as a JSON object. Read operations return the resource payload; most results carry a status: "success" field alongside the data. For example, GET /v4/me:
{
"authenticated": true,
"user": {
"uid": "usr_1a2b3c",
"email": "jane@example.com",
"displayName": "Jane Doe"
},
"access": {
"isStaff": false,
"isDeveloper": true,
"companyIds": ["co_acme"],
"supplierIds": []
}
}
And a list, GET /v4/orders:
{
"status": "success",
"orders": [
{ "id": "ord_123", "status": "shipped", "type": "Deployment" }
]
}
The
growrkCLI (and other GroWrk clients) wrap this result in a unified envelope,{ ok, data, meta }, so scripts can branch onokand read a correlation id frommeta. The raw REST response is the innerdata; see CLI output formats.
Error codes
Failures return the matching HTTP status with a JSON body containing statusCode and statusMessage:
{ "statusCode": 404, "statusMessage": "Order ord_123 not found" }
| Status | Meaning |
|---|---|
400 Bad Request | Invalid input: a missing or malformed field |
401 Unauthorized | Missing X-API-KEY header, or a key that is invalid, inactive, expired, unauthorized, or bound to a user who has been disabled or deleted. A legacy GW. v2 key also lands here |
403 Forbidden | Your key lacks the required capability, or the record is outside your scope |
404 Not Found | The requested resource does not exist (or is not visible to you) |
409 Conflict | The request conflicts with existing state (e.g. a duplicate employee email) |
500 Internal Server Error | An unexpected failure. The body is always the generic "Request failed"; the underlying error is deliberately not returned, only logged server-side. Report the endpoint and the time of the request |
Examples
All examples below are copy-pasteable. Replace grk_sk_your_key_here and the sample ids with your own.
Identity
curl https://ai.growrk.com/v4/me \
-H "X-API-KEY: grk_sk_your_key_here"
Orders
# List the 10 most recent shipped orders
curl "https://ai.growrk.com/v4/orders?status=shipped&limit=10" \
-H "X-API-KEY: grk_sk_your_key_here"
# Get one order
curl https://ai.growrk.com/v4/orders/ord_123 \
-H "X-API-KEY: grk_sk_your_key_here"
# Order history, tracking, and SLA
curl https://ai.growrk.com/v4/orders/ord_123/history -H "X-API-KEY: grk_sk_your_key_here"
curl https://ai.growrk.com/v4/orders/ord_123/tracking -H "X-API-KEY: grk_sk_your_key_here"
curl https://ai.growrk.com/v4/orders/ord_123/sla -H "X-API-KEY: grk_sk_your_key_here"
# Pre-flight validation (read-only) before placing an order
curl -X POST https://ai.growrk.com/v4/orders/validate \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"orderType":"Deployment","employeeId":"emp_123","productIds":["prod_456"]}'
# Place a deployment order (requires mcp:orders:write)
curl -X POST https://ai.growrk.com/v4/orders \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"orderType":"Deployment","employeeId":"emp_123","productIds":["prod_456"]}'
# Request a replacement charger for a device on an existing order.
# `productId` identifies the DEVICE that needs the charger, not a charger SKU.
# Only devices whose charger status is "Damaged" or "Not Included" are eligible.
curl -X POST https://ai.growrk.com/v4/orders/ord_123/accessories \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"productId":"prod_456"}'
# The device can also be identified by serial number instead of productId
curl -X POST https://ai.growrk.com/v4/orders/ord_123/accessories \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"serialNumber":"C02XY1234ABC"}'
# Purchase from the GroWrk catalog (requires mcp:orders:write).
# `itemId` is a catalog item id, NOT a legacy v2 companyItem id, and each
# item carries the country it ships from, because quotes are per region.
# Use "Purchase for Inventory" to stock the company pool instead of an employee.
curl -X POST https://ai.growrk.com/v4/orders/purchase \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"orderType": "Purchase for Employee",
"employeeId": "emp_123",
"items": [{ "itemId": "item_789", "quantity": 1, "country": "US" }],
"shippingType": "standard"
}'
Configure / build-to-order devices cannot be bought this way. Use a custom request for those.
Employees
# List employees
curl "https://ai.growrk.com/v4/employees?query=jane&limit=20" \
-H "X-API-KEY: grk_sk_your_key_here"
# Get one employee
curl https://ai.growrk.com/v4/employees/emp_123 \
-H "X-API-KEY: grk_sk_your_key_here"
# Devices assigned to an employee
curl https://ai.growrk.com/v4/employees/emp_123/devices \
-H "X-API-KEY: grk_sk_your_key_here"
# Create an employee (requires mcp:employees:write)
curl -X POST https://ai.growrk.com/v4/employees \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"displayName":"Jane Doe","email":"jane@example.com","country":"US"}'
# Update an employee's job title (requires mcp:employees:write)
curl -X PATCH https://ai.growrk.com/v4/employees/emp_123 \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"jobTitle":"Staff Engineer"}'
# Countries you already have employees in, derived from their stored delivery
# addresses. Returns each region as { value, label }, useful for populating a
# country picker before placing an order.
curl https://ai.growrk.com/v4/employees/countries \
-H "X-API-KEY: grk_sk_your_key_here"
Employee updates are restricted to a whitelist of editable fields: status, offboarding, payroll and identity fields are not writable through the API. Address changes affect future orders only, because the delivery address is read when an order is created.
Inventory & devices
# Search company inventory
curl "https://ai.growrk.com/v4/inventory?query=macbook&inStock=true&country=US" \
-H "X-API-KEY: grk_sk_your_key_here"
# Device options for ordering. `location` is where the device sits, one of
# "GroWrk Warehouse", "Employee Address", "Client Location", "In transit",
# not a country. Add `specs` to bias the ranking.
curl "https://ai.growrk.com/v4/devices/options?productType=Laptop&location=GroWrk%20Warehouse&specs=16GB%20512GB" \
-H "X-API-KEY: grk_sk_your_key_here"
# Alternative-device suggestions for a country
curl "https://ai.growrk.com/v4/devices/suggestions?country=DE&productType=Laptop" \
-H "X-API-KEY: grk_sk_your_key_here"
Products
# One inventory product (device): assignment, condition, location, serial
curl https://ai.growrk.com/v4/products/prod_456 \
-H "X-API-KEY: grk_sk_your_key_here"
# Store a device unlock PIN (requires mcp:inventory:write).
# Identify the device by productId OR serialNumber. Only device types that
# support a PIN are eligible: Desktops, Laptops, Mobile, Tablet.
curl -X POST https://ai.growrk.com/v4/products/pin-code \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"productId":"prod_456","pinCode":"482913"}'
Employees may only read their own devices.
Teams
# List teams (managers see only the teams their role scopes them to)
curl https://ai.growrk.com/v4/teams \
-H "X-API-KEY: grk_sk_your_key_here"
# One team, including its employee count
curl https://ai.growrk.com/v4/teams/team_321 \
-H "X-API-KEY: grk_sk_your_key_here"
# Create a team (requires mcp:teams:write)
curl -X POST https://ai.growrk.com/v4/teams \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"Platform Engineering"}'
# Rename a team (requires mcp:teams:write)
curl -X PATCH https://ai.growrk.com/v4/teams/team_321 \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"Core Platform"}'
Team names must be unique within the company, because the employee endpoints resolve teams by name and a duplicate would make that lookup ambiguous. Creating or renaming to an existing name returns 409 Conflict.
Company addresses
# Saved office / warehouse locations devices can ship to or be collected from
curl https://ai.growrk.com/v4/company/addresses \
-H "X-API-KEY: grk_sk_your_key_here"
# Save a new address (requires mcp:company:write)
curl -X POST https://ai.growrk.com/v4/company/addresses \
-H "X-API-KEY: grk_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"alias": "Madrid office",
"address": "Calle de Alcalá 45",
"city": "Madrid",
"zipCode": "28014",
"country": "ES",
"contactName": "Ana García",
"contactEmail": "ana@example.com",
"phone": "+34600000000"
}'
country must exist in the GroWrk regional catalog; addressTwo and state are optional, the rest are required.
Prefer a terminal or an AI assistant? The same operations are available through the CLI and MCP.