# Hardfin API API version 2026-10-26. The Hardfin public API reads and changes the records in your Hardfin organization. It is a JSON API served over HTTPS at `https://api.hardfin.com/v2`. ## Making a request Every request sends two headers. | Header | Value | | --- | --- | | `X-API-Key` or `Authorization` | An API key for your organization, or `Bearer` and an OAuth access token | | `X-API-Version` | The date your integration was built against, as `YYYY-MM-DD` | A request with a body sends it as JSON, with `Content-Type: application/json`. An upload sends `multipart/form-data` instead, and its operation lists the form fields and the file part. ```sh curl https://api.hardfin.com/v2/customer \ -H "X-API-Key: $HARDFIN_API_KEY" \ -H "X-API-Version: 2026-10-26" ``` ## Authentication - You create API keys on the Integrations page in Hardfin. - A key belongs to one organization, and every request made with it acts in that organization. - A key is issued as read-only or as read and write. A read-only key holds `hardfin:read`, and a read and write key also holds `hardfin:write`. - Hardfin's history records a change made through the API as made by the key, under the key's name. - Treat a key as a password. Keep it on your server and out of browser code. An application a person connects, such as an AI agent, signs in with OAuth 2.1 instead of a key. - The application sends `Authorization: Bearer `. - The token acts for the person who approved it, in the organization they chose, and never does more than that person can. - `hardfin:read` covers every `GET`. `hardfin:write` covers every other method, and includes reading. - The authorization server describes itself at `https://api.hardfin.com/.well-known/oauth-authorization-server`. - An application registers with a Client ID Metadata Document. There is no dynamic client registration. - An authorization request can carry an optional `device_id` of up to 255 bytes that names the device the application runs on. The person's account page lists the session under that name. A `device_id` that is longer, is not UTF-8, or holds a control character is refused. - A request that sends both an API key and a bearer token is refused with a 400. A request is refused before it reaches an endpoint in these cases. | Case | HTTP status | Body | | --- | --- | --- | | The key or token is missing or is not valid | 401 | None | | The key or token was not granted the scope the operation needs | 403 | An error with code `615` whose `details` name the `requiredScope` and the credential's `grantedScopes`, and a `WWW-Authenticate` header naming the scope | | The organization is deactivated | 403 | None | | The organization's access has ended | 403 | An error with code `1410` | ## Versioning `X-API-Version` names the date your integration was built against. Send the date you built and tested against, and keep sending it until you update your integration. - A date that is missing or cannot be read is refused with a 400 and error code `612`. - Each endpoint is versioned by itself. When an endpoint's shape changes, its earlier version is kept where it can be made compatible, and a client is answered by the newest version dated on or before its `X-API-Version`. - An answer from an earlier version carries an `API_VERSION_OUTDATED` notice in `metadata.notices`, whose `latestVersion` is the date to move to. This document describes each endpoint's current version only. - Every answer names the version that served it in the `X-API-Version` response header. A refusal that no version served carries back the date the request sent. - An earlier version that cannot be made compatible is removed, and the endpoint gets a cutoff date. - A request whose version is before an endpoint's cutoff, or before every version the endpoint still serves, is refused with a 400 and error code `613`. The client has to be updated to the endpoint's current shape. ## Responses Every response body except a 401 or a deactivated organization's 403 is an envelope. A download is the exception: its 200 body is the file's bytes and its 304 has no body, while a refused download still answers with an envelope. ```json { "data": { "id": "0192f7d4-3b6a-7c1e-9f2d-5a8b4c6e7d11", "name": "Acme Robotics" }, "metadata": { "errors": null, "requestId": "0192f7d4-3b6a-7c1e-9f2d-5a8b4c6e7d10", "requestTime": "12ms", "statusCode": 200, "notices": [] } } ``` | Field | Holds | | --- | --- | | `data` | What the endpoint returns, or `null` when the request was refused | | `metadata.errors` | Why the request was refused, or `null` when it succeeded | | `metadata.requestId` | The identifier to quote when you contact Hardfin about a request | | `metadata.requestTime` | How long the server took to answer | | `metadata.statusCode` | The HTTP status, or a Hardfin error code when one names the failure | | `metadata.notices` | What you should know about the request beside any error. A notice never fails a request | ## Notices `metadata.notices` lists what Hardfin noticed about a request. An endpoint's answer always carries the list, empty when there is nothing to say. A path that matches no endpoint is answered without it. | Code | Sent when | Extra field | | --- | --- | --- | | `API_VERSION_OUTDATED` | `X-API-Version` is behind the endpoint's last change | `latestVersion`, the date to move to | | `UNKNOWN_FIELD` | The request sent a query parameter or body field the endpoint does not read. The value was ignored | `field`, the parameter or the field's path, such as `lineItems[0].quantty` | - A body field is checked inside objects and list elements. The fields of a money object, `amount` and `isoCode`, are not checked. - A body field name matches in any case, as decoding does, so only a name the endpoint has under no spelling is noticed. - A request refused for one of its values still carries its notices. A misspelled required field is refused as missing, and the notice names what was sent instead. - A request refused before its fields are read, such as for a body that is not valid JSON, carries no `UNKNOWN_FIELD` notice. - At most 20 unknown fields are named. Past 20, one more `UNKNOWN_FIELD` notice, with no `field`, counts the rest. - Ignore a code you do not recognize. ## Errors - A refused request answers with a 400 and one or more entries in `metadata.errors`. - Each entry has an `error` message and a `statusCode`. - A `statusCode` above 600 is a Hardfin error code. It names the failure more precisely than the HTTP status does. - Branch on the code. The message is written for a person and may change. A slow request can fail under an HTTP 200. - `POST /shipment/{shipmentKey}/deliver` can run for a long time on a large shipment. - After 30 seconds it starts its response, to keep the connection open, and that sends the HTTP status as 200. - A delivery that fails after that point still answers with `data` as `null` and the reason in `metadata.errors`, under the 200. - Read `metadata.statusCode` and `metadata.errors` on this endpoint, not the HTTP status alone. ## Enums - An enum value is accepted in any case, so `asc`, `Asc` and `ASC` are the same value. - A response always uses the spelling the schema lists. - An enum whose schema allows `null` sends `null` when it has no value. ## Nullable fields and updates - A field whose type includes `null` may be sent or returned as `null`. - A `PATCH` changes only the fields it sends. An omitted field keeps its value. - Sending `null` for a field that accepts it clears the field. - A field whose type leaves out `null` refuses it, even in a `PATCH`. ## Redacted fields - Some fields are shown only to a caller whose role grants a permission. The field's description names that permission. - A redacted field is sent as an object with a `status` and a `value`, in one of two shapes. | `status` | `value` | Sent when | | --- | --- | --- | | `VISIBLE` | the field's value | the caller's role grants the permission | | `REMOVED` | `null` | the caller's role does not grant it | - Read `status` before `value`. A `VISIBLE` field whose type includes `null` can also carry `null`, and that means the field has no value. - A `REMOVED` field says nothing about whether the field has a value. ## Lists and pages A list endpoint returns one page of records in `data`. | Parameter | Meaning | | --- | --- | | `page` | The page to return, starting at 1. A page past the last is refused | | `limit` | The number of records per page, from 1 to 100. Defaults to 100 | | `sortBy` | One of the names the endpoint lists, or its snake_case spelling, in any case. Any other value is refused | | `sortOrder` | `asc` or `desc`, in any case. Any other value is refused. Defaults to `asc` | | `archived` | `false` for unarchived records, `true` for archived records, `all` for both. Defaults to `false` | A page with fewer records than `limit` is the last page. ## Identifiers and formats - Every record has an `id`, which is a UUID, and a `key`, such as `cust_V1StGXR8Z5jdHi6B`. - An endpoint that takes a record in its path takes the record's key. | Type | Sent as | | --- | --- | | Identifier | A UUID string | | Timestamp | An RFC 3339 string, such as `2026-09-17T14:03:00Z` | | Date | A `YYYY-MM-DD` string from 1900-01-01 through 2099-12-31, or from 1970-01-01 where a field's description says so | | Decimal | A string, such as `"125.50"`, so no precision is lost | ## Reference pages - [Asset operations](https://developers.hardfin.com/asset.md) - [Billing operations](https://developers.hardfin.com/billing.md) - [Contact operations](https://developers.hardfin.com/contact.md) - [Customer operations](https://developers.hardfin.com/customer.md) - [Exchange group operations](https://developers.hardfin.com/exchangegroup.md) - [File operations](https://developers.hardfin.com/file.md) - [Fulfillment operations](https://developers.hardfin.com/fulfillment.md) - [Inventory operations](https://developers.hardfin.com/inventory.md) - [Item operations](https://developers.hardfin.com/item.md) - [Location operations](https://developers.hardfin.com/location.md) - [Metadata operations](https://developers.hardfin.com/metadata.md) - [Note operations](https://developers.hardfin.com/note.md) - [Organization operations](https://developers.hardfin.com/organization.md) - [Project operations](https://developers.hardfin.com/project.md) - [Purchase order operations](https://developers.hardfin.com/purchaseorder.md) - [Return order operations](https://developers.hardfin.com/returnorder.md) - [Shipment operations](https://developers.hardfin.com/shipment.md) - [Token operations](https://developers.hardfin.com/token.md) - [URL link operations](https://developers.hardfin.com/urllink.md) - [Workflow operations](https://developers.hardfin.com/workflow.md) - [Schemas](https://developers.hardfin.com/schemas.md): every record's fields - [OpenAPI document](https://developers.hardfin.com/openapi.yaml) --- # Asset operations ## Get asset listing `GET https://api.hardfin.com/v2/asset` Operation `assetGetAssetListing`, which needs the `hardfin:read` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `results.accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `results.accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `results.accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `results.accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `results.accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `results.scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `results.scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-16 | `currency` added to the request | | 2026-10-16 | `results.accounting.costCurrencyCode` added to the response | | 2026-10-16 | `results.accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `results.scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-14 | Request validation changed | | 2026-10-08 | `ACTIVE` added to `results.project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `results.project.status` in the response | | 2026-10-08 | `PAST` added to `results.project.status` in the response | | 2026-10-08 | `UPCOMING` added to `results.project.status` in the response | | 2026-10-06 | `ACTIVE` added to `withProjectStatus` in the request | | 2026-10-06 | `NONE` added to `withProjectStatus` in the request | | 2026-10-06 | `PAST` added to `withProjectStatus` in the request | | 2026-10-06 | `UPCOMING` added to `withProjectStatus` in the request | | 2026-10-06 | `results.project.end` removed from the response | | 2026-10-06 | `results.project.endOn` added to the response | | 2026-10-06 | `results.project.start` removed from the response | | 2026-10-06 | `results.project.startOn` added to the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `serial`, `project`, `item`, `location`, `owner`, `activity` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived records, archived records, or all of them. | | `searchQuery` | query | no | string, or null | Text to match against the serial, description, item, project, owner, and location, ignored when shorter than three characters. | | `forAssetId` | query | no | list of string (uuid) | The IDs of the assets to list. | | `forAssetKey` | query | no | list of string | The keys of the assets to list. | | `forCustomer` | query | no | list of string (uuid) | The IDs of the customers whose assets to list. | | `forItem` | query | no | list of string (uuid) | The IDs of the items whose assets to list. | | `atSite` | query | no | list of string (uuid) | The IDs of the locations whose assets to list. | | `atCustomerSites` | query | no | list of string (uuid) | The IDs of the customers whose sites to list assets at. | | `withFunctionalStatuses` | query | no | list of [AssetFunctionalStatus](schemas.md#assetfunctionalstatus) | The functional statuses to list, where SCRAPPED lists scrapped assets only when scrapped is true or all, since scrapped defaults to false. | | `currency` | query | no | [CurrencyCode](schemas.md#currencycode), or null | The ISO 4217 code of the cost currency whose assets to list. | | `withTransitStatuses` | query | no | list of [TransitStatus](schemas.md#transitstatus) | The transit statuses to list. | | `withInventoryStatuses` | query | no | list of string | In_inventory, not_in_inventory, or both, which filters only when one is sent. | | `withLocationCompanyType` | query | no | list of string | Customer, manufacturer, or both, for assets at customer sites or your own, which filters only when one is sent. | | `withProjectStatus` | query | no | list of [AssetProjectStatusFilter](schemas.md#assetprojectstatusfilter) | The project assignments to list: UPCOMING, ACTIVE, PAST, or NONE. | | `withOwner` | query | no | list of string | Manufacturer for assets your organization owns, customer for assets customers own, or both. | | `forProject` | query | no | list of string (uuid) | The IDs of the projects whose assets to list. | | `scrapped` | query | no | [ScrappedState](schemas.md#scrappedstate) | Whether to list unscrapped assets, scrapped assets, or all of them. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetListing](schemas.md#assetlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create asset `POST https://api.hardfin.com/v2/asset` Operation `assetCreateAsset`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `allocatedIndirect.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `EUR` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `GBP` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `USD` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `billOfMaterials.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `EUR` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `GBP` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `USD` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `directLabor.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `directLabor.isoCode` in the request | | 2026-10-21 | `EUR` added to `directLabor.isoCode` in the request | | 2026-10-21 | `GBP` added to `directLabor.isoCode` in the request | | 2026-10-21 | `USD` added to `directLabor.isoCode` in the request | | 2026-10-21 | `freightInbound.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `EUR` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `GBP` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `USD` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `freightOutbound.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `EUR` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `GBP` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `USD` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `installation.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `installation.isoCode` in the request | | 2026-10-21 | `EUR` added to `installation.isoCode` in the request | | 2026-10-21 | `GBP` added to `installation.isoCode` in the request | | 2026-10-21 | `USD` added to `installation.isoCode` in the request | | 2026-10-21 | `interest.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `interest.isoCode` in the request | | 2026-10-21 | `EUR` added to `interest.isoCode` in the request | | 2026-10-21 | `GBP` added to `interest.isoCode` in the request | | 2026-10-21 | `USD` added to `interest.isoCode` in the request | | 2026-10-21 | `salvageValue.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `EUR` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `GBP` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `USD` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `simpleCostBasis.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `EUR` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `GBP` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `USD` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `tariffs.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `tariffs.isoCode` in the request | | 2026-10-21 | `EUR` added to `tariffs.isoCode` in the request | | 2026-10-21 | `GBP` added to `tariffs.isoCode` in the request | | 2026-10-21 | `USD` added to `tariffs.isoCode` in the request | | 2026-10-21 | `tax.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `tax.isoCode` in the request | | 2026-10-21 | `EUR` added to `tax.isoCode` in the request | | 2026-10-21 | `GBP` added to `tax.isoCode` in the request | | 2026-10-21 | `USD` added to `tax.isoCode` in the request | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-19 | `allocatedIndirect` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `billOfMaterials` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `directLabor` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `freightInbound` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `freightOutbound` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `installation` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `interest` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `salvageValue` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `simpleCostBasis` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `tariffs` in the request changed from `decimal or null` to `object or null` | | 2026-10-19 | `tax` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `costCurrencyCode` added to the request | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `allocatedIndirect` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | One unit's share of overhead, a cost component. | | `billOfMaterials` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The parts cost of one unit, a cost component. | | `costCurrencyCode` | [CurrencyCode](schemas.md#currencycode), or null | no | The ISO 4217 code the asset's costs are denominated in, which defaults to the item's accounting currency and then the organization's, and which every cost amount must match. | | `depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The method one unit is depreciated by, taken from the item when omitted, or null to leave it empty. | | `description` | string, or null | no | A free-form description of the asset. | | `directLabor` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The labor cost to build one unit, a cost component. | | `freightInbound` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The shipping cost to receive one unit, a cost component. | | `freightOutbound` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The shipping cost to deploy one unit, a deployment cost component. | | `functionalStatus` | [AssetFunctionalStatus](schemas.md#assetfunctionalstatus), or null | no | The asset's starting functional status, FUNCTIONAL when absent, which cannot be SCRAPPED because a scrapped asset is created first and then scrapped through its own endpoint. | | `inInventoryDate` | string (date) | yes | The day the asset entered inventory, which cannot be in the future. | | `inServiceDate` | string (date), or null | no | The day the asset was put into service, from 1970-01-01 through 2099-12-31, which Hardfin sets itself when absent. | | `installation` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The cost to install one unit, a deployment cost component. | | `interest` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The financing cost of one unit, a cost component. | | `itemId` | string (uuid) | yes | The ID of the catalog item the asset is a unit of, which cannot be changed after the asset is created. | | `locationId` | string (uuid) | yes | The ID of the location the asset enters inventory at. | | `salvageValue` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The value one unit keeps at the end of its useful life, in the asset's cost currency, taken from the item when omitted and the item's accounting currency is the asset's, or null to leave it empty. | | `serial` | string | yes | The asset's serial number, unique within your organization in any case. | | `simpleCostBasis` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | A single cost for one unit, which cannot be sent together with the cost components, and whose cluster is taken from the item when every cost field is omitted and the item's accounting currency is the asset's. | | `tariffs` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The import duty paid on one unit, a cost component. | | `tax` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The tax paid on one unit, a cost component. | | `usefulLife` | integer, or null | no | The number of months one unit is depreciated over, from 1 to 480, taken from the item when omitted, or null to leave it empty. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Execute asset move `POST https://api.hardfin.com/v2/asset/move/execute` Operation `assetExecuteAssetMove`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Error codes or messages changed | | 2026-10-12 | Error codes or messages changed | | 2026-09-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `moves` | list of [AssetProposedMultiMove](schemas.md#assetproposedmultimove) | no | The moves to carry out. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Plan asset move `POST https://api.hardfin.com/v2/asset/move/plan` Operation `assetPlanAssetMove`, which needs the `hardfin:write` scope. Last changed on 2026-10-12. | Date | Change | | --- | --- | | 2026-10-12 | Error codes or messages changed | | 2026-09-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `moves` | list of [AssetMoveToPlan](schemas.md#assetmovetoplan) | no | The moves to plan. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [AssetPlannedMove](schemas.md#assetplannedmove) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get asset `GET https://api.hardfin.com/v2/asset/{assetKey}` Operation `assetGetAsset`, which needs the `hardfin:read` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Patch asset `PATCH https://api.hardfin.com/v2/asset/{assetKey}` Operation `assetPatchAsset`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Request validation changed | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `description` | string, or null | no | The asset's new description, or null to clear it. | | `functionalStatus` | [AssetFunctionalStatus](schemas.md#assetfunctionalstatus), or null | no | The asset's new functional status, which cannot be SCRAPPED because scrapping has its own endpoint. | | `inInventoryDate` | string (date), or null | no | The day the asset entered inventory, which cannot be in the future. | | `initialLocationId` | string (uuid), or null | no | The ID of the location the asset entered inventory at. | | `metadata` | list of [AssetUpdateMetadataItem](schemas.md#assetupdatemetadataitem) | no | New values for the asset's custom fields, each naming its field. | | `serial` | string | no | The asset's new serial number, which cannot be empty and must be unique within your organization in any case. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Update asset accounting `PATCH https://api.hardfin.com/v2/asset/{assetKey}/accounting` Operation `assetUpdateAssetAccounting`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `allocatedIndirect.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `EUR` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `GBP` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `USD` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `billOfMaterials.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `EUR` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `GBP` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `USD` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `directLabor.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `directLabor.isoCode` in the request | | 2026-10-21 | `EUR` added to `directLabor.isoCode` in the request | | 2026-10-21 | `GBP` added to `directLabor.isoCode` in the request | | 2026-10-21 | `USD` added to `directLabor.isoCode` in the request | | 2026-10-21 | `freightInbound.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `EUR` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `GBP` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `USD` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `freightOutbound.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `EUR` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `GBP` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `USD` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `installation.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `installation.isoCode` in the request | | 2026-10-21 | `EUR` added to `installation.isoCode` in the request | | 2026-10-21 | `GBP` added to `installation.isoCode` in the request | | 2026-10-21 | `USD` added to `installation.isoCode` in the request | | 2026-10-21 | `interest.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `interest.isoCode` in the request | | 2026-10-21 | `EUR` added to `interest.isoCode` in the request | | 2026-10-21 | `GBP` added to `interest.isoCode` in the request | | 2026-10-21 | `USD` added to `interest.isoCode` in the request | | 2026-10-21 | `salvageValue.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `EUR` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `GBP` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `USD` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `simpleCostBasis.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `EUR` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `GBP` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `USD` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `tariffs.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `tariffs.isoCode` in the request | | 2026-10-21 | `EUR` added to `tariffs.isoCode` in the request | | 2026-10-21 | `GBP` added to `tariffs.isoCode` in the request | | 2026-10-21 | `USD` added to `tariffs.isoCode` in the request | | 2026-10-21 | `tax.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `tax.isoCode` in the request | | 2026-10-21 | `EUR` added to `tax.isoCode` in the request | | 2026-10-21 | `GBP` added to `tax.isoCode` in the request | | 2026-10-21 | `USD` added to `tax.isoCode` in the request | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-19 | Error codes or messages changed | | 2026-10-16 | `allocatedIndirect` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `billOfMaterials` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `costCurrencyCode` added to the request | | 2026-10-16 | `directLabor` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `freightInbound` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `freightOutbound` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `installation` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `interest` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `salvageValue` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `simpleCostBasis` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `tariffs` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `tax` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `allocatedIndirect` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | One unit's share of overhead, a cost component, and sending it clears simpleCostBasis. | | `billOfMaterials` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The parts cost of one unit, a cost component, and sending it clears simpleCostBasis. | | `costCurrencyCode` | [CurrencyCode](schemas.md#currencycode), or null | no | The ISO 4217 code every cost amount is denominated in, which must match the amounts sent and cannot be null. It is the only way to change the currency. A change keeps the held amounts and relabels them without conversion, and on an asset whose currency is locked it is refused. | | `depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The method one unit is depreciated by, or null to clear it. | | `directLabor` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The labor cost to build one unit, a cost component, and sending it clears simpleCostBasis. | | `freightInbound` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The shipping cost to receive one unit, a cost component, and sending it clears simpleCostBasis. | | `freightOutbound` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The shipping cost to deploy one unit, a deployment cost component, and sending it clears simpleCostBasis. | | `inServiceDate` | string (date), or null | no | The day the asset was put into service and began depreciating, from 1970-01-01 through 2099-12-31, or null to clear it. | | `installation` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The cost to install one unit, a deployment cost component, and sending it clears simpleCostBasis. | | `interest` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The financing cost of one unit, a cost component, and sending it clears simpleCostBasis. | | `isInServiceDateManagedAutomatically` | boolean, or null | no | Whether Hardfin sets the in-service date itself, which sending an in-service date turns off. | | `salvageValue` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The value one unit keeps at the end of its useful life, or null to clear it. | | `simpleCostBasis` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | A single cost for one unit, which clears the cost components and cannot be sent together with them. | | `tariffs` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The import duty paid on one unit, a cost component, and sending it clears simpleCostBasis. | | `tax` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The tax paid on one unit, a cost component, and sending it clears simpleCostBasis. | | `usefulLife` | integer, or null | no | The number of months one unit is depreciated over, from 1 to 480, or null to clear it. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Toggle in service date management `PATCH https://api.hardfin.com/v2/asset/{assetKey}/accounting/in-service-management` Operation `assetToggleInServiceDateManagement`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Request validation changed | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `automatic` | boolean | yes | Whether Hardfin sets the asset's in-service date itself. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Create asset cost adjustment `POST https://api.hardfin.com/v2/asset/{assetKey}/cost-adjustment` Operation `assetCreateAssetCostAdjustment`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `amount.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `amount.isoCode` in the request | | 2026-10-21 | `EUR` added to `amount.isoCode` in the request | | 2026-10-21 | `GBP` added to `amount.isoCode` in the request | | 2026-10-21 | `USD` added to `amount.isoCode` in the request | | 2026-10-21 | `amount` in the response changed from `decimal` to `object` | | 2026-10-19 | Request validation changed | | 2026-10-16 | `amount` in the request changed from `decimal` to `object` | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `adjustmentType` | [CostAdjustmentType](schemas.md#costadjustmenttype) | yes | Whether the adjustment adds to the asset's cost basis or writes it down. | | `amount` | [NonNegativeCurrency](schemas.md#nonnegativecurrency) | yes | How much the adjustment changes the cost basis by, in the asset's cost currency, which must be greater than zero. | | `amount.amount` | string (decimal) | no | The exact value as a decimal string, which cannot be negative, sent with at most two decimal places. | | `amount.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `effectiveDate` | string (date) | yes | The day the adjustment takes effect, which cannot be in the future. | | `notes` | string, or null | no | Free-form detail about the adjustment, which a reason of OTHER requires. | | `reason` | [CostAdjustmentReason](schemas.md#costadjustmentreason) | yes | Why the adjustment was made, which must be one its adjustment type allows. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetCostAdjustment](schemas.md#assetcostadjustment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get asset event list `GET https://api.hardfin.com/v2/asset/{assetKey}/event` Operation `assetGetAssetEventList`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [AssetEvent](schemas.md#assetevent) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get asset event group listing `GET https://api.hardfin.com/v2/asset/{assetKey}/event-group` Operation `assetGetAssetEventGroupListing`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | | `start` | query | no | string (date-time), or null | The earliest an event group may have happened, or null to read from the first. | | `end` | query | no | string (date-time), or null | The latest an event group may have happened, or null to read through the last. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [AssetEventGroup](schemas.md#asseteventgroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get asset event group `GET https://api.hardfin.com/v2/asset/{assetKey}/event-group/{eventGroupKey}` Operation `assetGetAssetEventGroup`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | | `eventGroupKey` | path | yes | string | The event group's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetEventGroup](schemas.md#asseteventgroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get asset files `GET https://api.hardfin.com/v2/asset/{assetKey}/file` Operation `assetGetAssetFiles`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [AssetFile](schemas.md#assetfile) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Delete asset file `DELETE https://api.hardfin.com/v2/asset/{assetKey}/file/{fileKey}` Operation `assetDeleteAssetFile`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | | `fileKey` | path | yes | string | The file's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get asset functional status history `GET https://api.hardfin.com/v2/asset/{assetKey}/functional-status` Operation `assetGetAssetFunctionalStatusHistory`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [AssetFunctionalStatusHistoryItem](schemas.md#assetfunctionalstatushistoryitem) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get asset ownership history `GET https://api.hardfin.com/v2/asset/{assetKey}/ownership` Operation `assetGetAssetOwnershipHistory`, which needs the `hardfin:read` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | `salePrice` in the response changed from `decimal or null` to `object or null` | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [AssetOwnershipHistoryItem](schemas.md#assetownershiphistoryitem) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Create asset ownership `POST https://api.hardfin.com/v2/asset/{assetKey}/ownership` Operation `assetCreateAssetOwnership`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `salePrice.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `salePrice.isoCode` in the request | | 2026-10-21 | `EUR` added to `salePrice.isoCode` in the request | | 2026-10-21 | `GBP` added to `salePrice.isoCode` in the request | | 2026-10-21 | `USD` added to `salePrice.isoCode` in the request | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-16 | `salePrice` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `customerId` | string (uuid) | yes | The ID of the customer that takes ownership of the asset, which records a sale or transfer to that customer. An asset your organization still owns at a customer's site takes no owner and is located at that site instead. | | `date` | string (date) | yes | The day the customer takes ownership, which cannot be in the future. | | `salePrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | What the customer paid for the asset, which cannot be negative. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Clear asset active ownership `DELETE https://api.hardfin.com/v2/asset/{assetKey}/ownership` Operation `assetClearAssetActiveOwnership`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `date` | string (date) | yes | The day your organization takes the asset back, which cannot be in the future. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get asset ownership segment `GET https://api.hardfin.com/v2/asset/{assetKey}/ownership/{segmentKey}` Operation `assetGetAssetOwnershipSegment`, which needs the `hardfin:read` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | `salePrice` in the response changed from `decimal or null` to `object or null` | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | | `segmentKey` | path | yes | string | The ownership segment's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetOwnershipHistoryItem](schemas.md#assetownershiphistoryitem) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Patch asset ownership segment `PATCH https://api.hardfin.com/v2/asset/{assetKey}/ownership/{segmentKey}` Operation `assetPatchAssetOwnershipSegment`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `customerId` in the request changed from `uuid or null` to `uuid` | | 2026-10-22 | `date` in the request changed from `date or null` to `date` | | 2026-10-19 | Request validation changed | | 2026-10-16 | `salePrice` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `salePrice` in the response changed from `decimal or null` to `object or null` | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | | `segmentKey` | path | yes | string | The ownership segment's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `customerId` | string (uuid) | no | The ID of the customer that owned the asset during the segment, and cannot be null. | | `date` | string (date) | no | The day the segment's owner took ownership, which cannot be null or in the future. | | `salePrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | What the owner paid for the asset, which cannot be negative. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetOwnershipHistoryItem](schemas.md#assetownershiphistoryitem) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Delete asset ownership segment `DELETE https://api.hardfin.com/v2/asset/{assetKey}/ownership/{segmentKey}` Operation `assetDeleteAssetOwnershipSegment`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | | `segmentKey` | path | yes | string | The ownership segment's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Scrap asset `POST https://api.hardfin.com/v2/asset/{assetKey}/scrap` Operation `assetScrapAsset`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `disposalPrice.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `disposalPrice.isoCode` in the request | | 2026-10-21 | `EUR` added to `disposalPrice.isoCode` in the request | | 2026-10-21 | `GBP` added to `disposalPrice.isoCode` in the request | | 2026-10-21 | `USD` added to `disposalPrice.isoCode` in the request | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-16 | `disposalPrice` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `disposalDate` | string (date) | yes | The day the asset was scrapped. | | `disposalPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | What the scrapped asset was sold for, left out when it was not sold, and refused even as null for an asset a customer owns. | | `disposalReason` | string, or null | no | Why the asset was scrapped. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Unscrap asset `POST https://api.hardfin.com/v2/asset/{assetKey}/unscrap` Operation `assetUnscrapAsset`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `accounting.acquisitionCogs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.capitalizedCosts` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.costAdjustments.amount` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.accumulated` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.bookValue` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.depreciationPeriods.depreciation` in the response changed from `decimal` to `object` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalPotentialCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `scrappedContext.disposalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `scrappedContext.disposalPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-10-16 | `accounting.isCostCurrencyLocked` added to the response | | 2026-10-16 | `scrappedContext.disposalPrice` in the response changed from `decimal or null` to `object or null` | | 2026-10-08 | `ACTIVE` added to `project.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `project.status` in the response | | 2026-10-08 | `PAST` added to `project.status` in the response | | 2026-10-08 | `UPCOMING` added to `project.status` in the response | | 2026-10-06 | `project.end` removed from the response | | 2026-10-06 | `project.endOn` added to the response | | 2026-10-06 | `project.start` removed from the response | | 2026-10-06 | `project.startOn` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Asset](schemas.md#asset) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get asset URL links `GET https://api.hardfin.com/v2/asset/{assetKey}/url-link` Operation `assetGetAssetURLLinks`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Create asset URL link `POST https://api.hardfin.com/v2/asset/{assetKey}/url-link` Operation `assetCreateAssetURLLink`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string, or null | no | The link's display name, or null to show the address instead. | | `url` | string | yes | The address the link points to. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Create asset useful life revision `POST https://api.hardfin.com/v2/asset/{assetKey}/useful-life-revision` Operation `assetCreateAssetUsefulLifeRevision`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `assetKey` | path | yes | string | The asset's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `effectiveDate` | string (date) | yes | The day the revised useful life takes effect, which cannot be in the future. | | `notes` | string, or null | no | Free-form detail about the revision, which a reason of OTHER requires. | | `reason` | [UsefulLifeRevisionReason](schemas.md#usefulliferevisionreason) | yes | Why the useful life was revised. | | `usefulLifeMonths` | integer | yes | The asset's revised useful life in months. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetUsefulLifeRevision](schemas.md#assetusefulliferevision) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Billing operations ## Get charges `GET https://api.hardfin.com/v2/charge` Operation `billingGetCharges`, which needs the `hardfin:read` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | Request validation changed | | 2026-10-14 | Request validation changed | | 2026-10-08 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `project`, `customer`, `label`, `totalPrice`, `servicePeriodStart`, `expectedBillableDate`, `status`, `item` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `search` | query | no | string, or null | Text to find in the charge's label, its project's name, its customer's name, or its item's SKU or name, and a number also finds a charge with exactly that total price. | | `status` | query | no | [ChargeStatus](schemas.md#chargestatus), or null | The one status to list: PLANNED, BILLABLE, INVOICED or CANCELLED. | | `customers` | query | no | list of string (hardfin-identifier) | The customers whose charges to list, each named by its ID or its key. | | `includeNoCustomer` | query | no | boolean, or null | True to list the charges of projects that have no customer. With customers it adds them to those customers' charges, and without customers it lists only them. | | `projects` | query | no | list of string (hardfin-identifier) | The projects whose charges to list, each named by its ID or its key. | | `billDateStart` | query | no | string (date), or null | A day, and only charges whose expectedBillableDate is on or after it are listed. | | `billDateEnd` | query | no | string (date), or null | A day, and only charges whose expectedBillableDate is on or before it are listed. | | `amountMin` | query | no | string (decimal), or null | An amount, and only charges whose total price is at least it are listed. | | `amountMax` | query | no | string (decimal), or null | An amount, and only charges whose total price is at most it are listed. | | `triggerTypes` | query | no | list of [ChargeTriggerType](schemas.md#chargetriggertype) | The trigger types to list: TIME, MANUAL or EVENT. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ChargePage](schemas.md#chargepage) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Cancel charge `POST https://api.hardfin.com/v2/charge/{chargeKey}/cancel` Operation `billingCancelCharge`, which needs the `hardfin:write` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | `actualBillableAt` added to the response | | 2026-10-16 | `cancellationReason` added to the response | | 2026-10-16 | `cancelledAt` added to the response | | 2026-10-12 | Request validation changed | | 2026-10-08 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `chargeKey` | path | yes | string | The key of the charge to cancel. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string, or null | no | Why the charge is cancelled, kept exactly as sent and 4,096 characters or less, or null for no reason. Cancelling a cancelled charge again replaces its reason with a different one sent, and null keeps the reason it has. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Charge](schemas.md#charge) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Mark charge billable `POST https://api.hardfin.com/v2/charge/{chargeKey}/mark-billable` Operation `billingMarkChargeBillable`, which needs the `hardfin:write` scope. Last changed on 2026-10-19. | Date | Change | | --- | --- | | 2026-10-19 | Request validation changed | | 2026-10-16 | `newCharge.actualBillableAt` added to the response | | 2026-10-16 | `newCharge.cancellationReason` added to the response | | 2026-10-16 | `newCharge.cancelledAt` added to the response | | 2026-10-16 | `updatedCharge.actualBillableAt` added to the response | | 2026-10-16 | `updatedCharge.cancellationReason` added to the response | | 2026-10-16 | `updatedCharge.cancelledAt` added to the response | | 2026-10-12 | `billingEligibleDate` in the request changed from `date or null` to `date` | | 2026-10-12 | `quantity` in the request is now required | | 2026-10-12 | Error codes or messages changed | | 2026-10-08 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `chargeKey` | path | yes | string | The key of the charge to mark billable. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `billingEligibleDate` | string (date) | yes | The day the charge became billable, which is required and does not change its expectedBillableDate. | | `quantity` | integer | yes | The number of units to bill now, from 1 to the charge's quantity, and a smaller number splits the charge in two. | | `servicePeriodEnd` | string (date), or null | no | The last day of the period a milestone charge covers, on or after servicePeriodStart. It replaces and is ignored the same way as servicePeriodStart. | | `servicePeriodStart` | string (date), or null | no | The first day of the period a milestone charge covers. On a milestone charge it replaces the charge's start, and omitting it leaves the charge with no start. A periodic charge ignores it. | | `totalPriceOverride` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The amount to bill now, which is required when a FIXED charge is split, must be in the charge's currency, is from 0 to the charge's total price, and is refused when the charge is not split or is priced PER_UNIT. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ChargeMarkedBillable](schemas.md#chargemarkedbillable) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Mark charge not billable `POST https://api.hardfin.com/v2/charge/{chargeKey}/mark-not-billable` Operation `billingMarkChargeNotBillable`, which needs the `hardfin:write` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | `actualBillableAt` added to the response | | 2026-10-16 | `cancellationReason` added to the response | | 2026-10-16 | `cancelledAt` added to the response | | 2026-10-08 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `chargeKey` | path | yes | string | The key of the charge to return to planned. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `expectedBillableDate` | string (date), or null | no | The new day a periodic charge is planned to become billable, or omitted to keep the day it has. A milestone charge, and a charge that is already planned, keep their day. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Charge](schemas.md#charge) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Revert charge cancellation `POST https://api.hardfin.com/v2/charge/{chargeKey}/revert-cancellation` Operation `billingRevertChargeCancellation`, which needs the `hardfin:write` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | `actualBillableAt` added to the response | | 2026-10-16 | `cancellationReason` added to the response | | 2026-10-16 | `cancelledAt` added to the response | | 2026-10-08 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `chargeKey` | path | yes | string | The key of the cancelled charge to restore. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Charge](schemas.md#charge) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Contact operations ## Get contacts `GET https://api.hardfin.com/v2/contact` Operation `contactGetContacts`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `name`, `email`, `phone`, `title`, `customer`, `lastUpdatedAt` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived records, archived records, or all of them. | | `customerIds` | query | no | list of string (uuid) | The IDs of the customers whose contacts to return. | | `search` | query | no | string, or null | Text to match against a contact's first name, last name, email, phone, title, comments, or customer name, in any case. | | `email` | query | no | string, or null | The email address of the contacts to return, matched exactly in any case. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ContactListing](schemas.md#contactlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create contact `POST https://api.hardfin.com/v2/contact` Operation `contactCreateContact`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `comments` | string, or null | no | A note about the contact. | | `customerId` | string (uuid) | yes | The ID of the customer the contact works for. | | `email` | string, or null | no | The contact's email address. | | `firstName` | string | yes | The contact's first name. | | `lastName` | string | yes | The contact's last name. | | `phone` | string, or null | no | The contact's phone number. | | `title` | string, or null | no | The contact's job title. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SparseContact](schemas.md#sparsecontact) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get contact `GET https://api.hardfin.com/v2/contact/{contactKey}` Operation `contactGetContact`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `contactKey` | path | yes | string | The contact's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SparseContact](schemas.md#sparsecontact) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Patch contact `PATCH https://api.hardfin.com/v2/contact/{contactKey}` Operation `contactPatchContact`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `contactKey` | path | yes | string | The contact's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `comments` | string, or null | no | A note about the contact, or null to clear it. | | `customerId` | string (uuid), or null | no | The ID of the customer the contact works for, which cannot be cleared. | | `email` | string, or null | no | The contact's email address, or null to clear it. | | `firstName` | string, or null | no | The contact's first name, which cannot be cleared. | | `isArchived` | boolean | no | Whether the contact is archived, and cannot be null. | | `lastName` | string, or null | no | The contact's last name, which cannot be cleared. | | `phone` | string, or null | no | The contact's phone number, or null to clear it. | | `title` | string, or null | no | The contact's job title, or null to clear it. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SparseContact](schemas.md#sparsecontact) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Customer operations ## Get customers `GET https://api.hardfin.com/v2/customer` Operation `customerGetCustomers`, which needs the `hardfin:read` scope. Last changed on 2026-10-14. | Date | Change | | --- | --- | | 2026-10-14 | Request validation changed | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `name`, `locationCount`, `assetCount`, `assetsAtLocation` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived records, archived records, or all of them. | | `isCustomer` | query | no | boolean, or null | True to return only customers, or false to return only non-customers. | | `isSupplier` | query | no | boolean, or null | True to return only suppliers, or false to return only non-suppliers. | | `syncStatuses` | query | no | list of one of `in-sync`, `out-of-sync`, `not-linked` | The integration sync statuses to return: in-sync, out-of-sync, or not-linked. | | `search` | query | no | string, or null | Text to match against customer names, ignored when shorter than three characters. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [CustomerListing](schemas.md#customerlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create customer `POST https://api.hardfin.com/v2/customer` Operation `customerCreateCustomer`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-09-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `billingAddress` | string, or null | no | The address invoices are sent to. | | `billingContact` | [CustomerBillingContact](schemas.md#customerbillingcontact), or null | no | The person who receives the customer's invoices. | | `comment` | string, or null | no | A free-form note about the customer. | | `domain` | string, or null | no | The customer's web domain, used to look up its logo. | | `externalId` | string, or null | no | The customer's identifier in another system. | | `isCustomer` | boolean | no | Whether the company is a customer. | | `isSupplier` | boolean | no | Whether the company is a supplier. | | `name` | string | yes | The customer's display name, unique within your organization in any case. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Customer](schemas.md#customer) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get customer `GET https://api.hardfin.com/v2/customer/{customerKey}` Operation `customerGetCustomer`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `customerKey` | path | yes | string | The customer's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Customer](schemas.md#customer) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Patch customer `PATCH https://api.hardfin.com/v2/customer/{customerKey}` Operation `customerPatchCustomer`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `customerKey` | path | yes | string | The customer's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `billingAddress` | string, or null | no | The address invoices are sent to. | | `billingContact` | [CustomerBillingContact](schemas.md#customerbillingcontact), or null | no | The person who receives the customer's invoices. | | `comment` | string, or null | no | A free-form note about the customer. | | `domain` | string, or null | no | The customer's web domain, used to look up its logo. | | `externalId` | string, or null | no | The customer's identifier in another system. | | `isArchived` | boolean, or null | no | Whether the customer is archived. | | `isCustomer` | boolean, or null | no | Whether the company is a customer. | | `isSupplier` | boolean, or null | no | Whether the company is a supplier. | | `name` | string | no | The customer's display name, unique within your organization in any case. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Customer](schemas.md#customer) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Exchange group operations ## List exchange groups `GET https://api.hardfin.com/v2/exchange-group` Operation `exchangeGroupListExchangeGroups`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `exchangeNumber`, `status` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `search` | query | no | string, or null | Text to find in the exchange's number, its status, or the names and SKUs of its orders' items. | | `exchangeGroupKeys` | query | no | list of string | The keys of the exchanges to list, and an exchange named here or in exchangeGroupIds is listed. | | `exchangeGroupIds` | query | no | list of string (uuid) | The IDs of the exchanges to list, and an exchange named here or in exchangeGroupKeys is listed. | | `statuses` | query | no | list of [ExchangeGroupStatus](schemas.md#exchangegroupstatus) | The statuses to list, as the exchange's status field spells them. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupListing](schemas.md#exchangegrouplisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create exchange group `POST https://api.hardfin.com/v2/exchange-group` Operation `exchangeGroupCreateExchangeGroup`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `fulfillmentOrder` | [FulfillmentCreate](schemas.md#fulfillmentcreate) | yes | The fulfillment order to create, from the organization's site to the customer's. | | `fulfillmentOrder.contactId` | string (uuid), or null | no | The ID of the contact the order is for, or null. | | `fulfillmentOrder.fileIds` | list of string (uuid), or null | no | The IDs of uploaded files to attach to the order, or null. | | `fulfillmentOrder.fromLocationId` | string (uuid) | yes | The ID of the location the order ships from. | | `fulfillmentOrder.items` | list of [FulfillmentItem](schemas.md#fulfillmentitem) | yes | The order's line items, from 1 to 50. | | `fulfillmentOrder.orderNotes` | string, or null | no | A note about the order, or null. | | `fulfillmentOrder.projectId` | string (uuid), or null | no | The ID of the project the order fills, or null when it fills none. Naming a project does not assign the order's assets to it, and assets are assigned to a project in the Hardfin app. | | `fulfillmentOrder.promiseDeliveryDate` | string (date), or null | no | The day the order is promised to arrive, or null. | | `fulfillmentOrder.promiseShipDate` | string (date), or null | no | The day the order is promised to ship, or null. | | `fulfillmentOrder.toLocationId` | string (uuid) | yes | The ID of the location the order ships to, which must differ from fromLocationId. | | `returnOrder` | [ReturnOrderCreate](schemas.md#returnordercreate) | yes | The return order to create, from the customer's site to the organization's. | | `returnOrder.fromLocationId` | string (uuid) | yes | The ID of the location the items are returned from. | | `returnOrder.items` | list of [ReturnOrderItem](schemas.md#returnorderitem) | yes | The order's lines, from 1 to 50 of them, each naming a different item. | | `returnOrder.orderNotes` | string, or null | no | A note about the order, where blank text is stored as null. | | `returnOrder.promiseDeliveryDate` | string (date), or null | no | The day the items are promised to arrive. | | `returnOrder.promiseShipDate` | string (date), or null | no | The day the items are promised to ship. | | `returnOrder.returnReason` | string, or null | no | A description of why the items are coming back, which is required when returnType is OTHER. | | `returnOrder.returnType` | [ReturnOrderType](schemas.md#returnordertype) | yes | Why the items are coming back. | | `returnOrder.toLocationId` | string (uuid) | yes | The ID of the location the items are returned to, which must differ from fromLocationId. | | `returnOrder.transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the items are returned with and its transport reference, or null when none of them is set. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupDetailedExchangeGroup](schemas.md#exchangegroupdetailedexchangegroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get exchange group `GET https://api.hardfin.com/v2/exchange-group/{exchangeGroupKey}` Operation `exchangeGroupGetExchangeGroup`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `exchangeGroupKey` | path | yes | string | The exchange's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupDetailedExchangeGroup](schemas.md#exchangegroupdetailedexchangegroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Attach exchange group fulfillment order `POST https://api.hardfin.com/v2/exchange-group/{exchangeGroupKey}/fulfillment/{fulfillmentKey}` Operation `exchangeGroupAttachExchangeGroupFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `exchangeGroupKey` | path | yes | string | The exchange's key. | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupDetailedExchangeGroup](schemas.md#exchangegroupdetailedexchangegroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Detach exchange group fulfillment order `DELETE https://api.hardfin.com/v2/exchange-group/{exchangeGroupKey}/fulfillment/{fulfillmentKey}` Operation `exchangeGroupDetachExchangeGroupFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `exchangeGroupKey` | path | yes | string | The exchange's key. | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupDetailedExchangeGroup](schemas.md#exchangegroupdetailedexchangegroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Attach exchange group return order `POST https://api.hardfin.com/v2/exchange-group/{exchangeGroupKey}/return-order/{returnOrderKey}` Operation `exchangeGroupAttachExchangeGroupReturnOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `exchangeGroupKey` | path | yes | string | The exchange's key. | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupDetailedExchangeGroup](schemas.md#exchangegroupdetailedexchangegroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Detach exchange group return order `DELETE https://api.hardfin.com/v2/exchange-group/{exchangeGroupKey}/return-order/{returnOrderKey}` Operation `exchangeGroupDetachExchangeGroupReturnOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `exchangeGroupKey` | path | yes | string | The exchange's key. | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ExchangeGroupDetailedExchangeGroup](schemas.md#exchangegroupdetailedexchangegroup) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # File operations ## Upload file `POST https://api.hardfin.com/v2/file` Operation `fileUploadFile`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | `LOGO` added to `fileType` in the request | | 2026-10-26 | `ICON` added to `fileType` in the request | | 2026-10-26 | `forEntity` in the request is no longer required | | 2026-09-17 | Endpoint added | ### Request body Sent as `multipart/form-data`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `data` | string (binary) | yes | The file's content, sent as the upload's only file part, named data, with its file name and media type. | | `fileType` | one of `ASSET_FILE`, `PURCHASE_ORDER_FILE`, `RETURN_ORDER_FILE`, `LOGO`, `ICON` | yes | The kind of file uploaded, ASSET_FILE for an asset, PURCHASE_ORDER_FILE for a purchase order, RETURN_ORDER_FILE for a return order, LOGO for the organization's full logo or ICON for its square icon, the only kinds the API uploads. A LOGO or an ICON replaces the organization's current one. | | `forEntity` | string (uuid) | no | The ID of the asset, purchase order or return order the file is attached to, which fileType names the kind of. It is required for those kinds and refused for a LOGO or an ICON. | | `isPublic` | boolean | no | Whether any organization's API key may download the file, sent as true or false in any case, and false when left out. A LOGO or an ICON is always public. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FileNewUpload](schemas.md#filenewupload) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get file `GET https://api.hardfin.com/v2/file/{fileKey}` Operation `fileGetFile`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fileKey` | path | yes | string | The file's key, and a public file is readable with any organization's API key while any other file is readable only with its own organization's. | | `attachment` | query | no | boolean, or null | True when the file downloads as an attachment rather than opening inline. | | `If-None-Match` | header | no | string | The ETag of a copy already held, which answers 304 when the file still has it. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded, and the body is the file's bytes, sent under the file's own media type. | | | 304 | The file still has the ETag If-None-Match sent. The response has no body. | | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing, is not valid, or belongs to an organization that does not own the private file. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Fulfillment operations ## List fulfillment orders `GET https://api.hardfin.com/v2/fulfillment` Operation `fulfillmentListFulfillmentOrders`, which needs the `hardfin:read` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `fulfillmentOrderNumber`, `status`, `promiseShipDate`, `promiseDeliveryDate`, `cycleTime` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `search` | query | no | string | Text to find in the order's number, its status, its locations' names, or its items' names and SKUs. | | `fulfillmentOrderKeys` | query | no | list of string | The keys of the fulfillment orders to list, and an order named here or in fulfillmentOrderIds is listed. | | `fulfillmentOrderIds` | query | no | list of string (uuid) | The IDs of the fulfillment orders to list, and an order named here or in fulfillmentOrderKeys is listed. | | `projectIds` | query | no | list of string (uuid) | The IDs of projects, and orders for one of them are listed. | | `statuses` | query | no | list of [FulfillmentOrderStatus](schemas.md#fulfillmentorderstatus) | The statuses to list. | | `fromLocationIds` | query | no | list of string (uuid) | The IDs of locations, and orders shipping from one of them are listed, as are orders any other from filter matches. | | `toLocationIds` | query | no | list of string (uuid) | The IDs of locations, and orders shipping to one of them are listed, as are orders any other to filter matches. | | `fromCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and orders shipping from a location assigned to one of them are listed, as are orders any other from filter matches. | | `toCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and orders shipping to a location assigned to one of them are listed, as are orders any other to filter matches. | | `fromLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed orders ship from, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and an order any other from filter matches is listed too. | | `toLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed orders ship to, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and an order any other to filter matches is listed too. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentListing](schemas.md#fulfillmentlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create fulfillment order `POST https://api.hardfin.com/v2/fulfillment` Operation `fulfillmentCreateFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `contactId` | string (uuid), or null | no | The ID of the contact the order is for, or null. | | `fileIds` | list of string (uuid), or null | no | The IDs of uploaded files to attach to the order, or null. | | `fromLocationId` | string (uuid) | yes | The ID of the location the order ships from. | | `items` | list of [FulfillmentItem](schemas.md#fulfillmentitem) | yes | The order's line items, from 1 to 50. | | `orderNotes` | string, or null | no | A note about the order, or null. | | `projectId` | string (uuid), or null | no | The ID of the project the order fills, or null when it fills none. Naming a project does not assign the order's assets to it, and assets are assigned to a project in the Hardfin app. | | `promiseDeliveryDate` | string (date), or null | no | The day the order is promised to arrive, or null. | | `promiseShipDate` | string (date), or null | no | The day the order is promised to ship, or null. | | `toLocationId` | string (uuid) | yes | The ID of the location the order ships to, which must differ from fromLocationId. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get fulfillment order `GET https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}` Operation `fulfillmentGetFulfillmentOrder`, which needs the `hardfin:read` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update fulfillment order `PATCH https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}` Operation `fulfillmentUpdateFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `contactId` | string (uuid), or null | no | The ID of the contact the order is for, or null to clear it. | | `fromLocationId` | string (uuid), or null | no | The ID of the location the order ships from, which cannot be cleared. | | `items` | list of [FulfillmentItem](schemas.md#fulfillmentitem), or null | no | The order's full set of line items, from 1 to 50, replacing the lines it had. | | `orderNotes` | string, or null | no | A note about the order, or null to clear it, and the one field an order that left draft accepts when sent alone, unless it ships from a 3PL location. | | `projectId` | string (uuid), or null | no | The ID of the project the order fills, or null to fill none. Naming a project does not assign the order's assets to it, and assets are assigned to a project in the Hardfin app. | | `promiseDeliveryDate` | string (date), or null | no | The day the order is promised to arrive, or null to clear it. | | `promiseShipDate` | string (date), or null | no | The day the order is promised to ship, or null to clear it. | | `toLocationId` | string (uuid), or null | no | The ID of the location the order ships to, which cannot be cleared and must differ from the order's origin. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Cancel fulfillment order `POST https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/cancel` Operation `fulfillmentCancelFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string | yes | Why the order is cancelled. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Close fulfillment order `POST https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/close` Operation `fulfillmentCloseFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get fulfillment order files `GET https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/file` Operation `fulfillmentGetFulfillmentOrderFiles`, which needs the `hardfin:read` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [File](schemas.md#file) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Unlink fulfillment order file `DELETE https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/file/{fileKey}` Operation `fulfillmentUnlinkFulfillmentOrderFile`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | | `fileKey` | path | yes | string | The key of the file to detach. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Resync fulfillment order `POST https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/resync` Operation `fulfillmentResyncFulfillmentOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Send fulfillment order to 3PL `POST https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/send-to-3pl` Operation `fulfillmentSendFulfillmentOrderTo3PL`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [FulfillmentOrder](schemas.md#fulfillmentorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get fulfillment order URL links `GET https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/url-link` Operation `fulfillmentGetFulfillmentOrderURLLinks`, which needs the `hardfin:read` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Create fulfillment order URL link `POST https://api.hardfin.com/v2/fulfillment/{fulfillmentKey}/url-link` Operation `fulfillmentCreateFulfillmentOrderURLLink`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `fulfillmentKey` | path | yes | string | The fulfillment order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string, or null | no | The link's display name, or null to show the address instead. | | `url` | string | yes | The address the link points to. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Inventory operations ## Get assemblies inventory `GET https://api.hardfin.com/v2/inventory/assemblies` Operation `inventoryGetAssembliesInventory`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `assetIds` | query | no | list of string (uuid) | The IDs of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as itemIds does, and an item named by either is returned. | | `itemIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as productIds does, and an item named by either is returned. | | `assetKeys` | query | no | list of string | The keys of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as itemKeys does, and an item named by either is returned. | | `itemKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as productKeys does, and an item named by either is returned. | | `includeScrappedAssets` | query | no | boolean, or null | Whether asset groups count scrapped assets, under the SCRAPPED status. | | `includeArchivedProducts` | query | no | boolean, or null | Whether to return the asset groups and assemblies of archived items. Bulk items are returned either way. | | `excludeSerials` | query | no | boolean, or null | Whether to return asset groups without their serial numbers. | | `locationIds` | query | no | list of string (uuid) | The IDs of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `locationKeys` | query | no | list of string | The keys of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `includeNonInventory` | query | no | boolean, or null | Whether to count stock at locations that are not inventory locations. | | `includeInTransit` | query | no | boolean, or null | Whether to return asset groups on their way to inventory or to the field. Bulk items in transit are not returned. The location filters, includeNonInventory, and excludeArchivedLocations do not apply to these groups. | | `excludeArchivedLocations` | query | no | boolean, or null | Whether to leave out stock at archived locations. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [InventoryAssemblyInventoryResponse](schemas.md#inventoryassemblyinventoryresponse) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Get assets inventory `GET https://api.hardfin.com/v2/inventory/assets` Operation `inventoryGetAssetsInventory`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `assetIds` | query | no | list of string (uuid) | The IDs of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as itemIds does, and an item named by either is returned. | | `itemIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as productIds does, and an item named by either is returned. | | `assetKeys` | query | no | list of string | The keys of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as itemKeys does, and an item named by either is returned. | | `itemKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as productKeys does, and an item named by either is returned. | | `includeScrappedAssets` | query | no | boolean, or null | Whether asset groups count scrapped assets, under the SCRAPPED status. | | `includeArchivedProducts` | query | no | boolean, or null | Whether to return the asset groups and assemblies of archived items. Bulk items are returned either way. | | `excludeSerials` | query | no | boolean, or null | Whether to return asset groups without their serial numbers. | | `locationIds` | query | no | list of string (uuid) | The IDs of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `locationKeys` | query | no | list of string | The keys of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `includeNonInventory` | query | no | boolean, or null | Whether to count stock at locations that are not inventory locations. | | `includeInTransit` | query | no | boolean, or null | Whether to return asset groups on their way to inventory or to the field. Bulk items in transit are not returned. The location filters, includeNonInventory, and excludeArchivedLocations do not apply to these groups. | | `excludeArchivedLocations` | query | no | boolean, or null | Whether to leave out stock at archived locations. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [InventoryAssetsInventoryResponse](schemas.md#inventoryassetsinventoryresponse) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Get bulk items `GET https://api.hardfin.com/v2/inventory/bulk-items` Operation `inventoryGetBulkItems`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `assetIds` | query | no | list of string (uuid) | The IDs of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as itemIds does, and an item named by either is returned. | | `itemIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as productIds does, and an item named by either is returned. | | `assetKeys` | query | no | list of string | The keys of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as itemKeys does, and an item named by either is returned. | | `itemKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as productKeys does, and an item named by either is returned. | | `includeScrappedAssets` | query | no | boolean, or null | Whether asset groups count scrapped assets, under the SCRAPPED status. | | `includeArchivedProducts` | query | no | boolean, or null | Whether to return the asset groups and assemblies of archived items. Bulk items are returned either way. | | `excludeSerials` | query | no | boolean, or null | Whether to return asset groups without their serial numbers. | | `locationIds` | query | no | list of string (uuid) | The IDs of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `locationKeys` | query | no | list of string | The keys of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `includeNonInventory` | query | no | boolean, or null | Whether to count stock at locations that are not inventory locations. | | `includeInTransit` | query | no | boolean, or null | Whether to return asset groups on their way to inventory or to the field. Bulk items in transit are not returned. The location filters, includeNonInventory, and excludeArchivedLocations do not apply to these groups. | | `excludeArchivedLocations` | query | no | boolean, or null | Whether to leave out stock at archived locations. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [InventoryBulkItemInventoryResponse](schemas.md#inventorybulkiteminventoryresponse) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Get location grouped inventory `GET https://api.hardfin.com/v2/inventory/by-location/{type}` Operation `inventoryGetLocationGroupedInventory`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `type` | path | yes | one of `all`, `bulk-items`, `assets`, `assemblies` | The kind of inventory to return at each location. | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `assetIds` | query | no | list of string (uuid) | The IDs of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as itemIds does, and an item named by either is returned. | | `itemIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as productIds does, and an item named by either is returned. | | `assetKeys` | query | no | list of string | The keys of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as itemKeys does, and an item named by either is returned. | | `itemKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as productKeys does, and an item named by either is returned. | | `includeScrappedAssets` | query | no | boolean, or null | Whether asset groups count scrapped assets, under the SCRAPPED status. | | `includeArchivedProducts` | query | no | boolean, or null | Whether to return the asset groups and assemblies of archived items. Bulk items are returned either way. | | `excludeSerials` | query | no | boolean, or null | Whether to return asset groups without their serial numbers. | | `locationIds` | query | no | list of string (uuid) | The IDs of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `locationKeys` | query | no | list of string | The keys of the sites or zones whose stock to return. A row still names the site, and counts only the stock at the named locations. Asset groups in transit are returned whatever it names. | | `includeNonInventory` | query | no | boolean, or null | Whether to count stock at locations that are not inventory locations. | | `includeInTransit` | query | no | boolean, or null | Whether to return asset groups on their way to inventory or to the field. Bulk items in transit are not returned. The location filters, includeNonInventory, and excludeArchivedLocations do not apply to these groups. | | `excludeArchivedLocations` | query | no | boolean, or null | Whether to leave out stock at archived locations. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [InventoryLocationInventoryResponse](schemas.md#inventorylocationinventoryresponse) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Get location inventory `GET https://api.hardfin.com/v2/inventory/location/{locationKey}` Operation `inventoryGetLocationInventory`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `locationKey` | path | yes | string | The key of the site, whose own stock and zones to list, or of the one zone to list. | | `type` | query | no | one of `all`, `bulk-items`, `assets`, `assemblies` | The kind of inventory to return at each location. | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `assetIds` | query | no | list of string (uuid) | The IDs of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as itemIds does, and an item named by either is returned. | | `itemIds` | query | no | list of string (uuid) | The IDs of items whose inventory to return. It names items as productIds does, and an item named by either is returned. | | `assetKeys` | query | no | list of string | The keys of assets to count. With item or product filters, an asset named by any of them is counted. Bulk items and assemblies are returned whatever it names. | | `productKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as itemKeys does, and an item named by either is returned. | | `itemKeys` | query | no | list of string | The keys of items whose inventory to return. It names items as productKeys does, and an item named by either is returned. | | `includeScrappedAssets` | query | no | boolean, or null | Whether asset groups count scrapped assets, under the SCRAPPED status. | | `includeArchivedProducts` | query | no | boolean, or null | Whether to return the asset groups and assemblies of archived items. Bulk items are returned either way. | | `excludeSerials` | query | no | boolean, or null | Whether to return asset groups without their serial numbers. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [InventoryLocationInventoryResponse](schemas.md#inventorylocationinventoryresponse) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get inventory lot details `GET https://api.hardfin.com/v2/inventory/lots` Operation `inventoryGetInventoryLotDetails`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | query | yes | string | The key of the bulk item whose lots to return. | | `locationKey` | query | yes | string | The key of the site or zone that holds the lots. A site's key returns only the lots at the site itself, not those in its zones. | | `includeEmptyLots` | query | no | boolean | Whether to return lots with nothing left. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [InventoryLotsResponse](schemas.md#inventorylotsresponse) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update inventory `PUT https://api.hardfin.com/v2/location/{locationKey}/inventory` Operation `inventoryUpdateInventory`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `locationKey` | path | yes | string | The key of the site or zone whose stock to change. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `direction` | [InventoryAdjustmentDirection](schemas.md#inventoryadjustmentdirection) | yes | INCREASE to add stock or DECREASE to remove it. | | `itemId` | string (uuid) | yes | The ID of the bulk item whose stock to change. | | `note` | string, or null | no | Free text about the change. | | `quantity` | integer | yes | The number of units to add or remove, above 0 and 1,000,000,000 or less. A decrease cannot remove more than the location holds. | | `reason` | string | yes | Why the stock changed. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Item operations ## Get items `GET https://api.hardfin.com/v2/item` Operation `itemGetItems`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | `results.unitOfMeasure` added to the response | | 2026-10-14 | Request validation changed | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `type` | query | no | [FrontendItemType](schemas.md#frontenditemtype) | The item type to list, SERVICE, DEVICE, or BULK, or absent for every type. | | `search` | query | no | string, or null | Text to match against item names, SKUs, and descriptions, in any case. | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `name`, `sku`, `type`, `lastUpdatedAt` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived records, archived records, or all of them. | | `excludeLinkedIntegration` | query | no | [IntegrationID](schemas.md#integrationid), or null | QBO or NETSUITE, to leave out the items already linked to that integration. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ItemListing](schemas.md#itemlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create item `POST https://api.hardfin.com/v2/item` Operation `itemCreateItem`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | `unitOfMeasure` added to the response | | 2026-10-22 | Request validation changed | | 2026-09-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `acceptsBulkSerials` | boolean | no | Whether a BULK item records serial numbers on its units, which SERVICE and DEVICE items ignore. | | `description` | string, or null | no | A free-form description of the item. | | `name` | string | yes | The item's display name, unique within your organization in any case. | | `sku` | string | yes | The item's stock keeping unit, unique within your organization in any case. | | `type` | [FrontendItemType](schemas.md#frontenditemtype) | yes | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit a BULK item's quantities are counted in, required for a BULK item and ignored for SERVICE and DEVICE items. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Item](schemas.md#item) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get item `GET https://api.hardfin.com/v2/item/{itemKey}` Operation `itemGetItem`, which needs the `hardfin:read` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | `unitOfMeasure` added to the response | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `defaultPricing.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `defaultPricing.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | path | yes | string | The item's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ItemDetail](schemas.md#itemdetail) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update item `PATCH https://api.hardfin.com/v2/item/{itemKey}` Operation `itemUpdateItem`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | `unitOfMeasure` added to the response | | 2026-10-22 | Error codes or messages changed | | 2026-10-22 | Request validation changed | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `defaultPricing.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `defaultPricing.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | path | yes | string | The item's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `acceptsBulkSerials` | boolean, or null | no | Whether a BULK item records serial numbers on its units, read only beside type, and false when type is sent without it. | | `description` | string, or null | no | The item's new description, or null to clear it. | | `fields` | list of [ItemFieldOrderingUpdateItem](schemas.md#itemfieldorderingupdateitem) | no | New positions for a DEVICE item's fields. | | `isArchived` | boolean | no | Whether the item is archived, which cannot be null. | | `name` | string | no | The item's new display name, which cannot be empty and must be unique within your organization in any case. | | `sku` | string | no | The item's new stock keeping unit, which cannot be empty and must be unique within your organization in any case. | | `type` | [RequestedItemType](schemas.md#requesteditemtype), or null | no | The type to convert the item to, when the item's assets and inventory history allow the conversion. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ItemDetail](schemas.md#itemdetail) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Update item accounting `PATCH https://api.hardfin.com/v2/item/{itemKey}/accounting` Operation `itemUpdateItemAccounting`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | `unitOfMeasure` added to the response | | 2026-10-21 | `allocatedIndirect.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `EUR` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `GBP` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `USD` added to `allocatedIndirect.isoCode` in the request | | 2026-10-21 | `billOfMaterials.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `EUR` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `GBP` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `USD` added to `billOfMaterials.isoCode` in the request | | 2026-10-21 | `directLabor.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `directLabor.isoCode` in the request | | 2026-10-21 | `EUR` added to `directLabor.isoCode` in the request | | 2026-10-21 | `GBP` added to `directLabor.isoCode` in the request | | 2026-10-21 | `USD` added to `directLabor.isoCode` in the request | | 2026-10-21 | `freightInbound.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `EUR` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `GBP` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `USD` added to `freightInbound.isoCode` in the request | | 2026-10-21 | `freightOutbound.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `EUR` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `GBP` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `USD` added to `freightOutbound.isoCode` in the request | | 2026-10-21 | `installation.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `installation.isoCode` in the request | | 2026-10-21 | `EUR` added to `installation.isoCode` in the request | | 2026-10-21 | `GBP` added to `installation.isoCode` in the request | | 2026-10-21 | `USD` added to `installation.isoCode` in the request | | 2026-10-21 | `interest.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `interest.isoCode` in the request | | 2026-10-21 | `EUR` added to `interest.isoCode` in the request | | 2026-10-21 | `GBP` added to `interest.isoCode` in the request | | 2026-10-21 | `USD` added to `interest.isoCode` in the request | | 2026-10-21 | `salvageValue.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `EUR` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `GBP` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `USD` added to `salvageValue.isoCode` in the request | | 2026-10-21 | `simpleCostBasis.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `EUR` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `GBP` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `USD` added to `simpleCostBasis.isoCode` in the request | | 2026-10-21 | `tariffs.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `tariffs.isoCode` in the request | | 2026-10-21 | `EUR` added to `tariffs.isoCode` in the request | | 2026-10-21 | `GBP` added to `tariffs.isoCode` in the request | | 2026-10-21 | `USD` added to `tariffs.isoCode` in the request | | 2026-10-21 | `tax.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `tax.isoCode` in the request | | 2026-10-21 | `EUR` added to `tax.isoCode` in the request | | 2026-10-21 | `GBP` added to `tax.isoCode` in the request | | 2026-10-21 | `USD` added to `tax.isoCode` in the request | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `defaultPricing.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `defaultPricing.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-19 | Error codes or messages changed | | 2026-10-16 | `allocatedIndirect` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `billOfMaterials` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `costCurrencyCode` added to the request | | 2026-10-16 | `directLabor` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `freightInbound` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `freightOutbound` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `installation` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `interest` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `salvageValue` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `simpleCostBasis` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `tariffs` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `tax` in the request changed from `decimal or null` to `object or null` | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | path | yes | string | The item's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `allocatedIndirect` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | One unit's share of overhead, a cost component, and sending it clears simpleCostBasis. | | `billOfMaterials` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The parts cost of one unit, a cost component, and sending it clears simpleCostBasis. | | `costCurrencyCode` | [CurrencyCode](schemas.md#currencycode), or null | no | The ISO 4217 code every cost amount is denominated in, which must match the amounts sent and cannot be null. It is the only way to change the currency. A change keeps the held amounts and relabels them without conversion, and on an asset whose currency is locked it is refused. | | `depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The method one unit is depreciated by, or null to clear it. | | `directLabor` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The labor cost to build one unit, a cost component, and sending it clears simpleCostBasis. | | `freightInbound` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The shipping cost to receive one unit, a cost component, and sending it clears simpleCostBasis. | | `freightOutbound` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The shipping cost to deploy one unit, a deployment cost component, and sending it clears simpleCostBasis. | | `installation` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The cost to install one unit, a deployment cost component, and sending it clears simpleCostBasis. | | `interest` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The financing cost of one unit, a cost component, and sending it clears simpleCostBasis. | | `salvageValue` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The value one unit keeps at the end of its useful life, or null to clear it. | | `simpleCostBasis` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | A single cost for one unit, which clears the cost components and cannot be sent together with them. | | `tariffs` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The import duty paid on one unit, a cost component, and sending it clears simpleCostBasis. | | `tax` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The tax paid on one unit, a cost component, and sending it clears simpleCostBasis. | | `usefulLife` | integer, or null | no | The number of months one unit is depreciated over, from 1 to 480, or null to clear it. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ItemDetail](schemas.md#itemdetail) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Create item field `POST https://api.hardfin.com/v2/item/{itemKey}/field` Operation `itemCreateItemField`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | `unitOfMeasure` added to the response | | 2026-10-22 | Request validation changed | | 2026-10-21 | `accounting.allocatedIndirect` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.billOfMaterials` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.directLabor` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightInbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.freightOutbound` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.installation` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.interest` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.salvageValue` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.simpleCostBasis` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tariffs` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.tax` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `accounting.totalCOGS` in the response changed from `decimal or null` to `object or null` | | 2026-10-21 | `defaultPricing.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.fixedPrice.isoCode` in the response | | 2026-10-21 | `defaultPricing.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `defaultPricing.unitPrice.isoCode` in the response | | 2026-10-16 | `accounting.costCurrencyCode` added to the response | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | path | yes | string | The item's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `fieldType` | [ItemFieldType](schemas.md#itemfieldtype) | yes | The kind of value the field holds. | | `label` | string | yes | The field's display name, unique within its item. | | `order` | integer, or null | yes | The field's position within its section, starting at 0. | | `section` | integer, or null | yes | The group the field is shown in, starting at 0. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ItemDetail](schemas.md#itemdetail) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Update item field `PATCH https://api.hardfin.com/v2/item/{itemKey}/field/{fieldKey}` Operation `itemUpdateItemField`, which needs the `hardfin:write` scope. Last changed on 2026-10-12. | Date | Change | | --- | --- | | 2026-10-12 | Error codes or messages changed | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | path | yes | string | The item's key. | | `fieldKey` | path | yes | string | The field's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `label` | string | no | The field's new display name, which cannot be empty and must be unique within its item. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ItemField](schemas.md#itemfield) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Delete item field `DELETE https://api.hardfin.com/v2/item/{itemKey}/field/{fieldKey}` Operation `itemDeleteItemField`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `itemKey` | path | yes | string | The item's key. | | `fieldKey` | path | yes | string | The field's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Location operations ## Get location listing `GET https://api.hardfin.com/v2/location` Operation `locationGetLocationListing`, which needs the `hardfin:read` scope. Last changed on 2026-10-14. | Date | Change | | --- | --- | | 2026-10-14 | Request validation changed | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `name`, `company`, `assetCount` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived records, archived records, or all of them. | | `isTransient` | query | no | [TransientState](schemas.md#transientstate) | Whether to return permanent locations (false), transient locations (true), or both (all). | | `search` | query | no | string, or null | Text to match against site, zone and customer names and site addresses, in any case. | | `forCustomerIds` | query | no | list of string | The IDs of the customers whose locations to return, where ORGANIZATION stands for your organization's own locations. | | `includeOrganization` | query | no | boolean | Whether the customer filter also matches your organization's own locations, which on its own returns only those. | | `syncStatuses` | query | no | list of one of `in-sync`, `out-of-sync`, `not-linked` | The integration sync statuses to return: in-sync, out-of-sync, or not-linked. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [LocationListing](schemas.md#locationlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create location `POST https://api.hardfin.com/v2/location` Operation `locationCreateLocation`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | Request validation changed | | 2026-10-12 | Error codes or messages changed | | 2026-09-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The site's structured address, which a zone refuses. | | `consignee` | string (uuid), or null | no | The ID of the customer a zone is designated for, such as for reservations, provisioning or a 3PL, which a site refuses. | | `customerId` | string (uuid), or null | no | The ID of the customer to assign a site to, or null for your organization's own site, which a zone refuses. | | `description` | string, or null | no | A free-form description of a zone, which a site refuses. | | `isInventory` | boolean | no | Whether assets at the location count as inventory for reporting, which a site passes to each of its zones without isInventoryOverride. | | `isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's, which a site refuses. | | `isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default, and which a zone refuses. | | `name` | string | yes | The location's display name, unique in any case among your organization's sites for the same customer or among a site's zones, and never shared by a site and its zones. | | `parentLocationId` | string (uuid), or null | no | The ID of the site a zone belongs to, required for a zone and refused for a site. | | `type` | [LocationType](schemas.md#locationtype) | yes | SITE for a site, or ZONE for a zone within a site. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Location](schemas.md#location) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get location `GET https://api.hardfin.com/v2/location/{locationKey}` Operation `locationGetLocation`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `locationKey` | path | yes | string | The location's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Location](schemas.md#location) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Patch location `PATCH https://api.hardfin.com/v2/location/{locationKey}` Operation `locationPatchLocation`, which needs the `hardfin:write` scope. Last changed on 2026-10-12. | Date | Change | | --- | --- | | 2026-10-12 | Error codes or messages changed | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `locationKey` | path | yes | string | The location's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The site's structured address, which a zone refuses. | | `consignee` | string (uuid), or null | no | The ID of the customer a zone is designated for, such as for reservations, provisioning or a 3PL, which a site refuses. | | `customerId` | string (uuid), or null | no | The ID of the customer to assign a site to, or null for your organization's own site, which a zone refuses. | | `description` | string, or null | no | A free-form description of a zone, which a site refuses. | | `isArchived` | boolean, or null | no | Whether the location is archived, and archiving or unarchiving a site does the same to all of its zones. | | `isInventory` | boolean, or null | no | Whether assets at the location count as inventory for reporting, which a site passes to each of its zones without isInventoryOverride. | | `isInventoryOverride` | boolean, or null | no | Whether a zone sets its own isInventory rather than inheriting its parent site's, which a site refuses, and which becomes true when a zone is sent isInventory without it. | | `isTransient` | boolean, or null | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default, and which a zone refuses. | | `name` | string | no | The location's display name, unique in any case among your organization's sites for the same customer or among a site's zones, never shared by a site and its zones, and taken from the address instead for a transient site with an address. | | `type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site, and must be the location's current type, since a type cannot be changed. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Location](schemas.md#location) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get zones `GET https://api.hardfin.com/v2/location/{locationKey}/zones` Operation `locationGetZones`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `locationKey` | path | yes | string | The key of the site whose zones to list. The location list returns sites only, so a site's zones are listed here, and a zone in this list names no parent because its parent is this site. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived zones, archived zones, or all of them. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [SparseLocation](schemas.md#sparselocation) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Metadata operations ## Get payment terms `GET https://api.hardfin.com/v2/meta/payment-terms` Operation `metadataGetPaymentTerms`, which needs the `hardfin:read` scope. Last changed on 2026-10-06. | Date | Change | | --- | --- | | 2026-10-06 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [PaymentTerm](schemas.md#paymentterm) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | --- # Note operations ## Get note `GET https://api.hardfin.com/v2/note/{noteKey}` Operation `noteGetNote`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `noteKey` | path | yes | string | The note's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Note](schemas.md#note) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update note `PATCH https://api.hardfin.com/v2/note/{noteKey}` Operation `noteUpdateNote`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `noteKey` | path | yes | string | The note's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `content` | string | yes | The note's new text, 1 to 2,000 characters. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Note](schemas.md#note) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Delete note `DELETE https://api.hardfin.com/v2/note/{noteKey}` Operation `noteDeleteNote`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `noteKey` | path | yes | string | The note's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Organization operations ## Get organization `GET https://api.hardfin.com/v2/organization` Operation `organizationGetOrganization`, which needs the `hardfin:read` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Organization](schemas.md#organization) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Patch organization `PATCH https://api.hardfin.com/v2/organization` Operation `organizationPatchOrganization`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `assetMarker` | string, or null | no | | | `billingAddress` | string, or null | no | The default bill-from address used for new invoices. | | `defaultCurrency` | [CurrencyCode](schemas.md#currencycode) | no | The organization's invoicing default currency. It cannot be cleared. | | `defaultInvoiceMemo` | string, or null | no | The default customer-facing memo copied onto new invoices. | | `defaultOriginLocationId` | string (uuid), or null | no | The organization's default origin location, used as a fallback when new flows (such as fulfillment orders) need an origin. May be set to null to clear the default. | | `defaultPaymentInstructions` | string, or null | no | The default remittance text copied onto new invoices. | | `defaultPaymentTerm` | string, or null | no | The fallback payment term used for invoices when the project has none, named by the ID or the label the payment term list returns. | | `defaultReceiveLocationId` | string (uuid), or null | no | The organization's default receive location, used as a fallback when new purchase orders need a destination. May be set to null to clear the default. | | `defaultReturnLocationId` | string (uuid), or null | no | The organization's default return location, used as a fallback when new return orders need a destination. May be set to null to clear the default. | | `invoiceNumberPrefix` | string, or null | no | The prefix used for future auto-generated invoice numbers. | | `name` | string | no | The new display name for the organization. If set, it cannot be empty. | | `serialPatterns` | list of [SerialPatternSpec](schemas.md#serialpatternspec), or null | no | | | `timezone` | string | no | The new timezone for the organization. If set, it must be a valid IANA timezone identifier. | | `weightedAverageCostOfCapital` | string (decimal) | no | The weighted average cost of capital used by the billing-lifecycle carrying-cost calculation. Expressed as a decimal in [0.01, 1.00] (1% .. 100%). It cannot be cleared. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Organization](schemas.md#organization) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get organization ledger accounts `GET https://api.hardfin.com/v2/organization/accounting` Operation `organizationGetOrganizationLedgerAccounts`, which needs the `hardfin:read` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [OrganizationLedgerAccounts](schemas.md#organizationledgeraccounts) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Update organization ledger accounts `PATCH https://api.hardfin.com/v2/organization/accounting` Operation `organizationUpdateOrganizationLedgerAccounts`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `ledgerAccounts` | object | yes | | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get attention thresholds `GET https://api.hardfin.com/v2/organization/attention-thresholds` Operation `organizationGetAttentionThresholds`, which needs the `hardfin:read` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [OrganizationAttentionThresholds](schemas.md#organizationattentionthresholds) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Update attention thresholds `PUT https://api.hardfin.com/v2/organization/attention-thresholds` Operation `organizationUpdateAttentionThresholds`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `thresholds` | list of [OrganizationAttentionThresholdEntry](schemas.md#organizationattentionthresholdentry) | yes | The organization's full override set, which is required and never null. A reason left out returns to its default, and an empty set clears every override. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [OrganizationAttentionThresholds](schemas.md#organizationattentionthresholds) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get external users `GET https://api.hardfin.com/v2/organization/external-user` Operation `organizationGetExternalUsers`, which needs the `hardfin:read` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [OrganizationExternalUser](schemas.md#organizationexternaluser) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create external user `POST https://api.hardfin.com/v2/organization/external-user` Operation `organizationCreateExternalUser`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string | yes | The email address of the external user | | `firstName` | string, or null | no | | | `label` | string | yes | A descriptive label for the external user | | `lastName` | string, or null | no | | | `notifications` | [NotificationUpdate](schemas.md#notificationupdate) | no | | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [OrganizationExternalUser](schemas.md#organizationexternaluser) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get external user `GET https://api.hardfin.com/v2/organization/external-user/{externalUserKey}` Operation `organizationGetExternalUser`, which needs the `hardfin:read` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `externalUserKey` | path | yes | string | The external user's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [OrganizationExternalUser](schemas.md#organizationexternaluser) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update external user `PATCH https://api.hardfin.com/v2/organization/external-user/{externalUserKey}` Operation `organizationUpdateExternalUser`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `externalUserKey` | path | yes | string | The external user's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string, or null | no | The updated email address of the external user | | `label` | string, or null | no | The updated descriptive label for the external user | | `notifications` | [NotificationUpdate](schemas.md#notificationupdate), or null | no | | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [OrganizationExternalUser](schemas.md#organizationexternaluser) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Delete external user `DELETE https://api.hardfin.com/v2/organization/external-user/{externalUserKey}` Operation `organizationDeleteExternalUser`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `externalUserKey` | path | yes | string | The external user's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get organization members `GET https://api.hardfin.com/v2/organization/user` Operation `organizationGetOrganizationMembers`, which needs the `hardfin:read` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [PersonOrganizationMember](schemas.md#personorganizationmember) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Update member `PATCH https://api.hardfin.com/v2/organization/user/{userKey}` Operation `organizationUpdateMember`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `userKey` | path | yes | string | The member's user key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `defaultRate` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The new default rate for the member. Can be set to null to clear the rate. | | `firstName` | string, or null | no | The new first name for the member. | | `lastName` | string, or null | no | The new last name for the member. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PersonOrganizationMember](schemas.md#personorganizationmember) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Activate member `POST https://api.hardfin.com/v2/organization/user/{userKey}/activate` Operation `organizationActivateMember`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `userKey` | path | yes | string | The member's user key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Deactivate member `POST https://api.hardfin.com/v2/organization/user/{userKey}/deactivate` Operation `organizationDeactivateMember`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `userKey` | path | yes | string | The member's user key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Demote member from admin `POST https://api.hardfin.com/v2/organization/user/{userKey}/demote` Operation `organizationDemoteMemberFromAdmin`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `userKey` | path | yes | string | The member's user key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Promote member to admin `POST https://api.hardfin.com/v2/organization/user/{userKey}/promote` Operation `organizationPromoteMemberToAdmin`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `userKey` | path | yes | string | The member's user key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Project operations ## Get projects `GET https://api.hardfin.com/v2/project` Operation `projectGetProjects`, which needs the `hardfin:read` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `results.discount.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.discount.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.discount.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.discount.isoCode` in the response | | 2026-10-21 | `USD` added to `results.discount.isoCode` in the response | | 2026-10-21 | `results.items.charges.totalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `results.items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `results.items.charges.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `results.items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `results.items.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.items.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.items.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.items.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `results.items.fixedPrice.isoCode` in the response | | 2026-10-21 | `results.items.totalOverride.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.items.totalOverride.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.items.totalOverride.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.items.totalOverride.isoCode` in the response | | 2026-10-21 | `USD` added to `results.items.totalOverride.isoCode` in the response | | 2026-10-21 | `results.items.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.items.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.items.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.items.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `results.items.unitPrice.isoCode` in the response | | 2026-10-21 | `results.totalContractValue.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `results.totalContractValue.isoCode` in the response | | 2026-10-21 | `EUR` added to `results.totalContractValue.isoCode` in the response | | 2026-10-21 | `GBP` added to `results.totalContractValue.isoCode` in the response | | 2026-10-21 | `USD` added to `results.totalContractValue.isoCode` in the response | | 2026-10-16 | `CAD` added to `results.annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `EUR` added to `results.annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `GBP` added to `results.annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `USD` added to `results.annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `CAD` added to `results.currency.isoCode` in the response | | 2026-10-16 | `EUR` added to `results.currency.isoCode` in the response | | 2026-10-16 | `GBP` added to `results.currency.isoCode` in the response | | 2026-10-16 | `USD` added to `results.currency.isoCode` in the response | | 2026-10-16 | `results.items.charges.actualBillableAt` added to the response | | 2026-10-16 | `results.items.charges.cancellationReason` added to the response | | 2026-10-16 | `results.items.charges.cancelledAt` added to the response | | 2026-10-14 | Request validation changed | | 2026-10-09 | `results.items.charges` added to the response | | 2026-10-09 | `results.items.hasInvoicedCharges` added to the response | | 2026-10-08 | `ACTIVE` added to `results.previousProject.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `results.previousProject.status` in the response | | 2026-10-08 | `PAST` added to `results.previousProject.status` in the response | | 2026-10-08 | `UPCOMING` added to `results.previousProject.status` in the response | | 2026-10-08 | `ACTIVE` added to `results.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `results.status` in the response | | 2026-10-08 | `PAST` added to `results.status` in the response | | 2026-10-08 | `UPCOMING` added to `results.status` in the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `name`, `startOn`, `endOn`, `workflow` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `archived` | query | no | [ArchivedState](schemas.md#archivedstate) | Whether to return unarchived records, archived records, or all of them. | | `search` | query | no | string, or null | Text of three or more characters, with shorter text ignored, to find in the project's name or description, its customer's name, its line items' locations, the names of the asset-carrying items its line items ask for, or the items of the assets it holds. | | `customerIds` | query | no | list of string (uuid) | The IDs of the customers whose projects to list. | | `itemIds` | query | no | list of string (uuid) | The IDs of the items whose projects to list, which are the projects with a line item for the item when it carries assets, or holding one of its assets. | | `projectIds` | query | no | list of string (uuid) | The IDs of the projects to list. | | `locationIds` | query | no | list of string (uuid) | The IDs of the locations whose projects to list, which are the projects with a line item at the location or with it as their default location. | | `statuses` | query | no | list of [ProjectStatusFilter](schemas.md#projectstatusfilter) | The statuses to list: UPCOMING, ACTIVE, PAST, or DATE_RANGE_INCOMPLETE for a project missing a start or an end. | | `startBy` | query | no | string (date) | A day, and only projects that start on or before it are listed. | | `endBy` | query | no | string (date) | A day, and only projects that end on or before it are listed. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ProjectListing](schemas.md#projectlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create project `POST https://api.hardfin.com/v2/project` Operation `projectCreateProject`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-21 | `lineItems.fixedPrice.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `EUR` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `GBP` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `USD` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `lineItems.totalOverride.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `EUR` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `GBP` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `USD` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `lineItems.unitPrice.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `EUR` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `GBP` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `USD` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `totalContractValue.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `EUR` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `GBP` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `USD` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `discount.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `discount.isoCode` in the response | | 2026-10-21 | `EUR` added to `discount.isoCode` in the response | | 2026-10-21 | `GBP` added to `discount.isoCode` in the response | | 2026-10-21 | `USD` added to `discount.isoCode` in the response | | 2026-10-21 | `items.charges.totalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `items.charges.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `items.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `items.totalOverride.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `USD` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `items.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `totalContractValue.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `EUR` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `GBP` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `USD` added to `totalContractValue.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-16 | `CAD` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `EUR` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `GBP` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `USD` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `CAD` added to `currency.isoCode` in the response | | 2026-10-16 | `EUR` added to `currency.isoCode` in the response | | 2026-10-16 | `GBP` added to `currency.isoCode` in the response | | 2026-10-16 | `USD` added to `currency.isoCode` in the response | | 2026-10-16 | `items.charges.actualBillableAt` added to the response | | 2026-10-16 | `items.charges.cancellationReason` added to the response | | 2026-10-16 | `items.charges.cancelledAt` added to the response | | 2026-10-12 | Error codes or messages changed | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `contractSignedOn` | string (date), or null | no | The day the contract was signed. | | `customerId` | string (uuid), or null | no | The ID of the customer the project is for. | | `defaultLocationId` | string (uuid), or null | no | The ID of the project's default location. | | `description` | string, or null | no | The project's description. | | `endOn` | string (date), or null | no | The day the project ends. | | `fileIds` | list of string (uuid), or null | no | The IDs of uploaded files to attach to the project. | | `inheritPreviousLineItems` | boolean, or null | no | Whether to copy the line items of the project this one renews, which applies only when previousProjectId is sent. | | `initialWorkflowStageId` | string (uuid), or null | no | The ID of the workflow stage the project starts on, which defaults to the workflow's first stage. | | `installDate` | string (date), or null | no | The day of the installation. | | `lineItems` | list of [ProjectItemBinding](schemas.md#projectitembinding), or null | no | The project's line items, each an item the project sells or provides as a service. | | `name` | string | yes | The project's name, which no other project in the organization may share, ignoring case. | | `previousProjectId` | string (uuid), or null | no | The ID of the project this one renews. | | `startOn` | string (date), or null | no | The day the project starts. | | `totalContractValue` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The contract's total value. | | `workflowId` | string (uuid), or null | no | The ID of the workflow to put the project on. A project created without one has no workflow. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Project](schemas.md#project) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get project `GET https://api.hardfin.com/v2/project/{projectKey}` Operation `projectGetProject`, which needs the `hardfin:read` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | `discount.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `discount.isoCode` in the response | | 2026-10-21 | `EUR` added to `discount.isoCode` in the response | | 2026-10-21 | `GBP` added to `discount.isoCode` in the response | | 2026-10-21 | `USD` added to `discount.isoCode` in the response | | 2026-10-21 | `items.charges.totalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `items.charges.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `items.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `items.totalOverride.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `USD` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `items.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `totalContractValue.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `EUR` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `GBP` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `USD` added to `totalContractValue.isoCode` in the response | | 2026-10-16 | `CAD` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `EUR` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `GBP` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `USD` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `CAD` added to `currency.isoCode` in the response | | 2026-10-16 | `EUR` added to `currency.isoCode` in the response | | 2026-10-16 | `GBP` added to `currency.isoCode` in the response | | 2026-10-16 | `USD` added to `currency.isoCode` in the response | | 2026-10-16 | `items.charges.actualBillableAt` added to the response | | 2026-10-16 | `items.charges.cancellationReason` added to the response | | 2026-10-16 | `items.charges.cancelledAt` added to the response | | 2026-10-09 | `items.charges` added to the response | | 2026-10-09 | `items.hasInvoicedCharges` added to the response | | 2026-10-08 | `ACTIVE` added to `previousProject.status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `previousProject.status` in the response | | 2026-10-08 | `PAST` added to `previousProject.status` in the response | | 2026-10-08 | `UPCOMING` added to `previousProject.status` in the response | | 2026-10-08 | `ACTIVE` added to `status` in the response | | 2026-10-08 | `DATE_RANGE_INCOMPLETE` added to `status` in the response | | 2026-10-08 | `PAST` added to `status` in the response | | 2026-10-08 | `UPCOMING` added to `status` in the response | | 2026-10-06 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `projectKey` | path | yes | string | The project's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Project](schemas.md#project) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Patch project `PATCH https://api.hardfin.com/v2/project/{projectKey}` Operation `projectPatchProject`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-21 | `discount.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `discount.isoCode` in the request | | 2026-10-21 | `EUR` added to `discount.isoCode` in the request | | 2026-10-21 | `GBP` added to `discount.isoCode` in the request | | 2026-10-21 | `USD` added to `discount.isoCode` in the request | | 2026-10-21 | `lineItems.fixedPrice.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `EUR` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `GBP` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `USD` added to `lineItems.fixedPrice.isoCode` in the request | | 2026-10-21 | `lineItems.totalOverride.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `EUR` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `GBP` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `USD` added to `lineItems.totalOverride.isoCode` in the request | | 2026-10-21 | `lineItems.unitPrice.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `EUR` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `GBP` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `USD` added to `lineItems.unitPrice.isoCode` in the request | | 2026-10-21 | `totalContractValue.amount` in the request changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `EUR` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `GBP` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `USD` added to `totalContractValue.isoCode` in the request | | 2026-10-21 | `discount.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `discount.isoCode` in the response | | 2026-10-21 | `EUR` added to `discount.isoCode` in the response | | 2026-10-21 | `GBP` added to `discount.isoCode` in the response | | 2026-10-21 | `USD` added to `discount.isoCode` in the response | | 2026-10-21 | `items.charges.totalPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.charges.totalPrice.isoCode` in the response | | 2026-10-21 | `items.charges.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.charges.unitPrice.isoCode` in the response | | 2026-10-21 | `items.fixedPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.fixedPrice.isoCode` in the response | | 2026-10-21 | `items.totalOverride.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `USD` added to `items.totalOverride.isoCode` in the response | | 2026-10-21 | `items.unitPrice.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `EUR` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `GBP` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `USD` added to `items.unitPrice.isoCode` in the response | | 2026-10-21 | `totalContractValue.amount` in the response changed from `string` to `decimal` | | 2026-10-21 | `CAD` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `EUR` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `GBP` added to `totalContractValue.isoCode` in the response | | 2026-10-21 | `USD` added to `totalContractValue.isoCode` in the response | | 2026-10-19 | Request validation changed | | 2026-10-16 | `CAD` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `EUR` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `GBP` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `USD` added to `annualRecurringRevenue.isoCode` in the response | | 2026-10-16 | `CAD` added to `currency.isoCode` in the response | | 2026-10-16 | `EUR` added to `currency.isoCode` in the response | | 2026-10-16 | `GBP` added to `currency.isoCode` in the response | | 2026-10-16 | `USD` added to `currency.isoCode` in the response | | 2026-10-16 | `items.charges.actualBillableAt` added to the response | | 2026-10-16 | `items.charges.cancellationReason` added to the response | | 2026-10-16 | `items.charges.cancelledAt` added to the response | | 2026-10-12 | Error codes or messages changed | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `projectKey` | path | yes | string | The project's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `acceptanceDate` | string (date), or null | no | The day the customer accepted the project. | | `billingAddress` | string, or null | no | The billing address the project's invoices use in place of the customer's. | | `billingContactEmail` | string, or null | no | The billing contact email the project's invoices use in place of the customer's. | | `billingContactName` | string, or null | no | The billing contact name the project's invoices use in place of the customer's. | | `billingContactPhone` | string, or null | no | The billing contact phone number the project's invoices use in place of the customer's. | | `contractSignedOn` | string (date), or null | no | The day the contract was signed. | | `customerId` | string (uuid), or null | no | The ID of the customer the project is for. | | `defaultLocationId` | string (uuid), or null | no | The ID of the project's default location. | | `description` | string, or null | no | The project's description. | | `discount` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The discount applied to the project. | | `endOn` | string (date), or null | no | The day the project ends. | | `goLiveDate` | string (date), or null | no | The day the project goes live. | | `installDate` | string (date), or null | no | The day of the installation. | | `isArchived` | boolean, or null | no | Whether the project is archived. | | `lineItems` | list of [ProjectItemBinding](schemas.md#projectitembinding), or null | no | The project's line items. The list sent replaces the project's line items. | | `memo` | string, or null | no | The memo new invoices for the project carry. | | `name` | string, or null | no | The project's new name, which no other project in the organization may share, ignoring case. | | `paymentTerm` | string, or null | no | The project's payment term, named by the ID or the label the payment term list returns. | | `previousProjectId` | string (uuid), or null | no | The ID of the project this one renews. | | `purchaseOrderNumber` | string, or null | no | The customer's purchase order number, which new invoices for the project carry. | | `siteVisitDate` | string (date), or null | no | The day of the site visit. | | `startOn` | string (date), or null | no | The day the project starts. | | `totalContractValue` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The contract's total value. | | `trainingDate` | string (date), or null | no | The day of the training. | | `workflowId` | string (uuid), or null | no | The ID of the workflow to put the project on. | | `workflowStageId` | string (uuid), or null | no | The ID of the workflow stage to move the project to, which has to belong to the project's workflow. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Project](schemas.md#project) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Patch project line item `PATCH https://api.hardfin.com/v2/project/{projectKey}/line-item/{lineItemKey}` Operation `projectPatchProjectLineItem`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | Error codes or messages changed | | 2026-10-19 | Request validation changed | | 2026-10-16 | Request validation changed | | 2026-10-16 | `charges.actualBillableAt` added to the response | | 2026-10-16 | `charges.cancellationReason` added to the response | | 2026-10-16 | `charges.cancelledAt` added to the response | | 2026-10-12 | `generate` added to the request | | 2026-10-12 | Request validation changed | | 2026-10-12 | Error codes or messages changed | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `projectKey` | path | yes | string | The key of the project the line item belongs to. | | `lineItemKey` | path | yes | string | The key of the line item to update. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `activationDate` | string (date), or null | no | The day a periodic line item's charge schedule is anchored on, from 1970-01-01 through 2099-12-31. | | `billingFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | The line item's single billing cadence. | | `chargeFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a periodic line item creates a charge, and is refused unless chargeSchedule is PERIODIC. | | `chargeMode` | [ChargeMode](schemas.md#chargemode), or null | no | CONFIRMED when activationDate is sent, or PENDING when it is null, and a MILESTONE line item is CONFIRMED with no activationDate. | | `chargeSchedule` | [BillingSchedule](schemas.md#billingschedule), or null | no | PERIODIC when charges recur at a regular frequency, or MILESTONE when each charge follows a project milestone. | | `charges` | list of [ProjectChargeRequestItem](schemas.md#projectchargerequestitem), or null | no | The line item's whole charge list, which replaces the charges it has, or omitted to leave them as they are. An INVOICED charge must stay in the list, because leaving it out is refused, and keeps its stored values whatever the list sends. | | `details` | string, or null | no | A free-form note about the line item, 65,536 characters or less. | | `fixedPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The flat price when pricingMode is FIXED, and is not sent together with unitPrice. | | `generate` | boolean | no | True to replace the line item's charges with the schedule its billing plan produces, and is not sent together with charges. A periodic plan needs its dates and its cadence, and generation is refused once a charge is INVOICED. | | `invoiceFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a periodic line item's charges are invoiced, which is never more often than chargeFrequency. | | `invoiceMode` | [BillingTiming](schemas.md#billingtiming), or null | no | ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends, and is refused unless chargeSchedule is PERIODIC. | | `itemId` | string (uuid), or null | no | The catalog item the line item is for. | | `locationId` | string (uuid), or null | no | The location the line item is for. | | `milestonePhases` | [MetadataMilestonePhases](schemas.md#metadatamilestonephases), or null | no | The named phases of a milestone line item and each one's share of its total. | | `pricingMode` | [PricingMode](schemas.md#pricingmode), or null | no | PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price whatever the quantity. | | `quantity` | integer, or null | no | The number of units the line item covers, which is zero or more and 100,000,000 or less. | | `totalOverride` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | A negotiated total for a periodic line item that replaces the computed one, in the project's currency. | | `transactionType` | [TransactionType](schemas.md#transactiontype), or null | no | SALE to sell the item, which only a physical item allows, or SERVICE to provide it as a service. | | `unitPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The price of one unit for each charge, and is not sent together with fixedPrice. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ProjectLineItem](schemas.md#projectlineitem) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get project line item charges `GET https://api.hardfin.com/v2/project/{projectKey}/line-item/{lineItemKey}/charges` Operation `projectGetProjectLineItemCharges`, which needs the `hardfin:read` scope. Last changed on 2026-10-16. | Date | Change | | --- | --- | | 2026-10-16 | `actualBillableAt` added to the response | | 2026-10-16 | `cancellationReason` added to the response | | 2026-10-16 | `cancelledAt` added to the response | | 2026-10-09 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `projectKey` | path | yes | string | The key of the project the line item belongs to. | | `lineItemKey` | path | yes | string | The key of the line item whose charges to return. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [Charge](schemas.md#charge) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get project notes `GET https://api.hardfin.com/v2/project/{projectKey}/note` Operation `projectGetProjectNotes`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `projectKey` | path | yes | string | The project's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [Note](schemas.md#note) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Create project note `POST https://api.hardfin.com/v2/project/{projectKey}/note` Operation `projectCreateProjectNote`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `projectKey` | path | yes | string | The project's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `content` | string | yes | The note's text, 1 to 2,000 characters. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Note](schemas.md#note) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Purchase order operations ## List purchase orders `GET https://api.hardfin.com/v2/purchase-order` Operation `purchaseOrderListPurchaseOrders`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `results.carrier` removed from the response | | 2026-10-22 | `results.transportReferenceDetails` added to the response | | 2026-10-20 | `results.carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `results.otherCarrier` removed from the response | | 2026-10-20 | `results.referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `purchaseOrderNumber`, `status`, `promiseShipDate`, `promiseDeliveryDate` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `search` | query | no | string, or null | Text to find in the order's number, its status, its supplier's name, its locations' names, or its items' names and SKUs. | | `purchaseOrderKeys` | query | no | list of string | The keys of the purchase orders to list, and an order named here or in purchaseOrderIds is listed. | | `purchaseOrderIds` | query | no | list of string (uuid) | The IDs of the purchase orders to list, and an order named here or in purchaseOrderKeys is listed. | | `supplierIds` | query | no | list of string (uuid) | The IDs of suppliers, and orders placed with one of them are listed. | | `statuses` | query | no | list of [PurchaseOrderStatus](schemas.md#purchaseorderstatus) | The statuses to list, as the order's status field spells them. | | `fromLocationIds` | query | no | list of string (uuid) | The IDs of locations, and orders shipping from one of them are listed, as are orders any other from filter matches. | | `toLocationIds` | query | no | list of string (uuid) | The IDs of locations, and orders delivered to one of them are listed, as are orders any other to filter matches. | | `fromCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and orders shipping from a location assigned to one of them are listed, as are orders any other from filter matches. | | `toCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and orders delivered to a location assigned to one of them are listed, as are orders any other to filter matches. | | `fromLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed orders ship from, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and an order any other from filter matches is listed too. | | `toLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed orders are delivered to, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and an order any other to filter matches is listed too. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrderListing](schemas.md#purchaseorderlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create purchase order `POST https://api.hardfin.com/v2/purchase-order` Operation `purchaseOrderCreatePurchaseOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the request | | 2026-10-22 | `transportReferenceDetails` added to the request | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-20 | `carrier` in the request changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the request | | 2026-10-20 | `referenceNumber` removed from the request | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `externalPurchaseOrderNumber` | string, or null | no | The supplier's own number for the order, or null when it has none. | | `fromLocationId` | string (uuid), or null | no | The ID of the location the supplier ships from, or null when the supplier has no location on record. | | `items` | list of [PurchaseOrderItem](schemas.md#purchaseorderitem) | yes | The order's lines, from 1 to 50 of them, each naming a different item. | | `orderNotes` | string, or null | no | A note about the order, where blank text is stored as null. | | `promiseDeliveryDate` | string (date), or null | no | The day the supplier promised the order would arrive. | | `promiseShipDate` | string (date), or null | no | The day the supplier promised to ship the order. | | `supplierId` | string (uuid) | yes | The ID of the company the items are ordered from, which must be a supplier. | | `toLocationId` | string (uuid) | yes | The ID of the location the order is delivered to. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the supplier ships the order with and its transport reference, or null when none of them is set. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrder](schemas.md#purchaseorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get purchase order `GET https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}` Operation `purchaseOrderGetPurchaseOrder`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrder](schemas.md#purchaseorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update purchase order `PATCH https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}` Operation `purchaseOrderUpdatePurchaseOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the request | | 2026-10-22 | `transportReferenceDetails` added to the request | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-20 | `carrier` in the request changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the request | | 2026-10-20 | `referenceNumber` removed from the request | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `externalPurchaseOrderNumber` | string, or null | no | The supplier's own number for the order, or null when it has none. | | `fromLocationId` | string (uuid), or null | no | The ID of the location the supplier ships from, or null when the supplier has no location on record. | | `items` | list of [PurchaseOrderItem](schemas.md#purchaseorderitem), or null | no | The 1 to 50 lines that replace the order's, each naming a different item. | | `orderNotes` | string, or null | no | A note about the order, which a request sending only the note can change after the order leaves draft, until any of it is received, it is cancelled, or it is sent to a 3PL. | | `promiseDeliveryDate` | string (date), or null | no | The day the supplier promised the order would arrive. | | `promiseShipDate` | string (date), or null | no | The day the supplier promised to ship the order. | | `supplierId` | string (uuid), or null | no | The ID of the company the items are ordered from, which must be a supplier. | | `toLocationId` | string (uuid), or null | no | The ID of the location the order is delivered to, which cannot be cleared. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the supplier ships the order with and its transport reference, where a field left out keeps its stored value and null clears all of them. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrder](schemas.md#purchaseorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Resync 3PL files `POST https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/3pl/files/resync` Operation `purchaseOrderResync3PLFiles`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrderResync3PLFilesResult](schemas.md#purchaseorderresync3plfilesresult) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Cancel purchase order `POST https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/cancel` Operation `purchaseOrderCancelPurchaseOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string | yes | Why the order is cancelled, which is required. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrder](schemas.md#purchaseorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get purchase order files `GET https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/file` Operation `purchaseOrderGetPurchaseOrderFiles`, which needs the `hardfin:read` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [File](schemas.md#file) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Unlink purchase order file `DELETE https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/file/{fileKey}` Operation `purchaseOrderUnlinkPurchaseOrderFile`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | | `fileKey` | path | yes | string | The key of the file to detach. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Resync purchase order `POST https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/resync` Operation `purchaseOrderResyncPurchaseOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrder](schemas.md#purchaseorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Send purchase order to 3PL `POST https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/send-to-3pl` Operation `purchaseOrderSendPurchaseOrderTo3PL`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [PurchaseOrder](schemas.md#purchaseorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get purchase order URL links `GET https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/url-link` Operation `purchaseOrderGetPurchaseOrderURLLinks`, which needs the `hardfin:read` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Create purchase order URL link `POST https://api.hardfin.com/v2/purchase-order/{purchaseOrderKey}/url-link` Operation `purchaseOrderCreatePurchaseOrderURLLink`, which needs the `hardfin:write` scope. Last changed on 2026-10-17. | Date | Change | | --- | --- | | 2026-10-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `purchaseOrderKey` | path | yes | string | The purchase order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string, or null | no | The link's display name, or null to show the address instead. | | `url` | string | yes | The address the link points to. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Return order operations ## List return orders `GET https://api.hardfin.com/v2/return-order` Operation `returnOrderListReturnOrders`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `results.carrier` removed from the response | | 2026-10-22 | `results.transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `returnOrderNumber`, `status`, `returnType`, `promiseShipDate`, `promiseDeliveryDate` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `search` | query | no | string, or null | Text to find in the order's number, its status, its return type, its locations' names, or its items' names and SKUs. | | `returnOrderKeys` | query | no | list of string | The keys of the return orders to list, and an order named here or in returnOrderIds is listed. | | `returnOrderIds` | query | no | list of string (uuid) | The IDs of the return orders to list, and an order named here or in returnOrderKeys is listed. | | `types` | query | no | list of [ReturnOrderType](schemas.md#returnordertype) | The return types to list, as the order's returnType field spells them. | | `statuses` | query | no | list of [ReturnOrderStatus](schemas.md#returnorderstatus) | The statuses to list, as the order's status field spells them. | | `fromLocationIds` | query | no | list of string (uuid) | The IDs of locations, and orders returned from one of them are listed, as are orders any other from filter matches. | | `toLocationIds` | query | no | list of string (uuid) | The IDs of locations, and orders returned to one of them are listed, as are orders any other to filter matches. | | `fromCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and orders returned from a location assigned to one of them are listed, as are orders any other from filter matches. | | `toCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and orders returned to a location assigned to one of them are listed, as are orders any other to filter matches. | | `fromLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed orders are returned from, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and an order any other from filter matches is listed too. | | `toLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed orders are returned to, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and an order any other to filter matches is listed too. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrderListing](schemas.md#returnorderlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create return order `POST https://api.hardfin.com/v2/return-order` Operation `returnOrderCreateReturnOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the request | | 2026-10-22 | `transportReferenceDetails` added to the request | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `fromLocationId` | string (uuid) | yes | The ID of the location the items are returned from. | | `items` | list of [ReturnOrderItem](schemas.md#returnorderitem) | yes | The order's lines, from 1 to 50 of them, each naming a different item. | | `orderNotes` | string, or null | no | A note about the order, where blank text is stored as null. | | `promiseDeliveryDate` | string (date), or null | no | The day the items are promised to arrive. | | `promiseShipDate` | string (date), or null | no | The day the items are promised to ship. | | `returnReason` | string, or null | no | A description of why the items are coming back, which is required when returnType is OTHER. | | `returnType` | [ReturnOrderType](schemas.md#returnordertype) | yes | Why the items are coming back. | | `toLocationId` | string (uuid) | yes | The ID of the location the items are returned to, which must differ from fromLocationId. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the items are returned with and its transport reference, or null when none of them is set. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrder](schemas.md#returnorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get return order `GET https://api.hardfin.com/v2/return-order/{returnOrderKey}` Operation `returnOrderGetReturnOrder`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrder](schemas.md#returnorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update return order `PATCH https://api.hardfin.com/v2/return-order/{returnOrderKey}` Operation `returnOrderUpdateReturnOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the request | | 2026-10-22 | `transportReferenceDetails` added to the request | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `fromLocationId` | string (uuid), or null | no | The ID of the location the items are returned from, which cannot be cleared. | | `items` | list of [ReturnOrderItem](schemas.md#returnorderitem), or null | no | The 1 to 50 lines that replace the order's, each naming a different item. | | `orderNotes` | string, or null | no | A note about the order, which a request sending only the note can change after the order leaves draft until it is received or cancelled, unless a 3PL runs its destination. | | `promiseDeliveryDate` | string (date), or null | no | The day the items are promised to arrive. | | `promiseShipDate` | string (date), or null | no | The day the items are promised to ship. | | `returnReason` | string, or null | no | A description of why the items are coming back, which the order must have while its type is OTHER. | | `returnType` | [ReturnOrderType](schemas.md#returnordertype), or null | no | Why the items are coming back, which cannot be cleared. | | `toLocationId` | string (uuid), or null | no | The ID of the location the items are returned to, which cannot be cleared and must differ from the order's origin. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the items are returned with and its transport reference, where a field left out keeps its stored value and null clears all of them. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrder](schemas.md#returnorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Resync 3PL files `POST https://api.hardfin.com/v2/return-order/{returnOrderKey}/3pl/files/resync` Operation `returnOrderResync3PLFiles`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrderResync3PLFilesResult](schemas.md#returnorderresync3plfilesresult) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Cancel return order `POST https://api.hardfin.com/v2/return-order/{returnOrderKey}/cancel` Operation `returnOrderCancelReturnOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string | yes | Why the order is cancelled, which is required. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrder](schemas.md#returnorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get return order files `GET https://api.hardfin.com/v2/return-order/{returnOrderKey}/file` Operation `returnOrderGetReturnOrderFiles`, which needs the `hardfin:read` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [File](schemas.md#file) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Unlink return order file `DELETE https://api.hardfin.com/v2/return-order/{returnOrderKey}/file/{fileKey}` Operation `returnOrderUnlinkReturnOrderFile`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | | `fileKey` | path | yes | string | The key of the file to detach. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Resync return order `POST https://api.hardfin.com/v2/return-order/{returnOrderKey}/resync` Operation `returnOrderResyncReturnOrder`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrder](schemas.md#returnorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Send return order to 3PL `POST https://api.hardfin.com/v2/return-order/{returnOrderKey}/send-to-3pl` Operation `returnOrderSendReturnOrderTo3PL`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `transportReferenceDetails` added to the response | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ReturnOrder](schemas.md#returnorder) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Get return order URL links `GET https://api.hardfin.com/v2/return-order/{returnOrderKey}/url-link` Operation `returnOrderGetReturnOrderURLLinks`, which needs the `hardfin:read` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Create return order URL link `POST https://api.hardfin.com/v2/return-order/{returnOrderKey}/url-link` Operation `returnOrderCreateReturnOrderURLLink`, which needs the `hardfin:write` scope. Last changed on 2026-10-21. | Date | Change | | --- | --- | | 2026-10-21 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `returnOrderKey` | path | yes | string | The return order's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string, or null | no | The link's display name, or null to show the address instead. | | `url` | string | yes | The address the link points to. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | --- # Shipment operations ## List shipments `GET https://api.hardfin.com/v2/shipment` Operation `shipmentListShipments`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `results.carrier` removed from the response | | 2026-10-22 | `results.trackingNumberDetails` added to the response | | 2026-10-20 | `results.carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `results.otherCarrier` removed from the response | | 2026-10-20 | `results.referenceNumber` removed from the response | | 2026-10-17 | `results.cancellationReason` added to the response | | 2026-10-17 | `results.cancelledReason` removed from the response | | 2026-10-17 | `results.fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `results.fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `results.purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `results.purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `results.purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `results.purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `results.returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `results.returnOrder.roNumber` removed from the response | | 2026-10-14 | Request validation changed | | 2026-10-12 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `page` | query | no | integer | The page to return, starting at 1. | | `limit` | query | no | integer | The number of records per page, from 1 to 100. | | `sortBy` | query | no | one of `shipmentNumber`, `shippingCostAmount`, `totalValue`, `status` | The field to sort by. | | `sortOrder` | query | no | [SortOrder](schemas.md#sortorder) | The sort direction. | | `status` | query | no | [ShipmentStatus](schemas.md#shipmentstatus), or null | The one status to list: OPEN, SHIPPED, DELIVERED, RECEIVED or CANCELLED. | | `shipmentType` | query | no | [ShipmentType](schemas.md#shipmenttype), or null | The one direction to list: INBOUND or OUTBOUND. | | `search` | query | no | string | Text to find in the shipment's number, its order numbers, its tracking number, its locations' names, or its items' names and SKUs. | | `foNumbers` | query | no | list of string | The fulfillment order numbers whose shipments to list. | | `poNumbers` | query | no | list of string | The purchase order numbers whose shipments to list. | | `roNumbers` | query | no | list of string | The return order numbers whose shipments to list. | | `locationIds` | query | no | list of string (uuid) | The IDs of locations, and only shipments leaving from or going to one of them are listed. | | `fromLocationIds` | query | no | list of string (uuid) | The IDs of locations, and shipments leaving from one of them are listed, as are shipments any other from filter matches. | | `toLocationIds` | query | no | list of string (uuid) | The IDs of locations, and shipments going to one of them are listed, as are shipments any other to filter matches. | | `fromCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and shipments leaving from a location assigned to one of them are listed, as are shipments any other from filter matches. | | `toCustomerIds` | query | no | list of string (uuid) | The IDs of customers, and shipments going to a location assigned to one of them are listed, as are shipments any other to filter matches. | | `fromLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed shipments leave from, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and a shipment any other from filter matches is listed too. | | `toLocationCompanyTypes` | query | no | list of [CompanyType](schemas.md#companytype) | The kind of site listed shipments go to, a CUSTOMER site or one of the organization's own MANUFACTURER sites, naming both filters nothing, and a shipment any other to filter matches is listed too. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [ShipmentListing](schemas.md#shipmentlisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create shipment `POST https://api.hardfin.com/v2/shipment` Operation `shipmentCreateShipment`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | Error codes or messages changed | | 2026-10-22 | `carrier` removed from the request | | 2026-10-22 | `trackingNumberDetails` added to the request | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-22 | `items.itemId` in the request is now required | | 2026-10-20 | `carrier` in the request changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the request | | 2026-10-20 | `referenceNumber` removed from the request | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-19 | Request validation changed | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredAt` | string (date-time), or null | no | When the shipment arrived, or null while it has not. It cannot be before shippedAt or more than five minutes ahead of the server's clock. | | `deliveredAtTimezone` | string, or null | no | The IANA time zone deliveredAt is recorded in, and the organization's when omitted. Sending one is strongly recommended. | | `expectedDeliveredOn` | string (date), or null | no | The day the shipment is expected to arrive, which on an inbound shipment cannot be before expectedShippedOn. | | `expectedShippedOn` | string (date), or null | no | The day the shipment is expected to leave. | | `fromLocationId` | string (uuid), or null | no | The ID of the location the shipment leaves from, which an outbound shipment requires. | | `fulfillmentOrderNumber` | string, or null | no | The number of the fulfillment order an outbound shipment fills, or null for none. | | `items` | list of [ShipmentItem](schemas.md#shipmentitem) | yes | The shipment's line items, from 1 to 100 of them. | | `purchaseOrderNumber` | string, or null | no | The number of the purchase order an inbound shipment fills, or null for none. | | `returnOrderNumber` | string, or null | no | The number of the return order an inbound shipment fills, or null for none. | | `shipmentNote` | string, or null | no | A note about the shipment. | | `shipmentType` | [ShipmentType](schemas.md#shipmenttype) | yes | Whether the shipment is INBOUND to the organization or OUTBOUND from it. | | `shippedAt` | string (date-time), or null | no | When the shipment left, or null while it has not. It cannot be more than five minutes ahead of the server's clock. | | `shippedAtTimezone` | string, or null | no | The IANA time zone shippedAt is recorded in, and the organization's when omitted. Sending one is strongly recommended. | | `shippingCost` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | What the shipment cost to send, which cannot be negative. | | `toLocationId` | string (uuid) | yes | The ID of the location the shipment is going to. | | `trackingNumberDetails` | [CarrierTrackingNumberDetails](schemas.md#carriertrackingnumberdetails), or null | no | Who carries the shipment and its tracking number, or null when none of them is set. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get shipment `GET https://api.hardfin.com/v2/shipment/{shipmentKey}` Operation `shipmentGetShipment`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | | 2026-10-12 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update shipment `PATCH https://api.hardfin.com/v2/shipment/{shipmentKey}` Operation `shipmentUpdateShipment`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the request | | 2026-10-22 | `trackingNumberDetails` added to the request | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-22 | `items.itemId` in the request is now required | | 2026-10-20 | `carrier` in the request changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the request | | 2026-10-20 | `referenceNumber` removed from the request | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-19 | Request validation changed | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredAt` | string (date-time), or null | no | When the shipment arrived, and can only be corrected here once the shipment is delivered or received. The deliver endpoint records a first delivery. It cannot be before shippedAt, after the shipment's receipt, or more than five minutes ahead of the server's clock. | | `deliveredAtTimezone` | string, or null | no | The IANA time zone deliveredAt is recorded in. When a new deliveredAt omits it, the zone already recorded is kept, or the organization's is used. Sending one is strongly recommended. | | `deliveryNote` | string, or null | no | The note written when the shipment was delivered. | | `expectedDeliveredOn` | string (date), or null | no | The day the shipment is expected to arrive, which on an inbound shipment cannot be before expectedShippedOn. | | `expectedShippedOn` | string (date), or null | no | The day the shipment is expected to leave. | | `fromLocationId` | string (uuid), or null | no | The ID of the location the shipment leaves from, which an outbound shipment cannot clear. | | `fulfillmentOrderNumber` | string, or null | no | The number of the fulfillment order an outbound shipment fills, or null for none. | | `items` | list of [ShipmentItem](schemas.md#shipmentitem), or null | no | The 1 to 100 line items that replace the shipment's, where a line already on the shipment keeps its quantity when sent without one. | | `purchaseOrderNumber` | string, or null | no | The number of the purchase order an inbound shipment fills, or null for none. | | `receiptNote` | string, or null | no | The note written when the shipment was received. | | `returnOrderNumber` | string, or null | no | The number of the return order an inbound shipment fills, or null for none. | | `shipmentNote` | string, or null | no | A note about the shipment. | | `shippedAt` | string (date-time), or null | no | When the shipment left, which cannot be cleared and, on an outbound shipment, can only be corrected after it has shipped. It cannot be after the shipment's delivery or receipt, or more than five minutes ahead of the server's clock. | | `shippedAtTimezone` | string, or null | no | The IANA time zone shippedAt is recorded in. When a new shippedAt omits it, the zone already recorded is kept, or the organization's is used. Sending one is strongly recommended. | | `shippingCost` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | What the shipment cost to send, which cannot be negative. | | `toLocationId` | string (uuid), or null | no | The ID of the location the shipment is going to, which cannot be cleared. | | `trackingNumberDetails` | [CarrierTrackingNumberDetails](schemas.md#carriertrackingnumberdetails), or null | no | Who carries the shipment and its tracking number, where a field left out keeps its stored value and null clears all of them. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Cancel shipment `POST https://api.hardfin.com/v2/shipment/{shipmentKey}/cancel` Operation `shipmentCancelShipment`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-22 | Request validation changed | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | `cancellationReason` added to the request | | 2026-10-17 | `reason` removed from the request | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | | 2026-10-12 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string | yes | Why the shipment is cancelled, which is required. | | `removeLinkedShippingCost` | boolean | no | True to also remove the shipping cost recorded for the shipment. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Mark shipment as delivered `POST https://api.hardfin.com/v2/shipment/{shipmentKey}/deliver` Operation `shipmentMarkShipmentAsDelivered`, which needs the `hardfin:write` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | | 2026-10-12 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredAt` | string (date-time) | yes | When the shipment arrived, which cannot be before its ship time or more than five minutes ahead of the server's clock. | | `deliveredAtTimezone` | string, or null | no | The IANA time zone deliveredAt is recorded in, and the organization's when omitted. Sending one is strongly recommended. | | `deliveryLocationId` | string (uuid) | yes | The ID of the location the shipment was delivered to. | | `deliveryNote` | string, or null | no | A note about the delivery. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Mark inbound shipment as received `POST https://api.hardfin.com/v2/shipment/{shipmentKey}/receive` Operation `shipmentMarkInboundShipmentAsReceived`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | | 2026-10-12 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | list of [ShipmentReceiveItem](schemas.md#shipmentreceiveitem) | no | What arrived on each line. | | `receiptNote` | string, or null | no | A note about the receipt. | | `receiveLocationId` | string (uuid) | yes | The ID of the location the items were received at. | | `receivedAt` | string (date-time) | yes | When the items were received, which cannot be before the shipment's delivery or ship time, or more than five minutes ahead of the server's clock. | | `receivedAtTimezone` | string, or null | no | The IANA time zone receivedAt is recorded in, and the organization's when omitted. Sending one is strongly recommended. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Mark outbound shipment as shipped `POST https://api.hardfin.com/v2/shipment/{shipmentKey}/ship` Operation `shipmentMarkOutboundShipmentAsShipped`, which needs the `hardfin:write` scope. Last changed on 2026-10-24. | Date | Change | | --- | --- | | 2026-10-24 | Request validation changed | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-22 | `items.itemId` in the request is now required | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherCarrier` removed from the response | | 2026-10-20 | `referenceNumber` removed from the response | | 2026-10-19 | Request validation changed | | 2026-10-17 | `cancellationReason` added to the response | | 2026-10-17 | `cancelledReason` removed from the response | | 2026-10-17 | `fulfillmentOrder.foNumber` removed from the response | | 2026-10-17 | `fulfillmentOrder.fulfillmentOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.externalPoNumber` removed from the response | | 2026-10-17 | `purchaseOrder.externalPurchaseOrderNumber` added to the response | | 2026-10-17 | `purchaseOrder.poNumber` removed from the response | | 2026-10-17 | `purchaseOrder.purchaseOrderNumber` added to the response | | 2026-10-17 | `returnOrder.returnOrderNumber` added to the response | | 2026-10-17 | `returnOrder.roNumber` removed from the response | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | list of [ShipmentItem](schemas.md#shipmentitem) | no | What left on each line, with the serial numbers of the units tracked by serial. | | `shipLocationId` | string (uuid) | yes | The ID of the location the shipment left from. | | `shipmentNote` | string, or null | no | A note about the shipment. | | `shippedAt` | string (date-time) | yes | When the shipment left, which cannot be after its delivery or more than five minutes ahead of the server's clock. | | `shippedAtTimezone` | string, or null | no | The IANA time zone shippedAt is recorded in, and the organization's when omitted. Sending one is strongly recommended. | | `shippingCost` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | What the shipment cost to send, which cannot be negative. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Shipment](schemas.md#shipment) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get shipment tracking events `GET https://api.hardfin.com/v2/shipment/{shipmentKey}/tracking` Operation `shipmentGetShipmentTrackingEvents`, which needs the `hardfin:read` scope. Last changed on 2026-10-22. | Date | Change | | --- | --- | | 2026-10-22 | `carrier` removed from the response | | 2026-10-22 | `trackingNumberDetails` added to the response | | 2026-10-20 | `carrier` in the response changed from `string or null` to `object or null` | | 2026-10-20 | `otherName` removed from the response | | 2026-10-20 | `trackingNumber` removed from the response | | 2026-10-12 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `shipmentKey` | path | yes | string | The shipment's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [AssetShippingDataListing](schemas.md#assetshippingdatalisting) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Token operations ## Get token `GET https://api.hardfin.com/v2/token` Operation `tokenGetToken`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Token](schemas.md#token) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | --- # URL link operations ## Get URL link by key `GET https://api.hardfin.com/v2/url-link/{linkKey}` Operation `urlLinkGetURLLinkByKey`, which needs the `hardfin:read` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `linkKey` | path | yes | string | The URL link's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update URL link `PATCH https://api.hardfin.com/v2/url-link/{linkKey}` Operation `urlLinkUpdateURLLink`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `linkKey` | path | yes | string | The URL link's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string, or null | no | The link's display name, or null to show the address instead, and an update sends it, url, or both. | | `url` | string | no | The address the link points to, which cannot be empty, and an update sends it, name, or both. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [URLLink](schemas.md#urllink) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Delete URL link `DELETE https://api.hardfin.com/v2/url-link/{linkKey}` Operation `urlLinkDeleteURLLink`, which needs the `hardfin:write` scope. Last changed on 2026-09-17. | Date | Change | | --- | --- | | 2026-09-17 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `linkKey` | path | yes | string | The URL link's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Workflow operations ## Get workflows `GET https://api.hardfin.com/v2/workflow` Operation `workflowGetWorkflows`, which needs the `hardfin:read` scope. Last changed on 2026-10-06. | Date | Change | | --- | --- | | 2026-10-06 | Endpoint added | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | list of [Workflow](schemas.md#workflow) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | ## Create workflow `POST https://api.hardfin.com/v2/workflow` Operation `workflowCreateWorkflow`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `isDefault` | boolean, or null | no | | | `name` | string | yes | | | `stages` | list of [WorkflowStageRequest](schemas.md#workflowstagerequest) | yes | | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Workflow](schemas.md#workflow) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Get workflow `GET https://api.hardfin.com/v2/workflow/{workflowKey}` Operation `workflowGetWorkflow`, which needs the `hardfin:read` scope. Last changed on 2026-10-06. | Date | Change | | --- | --- | | 2026-10-06 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `workflowKey` | path | yes | string | The workflow's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Workflow](schemas.md#workflow) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | ## Update workflow `PUT https://api.hardfin.com/v2/workflow/{workflowKey}` Operation `workflowUpdateWorkflow`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `workflowKey` | path | yes | string | The workflow's key. | ### Request body Sent as `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `isDefault` | boolean, or null | no | | | `name` | string, or null | no | | | `stages` | list of [WorkflowStageRequest](schemas.md#workflowstagerequest), or null | no | | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [Workflow](schemas.md#workflow) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | | 413 | The request body is larger than the endpoint accepts. Read the status rather than the body. | | ## Delete workflow `DELETE https://api.hardfin.com/v2/workflow/{workflowKey}` Operation `workflowDeleteWorkflow`, which needs the `hardfin:write` scope. Last changed on 2026-10-26. | Date | Change | | --- | --- | | 2026-10-26 | Endpoint added | ### Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `workflowKey` | path | yes | string | The workflow's key. | ### Responses | Status | Means | Data | | --- | --- | --- | | 200 | The request succeeded. | [SharedBool](schemas.md#sharedbool) | | 400 | The request was refused, and metadata.errors says why. | null | | 401 | The API key is missing or is not valid. Read the status rather than the body. | | | 404 | A record the request names does not exist, and metadata.errors says which. | null | --- # Schemas Every record the API sends and takes. A field is optional unless its row says it is required. ## ArchivedState Accepted in any case, and also as t, f, 1, 0, or 2 for all. The listed spelling is the one the API sends back. Its value is one of `all`, `false`, `true`. ## Asset | Field | Type | Required | Description | | --- | --- | --- | --- | | `functionalStatus` | [AssetFunctionalStatus](schemas.md#assetfunctionalstatus) | no | Whether the asset works, is broken, awaits review, or has been scrapped. | | `id` | string (uuid) | no | The asset's unique identifier. | | `inInventoryDate` | string (date) | no | The day the asset entered inventory. | | `isArchived` | boolean | no | Whether the asset is archived. | | `isInTransit` | boolean | no | Whether the asset has shipped and not yet been delivered. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The catalog item the asset is a unit of. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The asset's key, which the asset endpoints take as assetKey. | | `serial` | string | no | The asset's serial number, unique within your organization in any case. | | `currentLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | Where the asset is, or null while it is in transit. | | `inTransit` | boolean | no | Whether the asset has shipped and not yet been delivered. | | `nextLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | Where the asset is headed while it is in transit, or null when it is not in transit. | | `previousLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The location the asset was at before its current one, or null when it has not moved. | | `accounting` | [AssetAccountingDetails](schemas.md#assetaccountingdetails) | no | The asset's cost basis, depreciation, and accounting history. | | `accounting.acquisitionCogs` | [Currency](schemas.md#currency), or null | no | The asset's inventory cost basis, before deployment costs, which is what inventory is relieved by when the asset leaves it. | | `accounting.allocatedIndirect` | [Currency](schemas.md#currency), or null | no | The asset's share of overhead. | | `accounting.assetExceptions` | list of [AssetExceptionType](schemas.md#assetexceptiontype) | no | The problems that keep the asset's accounting from being computed, such as a missing cost basis. | | `accounting.billOfMaterials` | [Currency](schemas.md#currency), or null | no | The parts cost. | | `accounting.capitalizedCosts` | [Currency](schemas.md#currency), or null | no | The cost basis on the books now, the acquisition basis in inventory and the deployed basis once the asset is a fixed asset. | | `accounting.costAdjustments` | list of [AssetCostAdjustment](schemas.md#assetcostadjustment) | no | The capitalizations and impairments made to the asset's cost after it was acquired. | | `accounting.costCurrencyCode` | [CurrencyCode](schemas.md#currencycode) | no | The ISO 4217 code every cost amount on the asset is denominated in. | | `accounting.depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The method the asset is depreciated by. | | `accounting.depreciationPeriods` | list of [AssetDepreciationChartPeriod](schemas.md#assetdepreciationchartperiod), or null | no | The asset's book value month by month, from its inventory month, or null while it has an accounting exception. | | `accounting.directLabor` | [Currency](schemas.md#currency), or null | no | The labor cost to build the asset. | | `accounting.freightInbound` | [Currency](schemas.md#currency), or null | no | The shipping cost to receive the asset. | | `accounting.freightOutbound` | [Currency](schemas.md#currency), or null | no | The shipping cost to deploy the asset, a deployment cost. | | `accounting.inServiceDate` | string (date), or null | no | The day the asset was put into service and began depreciating. | | `accounting.installation` | [Currency](schemas.md#currency), or null | no | The cost to install the asset, a deployment cost. | | `accounting.interest` | [Currency](schemas.md#currency), or null | no | The financing cost of the asset. | | `accounting.isCostCurrencyLocked` | boolean | no | Whether the asset's cost currency can no longer be changed. Closing an accounting period, the first accounting true-up, or recording a cost adjustment locks it for good. A sale with a sale price, or a scrap with a disposal price, also locks it. That lock lifts when the sale is deleted, its sale price is cleared, or the asset is unscrapped, as long as no other priced sale or priced scrap remains. | | `accounting.isInServiceDateManagedAutomatically` | boolean | no | Whether Hardfin sets the in-service date itself rather than keeping one a person entered. | | `accounting.salvageValue` | [Currency](schemas.md#currency), or null | no | The value the asset keeps at the end of its useful life. | | `accounting.simpleCostBasis` | [Currency](schemas.md#currency), or null | no | A single cost entered in place of the cost components. | | `accounting.tariffs` | [Currency](schemas.md#currency), or null | no | The import duty paid on the asset. | | `accounting.tax` | [Currency](schemas.md#currency), or null | no | The tax paid on the asset. | | `accounting.totalPotentialCOGS` | [Currency](schemas.md#currency), or null | no | The deployed cost basis, including deployment costs, which is what is capitalized once the asset is put into service. | | `accounting.usefulLife` | integer, or null | no | The number of months the asset is depreciated over. | | `accounting.usefulLifeRevisions` | list of [AssetUsefulLifeRevision](schemas.md#assetusefulliferevision) | no | The changes made to the asset's useful life. | | `activity` | list of [AssetEvent](schemas.md#assetevent) | no | The asset's recent events, such as shipments and deliveries. | | `description` | string, or null | no | A free-form description of the asset. | | `fileCount` | integer | no | The number of files attached to the asset. | | `metadata` | list of [AssetMetadataFieldWrapper](schemas.md#assetmetadatafieldwrapper) | no | The asset's value for each custom field its item defines. | | `ownership` | [AssetOwnership](schemas.md#assetownership) | no | Who owns the asset now. | | `ownership.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer that owns the asset, or null when your organization owns it. | | `ownership.ownershipChangeDate` | string (date), or null | no | The day the asset's current owner took ownership, or null when its ownership has never changed. | | `project` | [SparseProject](schemas.md#sparseproject), or null | no | The project the asset is assigned to, or null when it is unassigned. | | `scrappedContext` | [AssetScrappedContext](schemas.md#assetscrappedcontext), or null | no | How and when the asset was scrapped, or null when it has not been. | | `ticketCount` | integer | no | The number of tickets about the asset. | | `urlLinkCount` | integer | no | The number of links attached to the asset. | ## AssetAccountingDetails | Field | Type | Required | Description | | --- | --- | --- | --- | | `acquisitionCogs` | [Currency](schemas.md#currency), or null | no | The asset's inventory cost basis, before deployment costs, which is what inventory is relieved by when the asset leaves it. | | `allocatedIndirect` | [Currency](schemas.md#currency), or null | no | The asset's share of overhead. | | `assetExceptions` | list of [AssetExceptionType](schemas.md#assetexceptiontype) | no | The problems that keep the asset's accounting from being computed, such as a missing cost basis. | | `billOfMaterials` | [Currency](schemas.md#currency), or null | no | The parts cost. | | `capitalizedCosts` | [Currency](schemas.md#currency), or null | no | The cost basis on the books now, the acquisition basis in inventory and the deployed basis once the asset is a fixed asset. | | `costAdjustments` | list of [AssetCostAdjustment](schemas.md#assetcostadjustment) | no | The capitalizations and impairments made to the asset's cost after it was acquired. | | `costCurrencyCode` | [CurrencyCode](schemas.md#currencycode) | no | The ISO 4217 code every cost amount on the asset is denominated in. | | `depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The method the asset is depreciated by. | | `depreciationPeriods` | list of [AssetDepreciationChartPeriod](schemas.md#assetdepreciationchartperiod), or null | no | The asset's book value month by month, from its inventory month, or null while it has an accounting exception. | | `directLabor` | [Currency](schemas.md#currency), or null | no | The labor cost to build the asset. | | `freightInbound` | [Currency](schemas.md#currency), or null | no | The shipping cost to receive the asset. | | `freightOutbound` | [Currency](schemas.md#currency), or null | no | The shipping cost to deploy the asset, a deployment cost. | | `inServiceDate` | string (date), or null | no | The day the asset was put into service and began depreciating. | | `installation` | [Currency](schemas.md#currency), or null | no | The cost to install the asset, a deployment cost. | | `interest` | [Currency](schemas.md#currency), or null | no | The financing cost of the asset. | | `isCostCurrencyLocked` | boolean | no | Whether the asset's cost currency can no longer be changed. Closing an accounting period, the first accounting true-up, or recording a cost adjustment locks it for good. A sale with a sale price, or a scrap with a disposal price, also locks it. That lock lifts when the sale is deleted, its sale price is cleared, or the asset is unscrapped, as long as no other priced sale or priced scrap remains. | | `isInServiceDateManagedAutomatically` | boolean | no | Whether Hardfin sets the in-service date itself rather than keeping one a person entered. | | `salvageValue` | [Currency](schemas.md#currency), or null | no | The value the asset keeps at the end of its useful life. | | `simpleCostBasis` | [Currency](schemas.md#currency), or null | no | A single cost entered in place of the cost components. | | `tariffs` | [Currency](schemas.md#currency), or null | no | The import duty paid on the asset. | | `tax` | [Currency](schemas.md#currency), or null | no | The tax paid on the asset. | | `totalPotentialCOGS` | [Currency](schemas.md#currency), or null | no | The deployed cost basis, including deployment costs, which is what is capitalized once the asset is put into service. | | `usefulLife` | integer, or null | no | The number of months the asset is depreciated over. | | `usefulLifeRevisions` | list of [AssetUsefulLifeRevision](schemas.md#assetusefulliferevision) | no | The changes made to the asset's useful life. | ## AssetCostAdjustment | Field | Type | Required | Description | | --- | --- | --- | --- | | `adjustmentType` | [CostAdjustmentType](schemas.md#costadjustmenttype) | no | CAPITALIZATION to add to the cost basis, or IMPAIRMENT to write it down. | | `amount` | [Currency](schemas.md#currency) | no | The size of the adjustment. | | `amount.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `amount.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `createdAt` | string (date-time) | no | When the adjustment was recorded. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | The person who recorded the adjustment. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `effectiveDate` | string (date) | no | The day the adjustment takes effect. | | `key` | string | no | The cost adjustment's key. | | `notes` | string, or null | no | Free-form detail about the adjustment. | | `reason` | [CostAdjustmentReason](schemas.md#costadjustmentreason) | no | Why the cost changed. | ## AssetDepreciationChartPeriod | Field | Type | Required | Description | | --- | --- | --- | --- | | `accumulated` | [Currency](schemas.md#currency) | no | The depreciation charged from the in-service date through the end of the period. | | `accumulated.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `accumulated.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `bookValue` | [Currency](schemas.md#currency) | no | The asset's value on the books at the end of the period. | | `bookValue.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `bookValue.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `date` | string (date) | no | The last day the period covers, which is the end of its month except for a final period cut short by a sale, a scrap, or today. | | `depreciation` | [Currency](schemas.md#currency) | no | The depreciation charged in the period. | | `depreciation.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `depreciation.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | ## AssetEvent | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the event was recorded. | | `eventTimezone` | string | no | The IANA time zone the event's times were entered in. | | `expectedAt` | string (date-time), or null | no | When the event is expected to happen, or null when no one has said. | | `id` | string | no | The event's unique identifier. | | `isRequired` | boolean | no | Whether the event has to happen for its group to complete. | | `occurredAt` | string (date-time), or null | no | When the event happened, or null while it has not. | | `promiseDate` | string (date), or null | no | The day the event was promised to a customer, or null when none was. | | `properties` | list of [AssetEventProperty](schemas.md#asseteventproperty) | no | The event's values a person set, such as carrier tracking. | | `sequence` | integer | no | The event's position within its group. | | `triggeredAt` | string (date-time), or null | no | When someone marked the event as happened in Hardfin, or null while it has not happened. | | `type` | [AssetEventType](schemas.md#asseteventtype) | no | What kind of event this is. A receipt that creates an asset records no event, so an asset's first events are its first ship and delivery. | | `type.id` | string | no | The event type's unique identifier. | | `type.name` | string | no | The event type's name, such as Ship or Deliver. | | `type.requiresEventGroup` | boolean | no | Whether an event of this type only happens as part of a group, such as a shipment. | ## AssetEventConfiguration | Field | Type | Required | Description | | --- | --- | --- | --- | | `properties` | list of [AssetEventProperty](schemas.md#asseteventproperty) | no | The properties an event of the type carries. | | `type` | [AssetEventType](schemas.md#asseteventtype) | no | The kind of event the configuration describes. | | `type.id` | string | no | The event type's unique identifier. | | `type.name` | string | no | The event type's name, such as Ship or Deliver. | | `type.requiresEventGroup` | boolean | no | Whether an event of this type only happens as part of a group, such as a shipment. | ## AssetEventGroup | Field | Type | Required | Description | | --- | --- | --- | --- | | `configuration` | [AssetEventGroupConfiguration](schemas.md#asseteventgroupconfiguration) | no | The kind of group this is, and the events it carries. | | `configuration.events` | list of [AssetEventConfiguration](schemas.md#asseteventconfiguration) | no | The events a group of the kind carries, in the order they happen. | | `configuration.id` | string | no | The configuration's unique identifier. | | `configuration.key` | string | no | The configuration's key. | | `configuration.name` | string | no | What the configuration is called, such as ship and deliver. | | `destination` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | Where the movement ends, or null when the group does not move the asset. | | `events` | list of [AssetEvent](schemas.md#assetevent) | no | The events the group has recorded so far. | | `id` | string | no | The event group's unique identifier. | | `key` | string | no | The event group's key, which the event group endpoints take as eventGroupKey. | | `origin` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | Where the movement started, or null when the group does not move the asset. | | `shipment` | [SparseShipment](schemas.md#sparseshipment), or null | no | The shipment the movement travels on, or null when it travels on none. | ## AssetEventGroupConfiguration | Field | Type | Required | Description | | --- | --- | --- | --- | | `events` | list of [AssetEventConfiguration](schemas.md#asseteventconfiguration) | no | The events a group of the kind carries, in the order they happen. | | `id` | string | no | The configuration's unique identifier. | | `key` | string | no | The configuration's key. | | `name` | string | no | What the configuration is called, such as ship and deliver. | ## AssetEventProperty | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | no | The event property's unique identifier. | | `isSystemProperty` | boolean | no | Whether Hardfin sets the property itself rather than a person, which responses leave out. | | `label` | string | no | The property's display name. | | `type` | string | no | The kind of value the property holds, such as CARRIER_TRACKING or CACHED_LOCATION. | | `value` | list of any or boolean or number or object or string, or null | no | The property's value, whose JSON shape depends on the property's type. | ## AssetEventType | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | no | The event type's unique identifier. | | `name` | string | no | The event type's name, such as Ship or Deliver. | | `requiresEventGroup` | boolean | no | Whether an event of this type only happens as part of a group, such as a shipment. | ## AssetExceptionType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DEPLOYMENT_WITHOUT_ACQUISITION`, `DISPOSAL_DATE_BEFORE_INVENTORY`, `FIRST_ASSIGNMENT_BEFORE_INVENTORY`, `FIRST_MOVEMENT_BEFORE_INVENTORY`, `FIRST_SALE_DATE_BEFORE_INVENTORY`, `IN_SERVICE_DATE_BEFORE_INVENTORY`, `MISSING_COST_BASIS`, `MISSING_USEFUL_LIFE`, `SALVAGE_EXCEEDS_50_PERCENT`, `UNKNOWN`. ## AssetFile | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The file's unique identifier. | | `isPublic` | boolean | no | Whether the file is readable with any organization's API key. | | `key` | string | no | The file's key, which the file endpoints take as fileKey. | | `mimeType` | string | no | The file's media type, or an empty string when the upload named none. | | `name` | string | no | The name the file had when it was uploaded. | | `size` | integer | no | The file's size in bytes. | | `type` | string | no | The file type the file was uploaded as. | | `uploadedAt` | string (date-time) | no | When the file was uploaded. | ## AssetFunctionalStatus Whether an asset works, is broken, awaits review, or has been scrapped. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `FUNCTIONAL`, `NEEDS_REVIEW`, `NON_FUNCTIONAL`, `SCRAPPED`. ## AssetFunctionalStatusHistoryItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `end` | string (date-time), or null | no | When the asset left the status, or null while it still holds it. | | `start` | string (date-time) | no | When the asset took the status. | | `status` | [AssetFunctionalStatus](schemas.md#assetfunctionalstatus) | no | Whether the asset worked, was broken, awaited review, or had been scrapped through the period. | ## AssetListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [Asset](schemas.md#asset) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## AssetLocationData | Field | Type | Required | Description | | --- | --- | --- | --- | | `currentLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | Where the asset is, or null while it is in transit. | | `inTransit` | boolean | no | Whether the asset has shipped and not yet been delivered. | | `nextLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | Where the asset is headed while it is in transit, or null when it is not in transit. | | `previousLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The location the asset was at before its current one, or null when it has not moved. | ## AssetMetadataField | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The item field's unique identifier. | | `key` | string | no | The item field's key. | | `label` | string | no | The field's display name. | | `order` | integer | no | The field's position within its section, starting at 0. | | `section` | integer | no | The group the field is shown in, starting at 0. | | `type` | [ItemFieldType](schemas.md#itemfieldtype) | no | The kind of value the field holds, which decides the JSON type of its value. | ## AssetMetadataFieldWrapper | Field | Type | Required | Description | | --- | --- | --- | --- | | `field` | [AssetMetadataField](schemas.md#assetmetadatafield) | no | The item field the value belongs to. | | `field.id` | string (uuid) | no | The item field's unique identifier. | | `field.key` | string | no | The item field's key. | | `field.label` | string | no | The field's display name. | | `field.order` | integer | no | The field's position within its section, starting at 0. | | `field.section` | integer | no | The group the field is shown in, starting at 0. | | `field.type` | [ItemFieldType](schemas.md#itemfieldtype) | no | The kind of value the field holds, which decides the JSON type of its value. | | `value` | list of any or boolean or number or object or string, or null | no | The field's value, sent as the JSON type its field's type names, or null when the asset has none. | ## AssetMoveToPlan | Field | Type | Required | Description | | --- | --- | --- | --- | | `assetId` | string (uuid) | yes | The ID of the asset to move. | | `deliverAt` | string (date-time), or null | no | When the asset reaches its destination, or null when the move only ships. | | `id` | string | yes | The client's own name for the move, which the plan echoes back beside its answer. | | `shipAt` | string (date-time), or null | no | When the asset leaves its origin, or null when the move only delivers. | ## AssetOwnership | Field | Type | Required | Description | | --- | --- | --- | --- | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer that owns the asset, or null when your organization owns it. | | `ownershipChangeDate` | string (date), or null | no | The day the asset's current owner took ownership, or null when its ownership has never changed. | ## AssetOwnershipHistoryItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the segment was recorded. | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer that owned the asset during the segment, or null when your organization did. | | `date` | string (date) | no | The day the segment's owner took ownership. | | `id` | string (uuid) | no | The ownership segment's unique identifier. | | `key` | string | no | The ownership segment's key, which the segment endpoints take as segmentKey. | | `lastModifiedAt` | string (date-time) | no | When the segment was last changed. | | `salePrice` | [Currency](schemas.md#currency), or null | no | What the owner paid for the asset, or null when no price was recorded. | ## AssetPlannedIntersection | Field | Type | Required | Description | | --- | --- | --- | --- | | `aegId` | string (uuid), or null | no | The ID of the event group the move would collide with, or null when none names one. | | `aegKey` | string, or null | no | The key of the event group the move would collide with, or null when none names one. | | `end` | string (date-time), or null | no | When the colliding movement ends, or null while it has no end. | | `start` | string (date-time) | no | When the colliding movement starts. | ## AssetPlannedMove | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | no | The client's own name for the move, echoed from the plan it asked about. | | `intersection` | [AssetPlannedIntersection](schemas.md#assetplannedintersection), or null | no | The movement the move would collide with, or null when it collides with none. | | `isValid` | boolean | no | Whether the move can be carried out as asked. | ## AssetProjectStatusFilter A project assignment the asset list filters by. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ACTIVE`, `NONE`, `PAST`, `UPCOMING`. ## AssetProposedMultiMove | Field | Type | Required | Description | | --- | --- | --- | --- | | `assetId` | string (uuid) | yes | The ID of the asset to move. | | `deliverAt` | string (date-time), or null | no | When the asset reaches its destination, and one of shipAt or deliverAt is required. | | `deliverAtTimezone` | string, or null | no | The IANA time zone name the delivery time was entered in, such as America/Denver, and the organization's time zone when omitted. The delivery time is kept as the instant sent, offset included. | | `destinationId` | string (uuid) | yes | The ID of the location the asset arrives at. | | `originId` | string (uuid) | yes | The ID of the location the asset leaves. | | `shipAt` | string (date-time), or null | no | When the asset leaves its origin, and one of shipAt or deliverAt is required. | | `shipAtTimezone` | string, or null | no | The IANA time zone name the ship time was entered in, such as America/Denver, and the organization's time zone when omitted. The ship time is kept as the instant sent, offset included. | ## AssetScrappedContext | Field | Type | Required | Description | | --- | --- | --- | --- | | `disposalDate` | string (date) | no | The day the asset was scrapped. | | `disposalPrice` | [Currency](schemas.md#currency), or null | no | What the scrapped asset was sold for, or null when it was not sold. | | `disposalReason` | string, or null | no | Why the asset was scrapped. | ## AssetShippingData | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When Hardfin recorded the update. | | `id` | string (uuid) | no | The tracking update's unique identifier. | | `key` | string | no | The tracking update's key. | | `location` | [AssetShippingDataLocation](schemas.md#assetshippingdatalocation), or null | no | Where the carrier reported the shipment, or null when it reported nowhere. | | `reportedAt` | string (date-time) | no | When the carrier says the update happened. | | `status` | string | no | The carrier's status for the shipment at that point. | | `statusText` | string | no | What the carrier wrote about the update. | | `substatus` | string, or null | no | The carrier's finer status, or null when it reported none. | | `updatedAt` | string (date-time) | no | When Hardfin last changed the update. | ## AssetShippingDataListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `eta` | string (date-time), or null | no | When the carrier now expects to deliver, or null when it says nothing. | | `originalEta` | string (date-time), or null | no | When the carrier first expected to deliver, or null when it said nothing. | | `serviceLevelName` | string, or null | no | The carrier's service the shipment travels on, or null when it names none. | | `shippingHistory` | list of [AssetShippingData](schemas.md#assetshippingdata) | no | What the carrier has reported, newest first. | | `trackingNumberDetails` | [CarrierTrackingNumberDetails](schemas.md#carriertrackingnumberdetails), or null | no | Who carries the shipment and the number it is tracked by, or null when neither is named. | ## AssetShippingDataLocation | Field | Type | Required | Description | | --- | --- | --- | --- | | `city` | string | no | The city the carrier reported. | | `country` | string | no | The country the carrier reported. | | `state` | string | no | The state or region the carrier reported. | | `zip` | string | no | The postal code the carrier reported. | ## AssetUpdateMetadataItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `fieldId` | string (uuid) | yes | The ID of the item field to set on the asset. | | `value` | list of any or boolean or number or object or string, or null | no | The field's new value, in the JSON type the field's type calls for, or null to clear it. | ## AssetUsefulLifeRevision | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the revision was recorded. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | The person who recorded the revision. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `effectiveDate` | string (date) | no | The day the new useful life takes effect. | | `key` | string | no | The revision's key. | | `notes` | string, or null | no | Free-form detail about the revision. | | `reason` | [UsefulLifeRevisionReason](schemas.md#usefulliferevisionreason) | no | Why the useful life changed. | | `usefulLifeMonths` | integer | no | The asset's new useful life in months. | ## AttentionEntity The entity type a needs-attention threshold applies to. Inbound and outbound shipments are separate entities because they have different configurable reason catalogs. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `INBOUND_SHIPMENT`, `OUTBOUND_SHIPMENT`. ## AttentionReason A machine-readable predicate describing why an entity needs attention. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DELIVERED_NOT_RECEIVED`, `OPEN_NOT_SHIPPED`, `SHIPPED_NOT_DELIVERED`. ## AttentionSeverity An ordinal severity for the needs-attention signal, which flags a record that has sat in a non-terminal state longer than expected. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CRITICAL`, `NOTICE`, `WARNING`. ## BillingFrequency Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ANNUALLY`, `BIENNIALLY`, `BIWEEKLY`, `DAILY`, `MONTHLY`, `ONCE`, `QUADRENNIALLY`, `QUARTERLY`, `QUINQUENNIALLY`, `SEMIANNUALLY`, `TRIENNIALLY`, `WEEKLY`. ## BillingSchedule Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `MILESTONE`, `PERIODIC`. ## BillingTiming Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ADVANCE`, `ARREARS`. ## Carrier Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `airterra`, `apc_postal`, `apg`, `aramex`, `asendia_us`, `australia_post`, `axlehire`, `better_trucks`, `borderguru`, `boxberry`, `bring`, `canada_post`, `cdl`, `chronopost`, `colissimo`, `collect_plus`, `correios_br`, `correos_espana`, `couriersplease`, `deutsche_post`, `dhl_benelux`, `dhl_ecommerce`, `dhl_express`, `dhl_germany`, `dhl_germany_c2c`, `dpd_de`, `dpd_uk`, `estafeta`, `fastway_australia`, `fedex`, `globegistics`, `gls_us`, `gophr`, `gso`, `hermes_germany_b2c`, `hermes_uk`, `hongkong_post`, `la_poste`, `lasership`, `lso`, `mondial_relay`, `new_zealand_post`, `nippon_express`, `ontrac`, `orangeds`, `other`, `parcel`, `parcelforce`, `passport`, `pcf`, `pitney_bowes`, `poste_italiane`, `posti`, `purolator`, `royal_mail`, `royal_mail_sf`, `rr_donnelley`, `russian_post`, `sendle`, `shippo`, `skypostal`, `stuart`, `swyft`, `uds`, `ups`, `usps`, `veho`, `x_delivery`, `yodel`. ## CarrierTrackingNumberDetails | Field | Type | Required | Description | | --- | --- | --- | --- | | `carrier` | [Carrier](schemas.md#carrier), or null | no | The carrier, or null when none is named. | | `name` | string, or null | no | The carrier's name, which is accepted only when carrier is other. | | `trackingNumber` | string, or null | no | The number the carrier tracks the shipment by, or null when it has none. | ## CarrierTransportReferenceDetails | Field | Type | Required | Description | | --- | --- | --- | --- | | `carrier` | [Carrier](schemas.md#carrier), or null | no | The carrier, or null when none is named. | | `name` | string, or null | no | The carrier's name, which is accepted only when carrier is other. | | `transportReference` | string, or null | no | The transportation reference sent to the 3PL, such as a bill of lading or carrier reference rather than a carrier tracking number, or null when it has none. | ## Charge | Field | Type | Required | Description | | --- | --- | --- | --- | | `actualBillableAt` | string (date-time), or null | no | The moment the charge became billable, or null while it has not. | | `billingEligibleDate` | string (date), or null | no | The day the charge became billable, or null while it has not. | | `cancellationReason` | string, or null | no | Why the charge was cancelled, or null when none was given or it is not cancelled. | | `cancelledAt` | string (date-time), or null | no | The moment the charge was cancelled, or null when it is not cancelled. | | `expectedBillableDate` | string (date), or null | no | The day the charge is planned to become billable, or null when it has no dates yet. | | `id` | string (uuid) | no | The charge's unique identifier. | | `isCustomModified` | boolean | no | True when the charge was split off another charge or a client saved it as custom, and false otherwise. | | `key` | string | no | The charge's key. | | `label` | string | no | The charge's display name, such as the period it covers or the milestone it follows. | | `pricingMode` | [PricingMode](schemas.md#pricingmode) | no | PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. | | `quantity` | integer | no | The number of units the charge bills. | | `sequence` | integer | no | The charge's position among its line item's charges, in ascending order. | | `servicePeriodEnd` | string (date), or null | no | The last day of the period the charge covers. | | `servicePeriodStart` | string (date), or null | no | The first day of the period the charge covers, or null when the charge has no dates yet. | | `status` | [ChargeStatus](schemas.md#chargestatus) | no | PLANNED before the charge can be invoiced, BILLABLE once it can, INVOICED once it is on an invoice, or CANCELLED when it will not be billed. | | `totalPrice` | [Currency](schemas.md#currency) | no | The amount the charge bills. | | `totalPrice.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `totalPrice.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `triggerType` | [ChargeTriggerType](schemas.md#chargetriggertype) | no | TIME when the charge becomes billable on expectedBillableDate, or MANUAL when a person marks it billable. | | `unitPrice` | [Currency](schemas.md#currency), or null | no | The price of one unit behind the charge, or null when totalPrice was not computed from one. | ## ChargeListItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `actualBillableAt` | string (date-time), or null | no | The moment the charge became billable, or null while it has not. | | `cancellationReason` | string, or null | no | Why the charge was cancelled, or null when none was given or it is not cancelled. | | `cancelledAt` | string (date-time), or null | no | The moment the charge was cancelled, or null when it is not cancelled. | | `chargeSchedule` | [BillingSchedule](schemas.md#billingschedule) | no | The line item's schedule: PERIODIC when its charges recur at a regular frequency, or MILESTONE when each follows a project milestone. | | `expectedBillableDate` | string (date), or null | no | The day the charge is planned to become billable, or null when it has no dates yet. | | `id` | string (uuid) | no | The charge's unique identifier. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the charge's line item bills for. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The charge's key. | | `label` | string | no | The charge's display name, such as the period it covers or the milestone it follows. | | `lineItemChargeMode` | [ChargeMode](schemas.md#chargemode) | no | CONFIRMED when a periodic line item has an activation date or the line item is a milestone one, or PENDING when a periodic line item's activation date is not yet known, and a PERIODIC charge can be marked billable only once it is CONFIRMED. | | `lineItemKey` | string | no | The key of the line item the charge belongs to. | | `pricingMode` | [PricingMode](schemas.md#pricingmode) | no | PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. | | `project` | [SparseProject](schemas.md#sparseproject) | no | The project the charge belongs to, which carries the charge's customer. | | `project.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the project is for. | | `project.endOn` | string (date), or null | no | The day the project ends. | | `project.id` | string (uuid) | no | The project's unique identifier. | | `project.integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The project's links to integrated systems. | | `project.isArchived` | boolean | no | Whether the project is archived. | | `project.key` | string | no | The project's key. | | `project.name` | string | no | The project's display name. | | `project.paymentTermLabel` | string, or null | no | The name of the project's payment term. | | `project.purchaseOrderNumber` | string, or null | no | The customer's purchase order number, which new invoices for the project carry. | | `project.startOn` | string (date), or null | no | The day the project starts. | | `project.status` | [ProjectStatus](schemas.md#projectstatus) | no | Whether the project is upcoming, active, or past, judged from its dates. | | `quantity` | integer | no | The number of units the charge bills. | | `servicePeriodEnd` | string (date), or null | no | The last day of the period the charge covers. | | `servicePeriodStart` | string (date), or null | no | The first day of the period the charge covers, or null when the charge has no dates yet. | | `splitCount` | integer | no | The number of its line item's charges that share the charge's label and service period, which is 1 for a charge that was never split. | | `splitIndex` | integer | no | The charge's position, counted from 1 by expected billable date, among its line item's charges that share its label and service period. | | `status` | [ChargeStatus](schemas.md#chargestatus) | no | PLANNED before the charge can be invoiced, BILLABLE once it can, INVOICED once it is on an invoice, or CANCELLED when it will not be billed. | | `totalPrice` | [Currency](schemas.md#currency) | no | The amount the charge bills. | | `totalPrice.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `totalPrice.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `triggerType` | [ChargeTriggerType](schemas.md#chargetriggertype) | no | TIME when the charge becomes billable on expectedBillableDate, or MANUAL when a person marks it billable. | | `unitPrice` | [Currency](schemas.md#currency), or null | no | The price of one unit behind the charge, or null when totalPrice was not computed from one. | ## ChargeMarkedBillable | Field | Type | Required | Description | | --- | --- | --- | --- | | `newCharge` | [Charge](schemas.md#charge), or null | no | The PLANNED charge created for the quantity not billed, or null when the whole charge was billed. | | `updatedCharge` | [Charge](schemas.md#charge) | no | The charge the request named, which holds the quantity billed now and is BILLABLE. | | `updatedCharge.actualBillableAt` | string (date-time), or null | no | The moment the charge became billable, or null while it has not. | | `updatedCharge.billingEligibleDate` | string (date), or null | no | The day the charge became billable, or null while it has not. | | `updatedCharge.cancellationReason` | string, or null | no | Why the charge was cancelled, or null when none was given or it is not cancelled. | | `updatedCharge.cancelledAt` | string (date-time), or null | no | The moment the charge was cancelled, or null when it is not cancelled. | | `updatedCharge.expectedBillableDate` | string (date), or null | no | The day the charge is planned to become billable, or null when it has no dates yet. | | `updatedCharge.id` | string (uuid) | no | The charge's unique identifier. | | `updatedCharge.isCustomModified` | boolean | no | True when the charge was split off another charge or a client saved it as custom, and false otherwise. | | `updatedCharge.key` | string | no | The charge's key. | | `updatedCharge.label` | string | no | The charge's display name, such as the period it covers or the milestone it follows. | | `updatedCharge.pricingMode` | [PricingMode](schemas.md#pricingmode) | no | PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. | | `updatedCharge.quantity` | integer | no | The number of units the charge bills. | | `updatedCharge.sequence` | integer | no | The charge's position among its line item's charges, in ascending order. | | `updatedCharge.servicePeriodEnd` | string (date), or null | no | The last day of the period the charge covers. | | `updatedCharge.servicePeriodStart` | string (date), or null | no | The first day of the period the charge covers, or null when the charge has no dates yet. | | `updatedCharge.status` | [ChargeStatus](schemas.md#chargestatus) | no | PLANNED before the charge can be invoiced, BILLABLE once it can, INVOICED once it is on an invoice, or CANCELLED when it will not be billed. | | `updatedCharge.totalPrice` | [Currency](schemas.md#currency) | no | The amount the charge bills. | | `updatedCharge.totalPrice.amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `updatedCharge.totalPrice.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `updatedCharge.triggerType` | [ChargeTriggerType](schemas.md#chargetriggertype) | no | TIME when the charge becomes billable on expectedBillableDate, or MANUAL when a person marks it billable. | | `updatedCharge.unitPrice` | [Currency](schemas.md#currency), or null | no | The price of one unit behind the charge, or null when totalPrice was not computed from one. | ## ChargeMode Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CONFIRMED`, `PENDING`. ## ChargePage | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [ChargeListItem](schemas.md#chargelistitem) | no | The charges on this page. | | `totalCount` | integer | no | The number of charges the filters match, across every page. | ## ChargeStatus Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `BILLABLE`, `CANCELLED`, `INVOICED`, `PLANNED`. ## ChargeTriggerType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `EVENT`, `MANUAL`, `TIME`. ## CompanyType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CUSTOMER`, `MANUFACTURER`. ## ContactListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [SparseContact](schemas.md#sparsecontact) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## CostAdjustmentReason Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ADDITION`, `BETTERMENT`, `DAMAGE`, `INSTALLATION`, `LIFE_EXTENSION`, `MARKET_DECLINE`, `OBSOLESCENCE`, `OTHER`, `REGULATORY`. ## CostAdjustmentType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CAPITALIZATION`, `IMPAIRMENT`. ## CostBasisMode Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ADVANCED`, `SIMPLE`, or null. ## CredentialType The kind of credential a request was made with. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `API_KEY` | An API key, for an integration that runs unattended | | `OAUTH` | An OAuth access token, issued to an application a person connected | | `SESSION` | A person signed in to Hardfin in a browser | Its value is one of `API_KEY`, `OAUTH`, `SESSION`. ## Currency | Field | Type | Required | Description | | --- | --- | --- | --- | | `amount` | string (decimal) | no | The exact value as a decimal string, sent with at most two decimal places. | | `isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | ## CurrencyCode An ISO 4217 alpha currency code. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CAD`, `EUR`, `GBP`, `USD`. ## Customer | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The customer's unique identifier. | | `isArchived` | boolean | no | Whether the customer is archived. | | `isCustomer` | boolean | no | Whether the company is a customer. | | `isSupplier` | boolean | no | Whether the company is a supplier. | | `key` | string | no | The customer's key, which the customer endpoints take as customerKey. | | `name` | string | no | The customer's display name, unique within your organization in any case. | | `activeProjectCt` | integer | no | The number of the customer's active projects. | | `assetCount` | integer | no | The number of unscrapped assets the customer owns. | | `assetsAtLocation` | integer | no | The number of unscrapped assets at the customer's sites and their zones. | | `billingAddress` | string, or null | no | The address invoices are sent to. | | `billingContact` | [CustomerBillingContact](schemas.md#customerbillingcontact), or null | no | The person who receives the customer's invoices. | | `comment` | string, or null | no | A free-form note about the customer. | | `domain` | string, or null | no | The customer's web domain, used to look up its logo. | | `externalId` | string, or null | no | The customer's identifier in another system. | | `incompleteProjectCt` | integer | no | The number of the customer's projects missing a start or end date. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The customer's links to integrated systems, with a null link for the organization's CRM when the customer is not linked to it. | | `locationCount` | integer | no | The number of the customer's sites. | | `locations` | list of [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The customer's sites. | | `logoFileKey` | string, or null | no | The storage key of the customer's logo file. | | `pastProjectCt` | integer | no | The number of the customer's past projects. | | `upcomingProjectCt` | integer | no | The number of the customer's upcoming projects. | ## CustomerBillingContact | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string, or null | no | The billing contact's email address. | | `name` | string, or null | no | The billing contact's name. | | `phone` | string, or null | no | The billing contact's phone number. | ## CustomerListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [Customer](schemas.md#customer) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## Depreciation Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DOUBLE_DECLINING`, `STRAIGHT_LINE`, `SUM_YEAR`, `UNIT_OF_PRODUCTION`, or null. ## EntityType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ASSET`, `BILLING`, `BILLING_PLAN`, `CHARGE`, `CONTACT`, `COST`, `CUSTOMER`, `FULFILLMENT_ORDER`, `INVOICE`, `ITEM`, `LOCATION`, `ORGANIZATION`, `PERSON`, `PROJECT`, `PURCHASE_ORDER`, `RETURN_ORDER`, `SHIPMENT`, `TIME_RECORD`. ## Error | Field | Type | Required | Description | | --- | --- | --- | --- | | `error` | string | yes | | | `statusCode` | integer | yes | | ## ExchangeGroup | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the exchange was created. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who created the exchange. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `exchangeNumber` | string | no | The number the exchange is known by. | | `fulfillmentOrders` | list of [ExchangeGroupLinkedFulfillmentOrder](schemas.md#exchangegrouplinkedfulfillmentorder) | no | The fulfillment orders that send replacement units, oldest first. | | `id` | string (uuid) | no | The exchange's unique identifier. | | `items` | list of [ExchangeGroupItem](schemas.md#exchangegroupitem) | no | Each item the exchange's orders move. | | `key` | string | no | The exchange's key. | | `lastUpdatedAt` | string (date-time) | no | When the exchange last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | Who last changed the exchange. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `locationPairs` | list of [ExchangeGroupLocationPair](schemas.md#exchangegrouplocationpair) | no | The origin and destination of each of the exchange's orders, return orders first, leaving out a return order whose origin is not known. | | `orderNotes` | string, or null | no | The note the exchange's return order was created with, or null. | | `returnOrders` | list of [ExchangeGroupLinkedReturnOrder](schemas.md#exchangegrouplinkedreturnorder) | no | The return orders that bring units back, oldest first. | | `status` | [ExchangeGroupStatus](schemas.md#exchangegroupstatus) | no | Where the exchange stands: DRAFT, IN_PROGRESS once an order moves past draft, COMPLETE once every live order is received or delivered, or CANCELLED once every order is cancelled. | ## ExchangeGroupDetailedExchangeGroup | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the exchange was created. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who created the exchange. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `exchangeNumber` | string | no | The number the exchange is known by. | | `fulfillmentOrders` | list of [FulfillmentOrder](schemas.md#fulfillmentorder) | no | The fulfillment orders that send replacement units, in full, oldest first. | | `id` | string (uuid) | no | The exchange's unique identifier. | | `items` | list of [ExchangeGroupItem](schemas.md#exchangegroupitem) | no | Each item the exchange's orders move. | | `key` | string | no | The exchange's key. | | `lastUpdatedAt` | string (date-time) | no | When the exchange last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | Who last changed the exchange. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `locationPairs` | list of [ExchangeGroupLocationPair](schemas.md#exchangegrouplocationpair) | no | The origin and destination of each of the exchange's orders, return orders first, leaving out a return order whose origin is not known. | | `orderNotes` | string, or null | no | The note the exchange's return order was created with, or null. | | `returnOrders` | list of [ReturnOrder](schemas.md#returnorder) | no | The return orders that bring units back, in full, oldest first. | | `status` | [ExchangeGroupStatus](schemas.md#exchangegroupstatus) | no | Where the exchange stands: DRAFT, IN_PROGRESS once an order moves past draft, COMPLETE once every live order is received or delivered, or CANCELLED once every order is cancelled. | ## ExchangeGroupItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `fulfillmentQuantity` | [ExchangeGroupQuantities](schemas.md#exchangegroupquantities) | no | The item's units on the exchange's fulfillment orders. | | `fulfillmentQuantity.deliveredQuantity` | integer | no | How many units reached the destination. | | `fulfillmentQuantity.pendingQuantity` | integer, or null | no | How many units the fulfillment orders have not yet shipped, or null on the return side, which has no pending units. | | `fulfillmentQuantity.receivedQuantity` | integer | no | How many units were received at the destination. | | `fulfillmentQuantity.requestedQuantity` | integer | no | How many units the side's orders asked for. | | `fulfillmentQuantity.shippedQuantity` | integer | no | How many units left on a shipment. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `returnQuantity` | [ExchangeGroupQuantities](schemas.md#exchangegroupquantities) | no | The item's units on the exchange's return orders. | | `returnQuantity.deliveredQuantity` | integer | no | How many units reached the destination. | | `returnQuantity.pendingQuantity` | integer, or null | no | How many units the fulfillment orders have not yet shipped, or null on the return side, which has no pending units. | | `returnQuantity.receivedQuantity` | integer | no | How many units were received at the destination. | | `returnQuantity.requestedQuantity` | integer | no | How many units the side's orders asked for. | | `returnQuantity.shippedQuantity` | integer | no | How many units left on a shipment. | ## ExchangeGroupLinkedFulfillmentOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `fromLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site the replacement units ship from. | | `fromLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `fromLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `fromLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `fromLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `fromLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `fromLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `fromLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `fromLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `fromLocation.description` | string, or null | no | A free-form description of a zone. | | `fromLocation.id` | string (uuid) | no | The location's unique identifier. | | `fromLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `fromLocation.isArchived` | boolean | no | Whether the location is archived. | | `fromLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `fromLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `fromLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `fromLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `fromLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `fromLocation.name` | string | no | The location's display name. | | `fromLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `fromLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `fromLocation.zoneCount` | integer | no | The number of zones at a site. | | `fromLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `fromLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `fulfillmentOrderNumber` | string | no | The number the fulfillment order is known by. | | `id` | string (uuid) | no | The fulfillment order's unique identifier. | | `key` | string | no | The fulfillment order's key. | | `status` | [FulfillmentOrderStatus](schemas.md#fulfillmentorderstatus) | no | Where the fulfillment order stands. | | `toLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site the replacement units ship to. | | `toLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `toLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `toLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `toLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `toLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `toLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `toLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `toLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `toLocation.description` | string, or null | no | A free-form description of a zone. | | `toLocation.id` | string (uuid) | no | The location's unique identifier. | | `toLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `toLocation.isArchived` | boolean | no | Whether the location is archived. | | `toLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `toLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `toLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `toLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `toLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `toLocation.name` | string | no | The location's display name. | | `toLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `toLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `toLocation.zoneCount` | integer | no | The number of zones at a site. | | `toLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `toLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## ExchangeGroupLinkedReturnOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `fromLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The site the units come back from, or null when it is not known yet. | | `id` | string (uuid) | no | The return order's unique identifier. | | `key` | string | no | The return order's key. | | `promiseDeliveryDate` | string (date), or null | no | The day the units were promised to arrive, or null. | | `promiseShipDate` | string (date), or null | no | The day the units were promised to ship, or null. | | `returnOrderNumber` | string | no | The number the return order is known by. | | `returnReason` | string, or null | no | The reason the customer gave, or null. | | `returnType` | [ReturnOrderType](schemas.md#returnordertype) | no | Why the items are coming back. | | `status` | [ReturnOrderStatus](schemas.md#returnorderstatus) | no | Where the return order stands. | | `toLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site the units come back to. | | `toLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `toLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `toLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `toLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `toLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `toLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `toLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `toLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `toLocation.description` | string, or null | no | A free-form description of a zone. | | `toLocation.id` | string (uuid) | no | The location's unique identifier. | | `toLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `toLocation.isArchived` | boolean | no | Whether the location is archived. | | `toLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `toLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `toLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `toLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `toLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `toLocation.name` | string | no | The location's display name. | | `toLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `toLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `toLocation.zoneCount` | integer | no | The number of zones at a site. | | `toLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `toLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## ExchangeGroupListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [ExchangeGroup](schemas.md#exchangegroup) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## ExchangeGroupLocationPair | Field | Type | Required | Description | | --- | --- | --- | --- | | `fromLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site the order's units leave. | | `fromLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `fromLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `fromLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `fromLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `fromLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `fromLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `fromLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `fromLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `fromLocation.description` | string, or null | no | A free-form description of a zone. | | `fromLocation.id` | string (uuid) | no | The location's unique identifier. | | `fromLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `fromLocation.isArchived` | boolean | no | Whether the location is archived. | | `fromLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `fromLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `fromLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `fromLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `fromLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `fromLocation.name` | string | no | The location's display name. | | `fromLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `fromLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `fromLocation.zoneCount` | integer | no | The number of zones at a site. | | `fromLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `fromLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `toLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site the order's units arrive at. | | `toLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `toLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `toLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `toLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `toLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `toLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `toLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `toLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `toLocation.description` | string, or null | no | A free-form description of a zone. | | `toLocation.id` | string (uuid) | no | The location's unique identifier. | | `toLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `toLocation.isArchived` | boolean | no | Whether the location is archived. | | `toLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `toLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `toLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `toLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `toLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `toLocation.name` | string | no | The location's display name. | | `toLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `toLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `toLocation.zoneCount` | integer | no | The number of zones at a site. | | `toLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `toLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## ExchangeGroupQuantities | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredQuantity` | integer | no | How many units reached the destination. | | `pendingQuantity` | integer, or null | no | How many units the fulfillment orders have not yet shipped, or null on the return side, which has no pending units. | | `receivedQuantity` | integer | no | How many units were received at the destination. | | `requestedQuantity` | integer | no | How many units the side's orders asked for. | | `shippedQuantity` | integer | no | How many units left on a shipment. | ## ExchangeGroupStatus Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CANCELLED`, `COMPLETE`, `DRAFT`, `IN_PROGRESS`. ## File | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The file's unique identifier. | | `key` | string | no | The file's key, which the file endpoints take as fileKey. | | `mimeType` | string | no | The file's media type, or empty when the upload named none. | | `name` | string | no | The file's name as it was uploaded. | | `size` | integer | no | The file's size in bytes. | | `uploadedAt` | string (date-time) | no | When the file was uploaded. | ## FileNewUpload | Field | Type | Required | Description | | --- | --- | --- | --- | | `fileId` | string (uuid) | no | The uploaded file's unique identifier. | | `fileKey` | string | no | The uploaded file's key, which the file endpoints take as fileKey. | ## FrontendItemType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `BULK`, `DEVICE`, `SERVICE`. ## FulfillmentContactSnapshot | Field | Type | Required | Description | | --- | --- | --- | --- | | `data` | [FulfillmentContactSnapshotData](schemas.md#fulfillmentcontactsnapshotdata) | no | The contact as the 3PL received it. | | `data.company` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the contact belonged to when the order was sent, or null. | | `data.email` | string, or null | no | The contact's email address when the order was sent, or null. | | `data.firstName` | string, or null | no | The contact's first name when the order was sent, or null. | | `data.lastName` | string, or null | no | The contact's last name when the order was sent, or null. | | `data.phone` | string, or null | no | The contact's phone number when the order was sent, or null. | | `savedAt` | string (date-time) | no | When the contact was copied. | ## FulfillmentContactSnapshotData | Field | Type | Required | Description | | --- | --- | --- | --- | | `company` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the contact belonged to when the order was sent, or null. | | `email` | string, or null | no | The contact's email address when the order was sent, or null. | | `firstName` | string, or null | no | The contact's first name when the order was sent, or null. | | `lastName` | string, or null | no | The contact's last name when the order was sent, or null. | | `phone` | string, or null | no | The contact's phone number when the order was sent, or null. | ## FulfillmentCreate | Field | Type | Required | Description | | --- | --- | --- | --- | | `contactId` | string (uuid), or null | no | The ID of the contact the order is for, or null. | | `fileIds` | list of string (uuid), or null | no | The IDs of uploaded files to attach to the order, or null. | | `fromLocationId` | string (uuid) | yes | The ID of the location the order ships from. | | `items` | list of [FulfillmentItem](schemas.md#fulfillmentitem) | yes | The order's line items, from 1 to 50. | | `orderNotes` | string, or null | no | A note about the order, or null. | | `projectId` | string (uuid), or null | no | The ID of the project the order fills, or null when it fills none. Naming a project does not assign the order's assets to it, and assets are assigned to a project in the Hardfin app. | | `promiseDeliveryDate` | string (date), or null | no | The day the order is promised to arrive, or null. | | `promiseShipDate` | string (date), or null | no | The day the order is promised to ship, or null. | | `toLocationId` | string (uuid) | yes | The ID of the location the order ships to, which must differ from fromLocationId. | ## FulfillmentCycleTime | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdToOpenedDays` | string (decimal), or null | no | The days from the order's creation until it opened, or null while it has not opened. | | `firstShipmentShippedToCloseDays` | string (decimal), or null | no | The days from the first shipment shipping until the order closed, or null until both happen. | | `openToFirstShipmentShippedDays` | string (decimal), or null | no | The days from the order opening until its first shipment shipped, or null until both happen. | ## FulfillmentItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `itemId` | string (uuid) | yes | The ID of the physical item the line asks for, which may appear on only one line. | | `requestedQuantity` | integer | yes | How many units of the item the order asks for, above 0 and 1,000,000,000 or less. | ## FulfillmentListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [FulfillmentOrder](schemas.md#fulfillmentorder) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## FulfillmentOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string, or null | no | Why the order was cancelled, or null while it has not been. | | `cancelledAt` | string (date-time), or null | no | When the order was cancelled, or null while it has not been. | | `cancelledBy` | [SparsePerson](schemas.md#sparseperson), or null | no | Who cancelled the order, or null while it has not been cancelled. | | `closedAt` | string (date-time), or null | no | When the order closed, or null while it is open. An order closes at the ship time of the shipment that first covers every line, before delivery, and its status keeps moving after it closes. A 3PL order closes when the 3PL finalizes it. | | `closedAtSource` | [FulfillmentOrderClosedAtSource](schemas.md#fulfillmentorderclosedatsource), or null | no | What closed the order: SHIPMENT_COMPLETE, MANUAL_CLOSE, THIRD_PARTY_FIN or CANCELLED, or null while it is open. | | `closedBy` | [SparsePerson](schemas.md#sparseperson), or null | no | Who closed the order, the system user when it closed on its own, or null while it is open. | | `contact` | [SparseContact](schemas.md#sparsecontact), or null | no | The person at the destination the order is for, or null. | | `createdAt` | string (date-time) | no | When the order was created. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who created the order. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `cycleTime` | [FulfillmentCycleTime](schemas.md#fulfillmentcycletime) | no | How long the order spent in each stage. | | `cycleTime.createdToOpenedDays` | string (decimal), or null | no | The days from the order's creation until it opened, or null while it has not opened. | | `cycleTime.firstShipmentShippedToCloseDays` | string (decimal), or null | no | The days from the first shipment shipping until the order closed, or null until both happen. | | `cycleTime.openToFirstShipmentShippedDays` | string (decimal), or null | no | The days from the order opening until its first shipment shipped, or null until both happen. | | `exchangeGroup` | [SparseExchangeGroup](schemas.md#sparseexchangegroup), or null | no | The exchange the order is part of, or null when it is not part of one. | | `fileCount` | integer | no | How many files are attached to the order. | | `firstShipmentOpenedAt` | string (date-time), or null | no | When the order's first outbound shipment was created, cancelled shipments included, or null while it has none. | | `firstShipmentShippedAt` | string (date-time), or null | no | When the order's first outbound shipment shipped, cancelled shipments included, or null while none has. | | `fromLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration), or null | no | Where the order ships from. | | `fulfillmentOrderNumber` | string | no | The number the fulfillment order is known by. | | `id` | string (uuid) | no | The fulfillment order's unique identifier. | | `items` | list of [FulfillmentOrderItem](schemas.md#fulfillmentorderitem) | no | The order's line items. | | `key` | string | no | The fulfillment order's key, which the fulfillment endpoints take as fulfillmentKey. | | `lastShipmentOpenedAt` | string (date-time), or null | no | When the order's latest outbound shipment was created, cancelled shipments included, or null while it has none. | | `lastShipmentShippedAt` | string (date-time), or null | no | When the order's latest outbound shipment shipped, cancelled shipments included, or null while none has. | | `lastUpdatedAt` | string (date-time) | no | When the order last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | Who last changed the order. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `mostRecentDeliveredAt` | string (date-time), or null | no | When the order's latest shipment that is not cancelled was delivered, or null while none has been. | | `mostRecentShippedAt` | string (date-time), or null | no | When the order's latest shipment that is not cancelled shipped, or null while none has. | | `openedAt` | string (date-time), or null | no | When the order opened, which is when it was sent to a 3PL or when its first shipment was created, or null while it has not. | | `orderDataSnapshot` | [FulfillmentOrderDataSnapshot](schemas.md#fulfillmentorderdatasnapshot), or null | no | What Hardfin sent to a 3PL with the order, or null when it was never sent or named no contact. | | `orderNotes` | string, or null | no | The note written about the order, or null. | | `project` | [SparseProject](schemas.md#sparseproject), or null | no | The project the order fills, or null when it fills none. | | `promiseDeliveryDate` | string (date), or null | no | The day the order is promised to arrive, or null when no one has said. | | `promiseShipDate` | string (date), or null | no | The day the order is promised to ship, or null when no one has said. | | `status` | [FulfillmentOrderStatus](schemas.md#fulfillmentorderstatus) | no | Where the order stands: DRAFT, AWAITING_3PL, CANCELLED, or OPEN, SHIPPED or DELIVERED, each PARTIAL, FULL or OVERAGE against the requested quantities. | | `thirdParty` | [FulfillmentThirdParty](schemas.md#fulfillmentthirdparty) | no | The order's fulfillment by a third-party logistics (3PL) provider and its sync state. | | `thirdParty.hasSyncError` | boolean | no | Whether the last sync with the 3PL provider failed. | | `thirdParty.isEnabled` | boolean | no | Whether the order was sent to a 3PL provider, which then ships it. | | `thirdParty.lastSyncedAt` | string (date-time), or null | no | When Hardfin last checked the order with its 3PL provider, or null when it has never checked. | | `thirdParty.lastUpdateAt` | string (date-time), or null | no | When the 3PL provider last reported a change to the order, or null when it has reported none. | | `thirdParty.syncErrorMessage` | string, or null | no | Why the last sync with the 3PL provider failed, or null when it did not. | | `toLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration), or null | no | Where the order ships to. | ## FulfillmentOrderClosedAtSource Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CANCELLED`, `MANUAL_CLOSE`, `SHIPMENT_COMPLETE`, `THIRD_PARTY_FIN`. ## FulfillmentOrderDataSnapshot | Field | Type | Required | Description | | --- | --- | --- | --- | | `contact` | [FulfillmentContactSnapshot](schemas.md#fulfillmentcontactsnapshot), or null | no | The contact as it stood when the order was sent to a 3PL. | ## FulfillmentOrderItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredQuantity` | integer | no | How many units are on shipments that have been delivered. | | `id` | string (uuid) | no | The line item's unique identifier. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the line asks for. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The line item's key. | | `pendingQuantity` | integer | no | How many units sit on the order's outbound shipments that have not shipped. | | `quarantinedQuantity` | integer | no | How many units a 3PL reported under a serial that conflicts with the asset record, held until someone resolves them. | | `requestedQuantity` | integer | no | How many units of the item the order asks for. | | `shippedQuantity` | integer | no | How many units are on shipments that have shipped and not yet been delivered. | | `status` | [FulfillmentOrderLineItemStatus](schemas.md#fulfillmentorderlineitemstatus) | no | How far the line's units have got, such as OPEN_PARTIAL or DELIVERED_FULL, or DRAFT while none of its units is on a shipment. | ## FulfillmentOrderLineItemStatus Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DELIVERED_FULL`, `DELIVERED_OVERAGE`, `DELIVERED_PARTIAL`, `DRAFT`, `OPEN_FULL`, `OPEN_OVERAGE`, `OPEN_PARTIAL`, `SHIPPED_FULL`, `SHIPPED_OVERAGE`, `SHIPPED_PARTIAL`. ## FulfillmentOrderStatus Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `AWAITING_3PL`, `CANCELLED`, `DELIVERED_FULL`, `DELIVERED_OVERAGE`, `DELIVERED_PARTIAL`, `DRAFT`, `OPEN_FULL`, `OPEN_OVERAGE`, `OPEN_PARTIAL`, `SHIPPED_FULL`, `SHIPPED_OVERAGE`, `SHIPPED_PARTIAL`. ## FulfillmentThirdParty | Field | Type | Required | Description | | --- | --- | --- | --- | | `hasSyncError` | boolean | no | Whether the last sync with the 3PL provider failed. | | `isEnabled` | boolean | no | Whether the order was sent to a 3PL provider, which then ships it. | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last checked the order with its 3PL provider, or null when it has never checked. | | `lastUpdateAt` | string (date-time), or null | no | When the 3PL provider last reported a change to the order, or null when it has reported none. | | `syncErrorMessage` | string, or null | no | Why the last sync with the 3PL provider failed, or null when it did not. | ## HubspotConfiguredPipeline | Field | Type | Required | Description | | --- | --- | --- | --- | | `enabledAt` | string (date-time) | no | When the stage was set up for syncing. | | `isArchived` | boolean | no | Whether HubSpot has archived the stage. | | `isEnabled` | boolean | no | Whether Hardfin syncs deals in the stage. | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last synced deals in the stage, or null before it has. | | `pipelineId` | string | no | The HubSpot deal pipeline's ID. | | `pipelineLabel` | string | no | The pipeline's name in HubSpot. | | `stageId` | string | no | The HubSpot deal stage whose deals Hardfin syncs. | | `stageLabel` | string | no | The stage's name in HubSpot. | | `startDate` | string (date), or null | no | The day the first sync reads deals from, or null when it reads every deal. | ## HubspotSetupStep | Field | Type | Required | Description | | --- | --- | --- | --- | | `completed` | boolean | no | Whether the step is done. | | `id` | string | no | The representation of the page that this setup is referencing | ## HubspotStateConfig | Field | Type | Required | Description | | --- | --- | --- | --- | | `allScopesPresent` | boolean | no | Whether the connection granted every permission Hardfin asks HubSpot for. | | `configuredPipelines` | list of [HubspotConfiguredPipeline](schemas.md#hubspotconfiguredpipeline) | no | | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last refreshed deals from HubSpot, or null before it has. | | `steps` | list of [HubspotSetupStep](schemas.md#hubspotsetupstep) | no | | ## IntegrationCategory Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CRM`, `ERP`. ## IntegrationID Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `HUBSPOT`, `NETSUITE`, `NONE`, `QBO`, `SFDC`. ## IntegrationType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `HUBSPOT`, `NETSUITE`, `NONE`, `QBO`, `SFDC`. ## InventoryAdjustmentDirection Whether an inventory adjustment adds stock or removes it. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DECREASE`, `INCREASE`. ## InventoryAssemblyInventoryItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `inventory` | list of [InventoryEntry](schemas.md#inventoryentry) | no | The assemblies at each location at the site that holds some, the site itself first and then its zones by name. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the assemblies build. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site that holds the assemblies. | | `location.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `location.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `location.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `location.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `location.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `location.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `location.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `location.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `location.description` | string, or null | no | A free-form description of a zone. | | `location.id` | string (uuid) | no | The location's unique identifier. | | `location.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `location.isArchived` | boolean | no | Whether the location is archived. | | `location.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `location.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `location.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `location.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `location.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `location.name` | string | no | The location's display name. | | `location.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `location.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `location.zoneCount` | integer | no | The number of zones at a site. | | `location.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `location.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## InventoryAssemblyInventoryResponse | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [InventoryAssemblyInventoryItem](schemas.md#inventoryassemblyinventoryitem) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## InventoryAssetEntry | Field | Type | Required | Description | | --- | --- | --- | --- | | `count` | integer | no | The number of assets at the location. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site or zone the assets are at, or the group's in-transit location. | | `location.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `location.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `location.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `location.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `location.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `location.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `location.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `location.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `location.description` | string, or null | no | A free-form description of a zone. | | `location.id` | string (uuid) | no | The location's unique identifier. | | `location.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `location.isArchived` | boolean | no | Whether the location is archived. | | `location.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `location.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `location.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `location.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `location.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `location.name` | string | no | The location's display name. | | `location.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `location.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `location.zoneCount` | integer | no | The number of zones at a site. | | `location.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `location.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `serials` | list of string | no | The assets' serial numbers sorted without regard to case, and empty when the request excludes serials. | ## InventoryAssetsInventoryResponse | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [InventoryGroupedAssetInventoryItem](schemas.md#inventorygroupedassetinventoryitem) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## InventoryBulkItemInventoryItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `inventory` | list of [InventoryEntry](schemas.md#inventoryentry) | no | The units at each location at the site that holds some, the site itself first and then its zones by name. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The bulk item. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site that holds the stock. | | `location.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `location.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `location.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `location.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `location.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `location.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `location.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `location.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `location.description` | string, or null | no | A free-form description of a zone. | | `location.id` | string (uuid) | no | The location's unique identifier. | | `location.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `location.isArchived` | boolean | no | Whether the location is archived. | | `location.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `location.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `location.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `location.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `location.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `location.name` | string | no | The location's display name. | | `location.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `location.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `location.zoneCount` | integer | no | The number of zones at a site. | | `location.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `location.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## InventoryBulkItemInventoryResponse | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [InventoryBulkItemInventoryItem](schemas.md#inventorybulkiteminventoryitem) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## InventoryEntry | Field | Type | Required | Description | | --- | --- | --- | --- | | `count` | integer | no | The number of units at the location. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site or zone that holds the units. | | `location.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `location.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `location.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `location.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `location.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `location.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `location.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `location.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `location.description` | string, or null | no | A free-form description of a zone. | | `location.id` | string (uuid) | no | The location's unique identifier. | | `location.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `location.isArchived` | boolean | no | Whether the location is archived. | | `location.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `location.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `location.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `location.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `location.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `location.name` | string | no | The location's display name. | | `location.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `location.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `location.zoneCount` | integer | no | The number of zones at a site. | | `location.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `location.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## InventoryGroupedAssetInventoryItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `functionalStatus` | string | no | FUNCTIONAL, NON_FUNCTIONAL, NEEDS_REVIEW, or SCRAPPED, and empty for assets with no status. | | `inventory` | list of [InventoryAssetEntry](schemas.md#inventoryassetentry) | no | The assets at each location at the site that holds some, the site itself first and then its zones by name, or one entry for an in-transit group. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the assets are. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site the assets are at, or an in-transit location with a nil ID and the key IN_TRANSIT_TO_INVENTORY or IN_TRANSIT_TO_FIELD. | | `location.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `location.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `location.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `location.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `location.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `location.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `location.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `location.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `location.description` | string, or null | no | A free-form description of a zone. | | `location.id` | string (uuid) | no | The location's unique identifier. | | `location.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `location.isArchived` | boolean | no | Whether the location is archived. | | `location.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `location.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `location.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `location.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `location.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `location.name` | string | no | The location's display name. | | `location.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `location.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `location.zoneCount` | integer | no | The number of zones at a site. | | `location.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `location.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## InventoryLocationInventoryItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | [InventoryLocationInventoryItems](schemas.md#inventorylocationinventoryitems) | no | The inventory of the requested kind at the location. | | `items.assemblies` | list of [InventoryAssemblyInventoryItem](schemas.md#inventoryassemblyinventoryitem) | no | The unbound assemblies at the location. | | `items.assets` | list of [InventoryGroupedAssetInventoryItem](schemas.md#inventorygroupedassetinventoryitem) | no | The asset groups at the location. | | `items.bulkItems` | list of [InventoryBulkItemInventoryItem](schemas.md#inventorybulkiteminventoryitem) | no | The bulk item stock at the location. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | The site or zone the entry holds, or an in-transit location with a nil ID and the key IN_TRANSIT_TO_INVENTORY or IN_TRANSIT_TO_FIELD. | | `location.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `location.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `location.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `location.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `location.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `location.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `location.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `location.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `location.description` | string, or null | no | A free-form description of a zone. | | `location.id` | string (uuid) | no | The location's unique identifier. | | `location.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `location.isArchived` | boolean | no | Whether the location is archived. | | `location.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `location.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `location.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `location.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `location.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `location.name` | string | no | The location's display name. | | `location.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `location.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `location.zoneCount` | integer | no | The number of zones at a site. | | `location.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `location.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## InventoryLocationInventoryItems | Field | Type | Required | Description | | --- | --- | --- | --- | | `assemblies` | list of [InventoryAssemblyInventoryItem](schemas.md#inventoryassemblyinventoryitem) | no | The unbound assemblies at the location. | | `assets` | list of [InventoryGroupedAssetInventoryItem](schemas.md#inventorygroupedassetinventoryitem) | no | The asset groups at the location. | | `bulkItems` | list of [InventoryBulkItemInventoryItem](schemas.md#inventorybulkiteminventoryitem) | no | The bulk item stock at the location. | ## InventoryLocationInventoryResponse | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [InventoryLocationInventoryItem](schemas.md#inventorylocationinventoryitem) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## InventoryLot | Field | Type | Required | Description | | --- | --- | --- | --- | | `batch` | [SparseBatch](schemas.md#sparsebatch) | no | The receipt the lot came from. | | `batch.id` | string (uuid) | no | The batch's ID. | | `batch.receiveType` | one of `PURCHASE`, `TRANSFER`, `ADJUSTMENT`, `SHIPMENT` | no | How the batch arrived: SHIPMENT when a shipment was received, or ADJUSTMENT when an inventory adjustment added it. PURCHASE and TRANSFER are reserved and not written today. | | `batch.receivedAt` | string (date-time) | no | When the batch was received into inventory. | | `batch.receivedQuantity` | integer | no | The number of units the batch arrived with. | | `batch.shipmentReference` | string, or null | no | The external reference on the shipment line that brought the batch in, and null when there is none. | | `id` | string (uuid) | no | The lot's ID. | | `quantity` | integer | no | The number of units left in the lot at the location. | ## InventoryLotsResponse | Field | Type | Required | Description | | --- | --- | --- | --- | | `lots` | list of [InventoryLot](schemas.md#inventorylot) | no | The bulk item's lots at the location. | ## Item | Field | Type | Required | Description | | --- | --- | --- | --- | | `acceptsBulkSerials` | boolean | no | Whether a BULK item records serial numbers on its units, which is false for SERVICE and DEVICE items. | | `assetCount` | integer, or null | no | The number of unscrapped assets of a DEVICE item, and null for other types. | | `description` | string, or null | no | A free-form description of the item. | | `id` | string (uuid) | no | The item's unique identifier. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The item's links to integrated systems. | | `isArchived` | boolean | no | Whether the item is archived. | | `key` | string | no | The item's key, which the item endpoints take as itemKey. | | `lastUpdatedAt` | string (date-time), or null | no | When the item was last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | The person who last changed the item. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `name` | string | no | The item's display name, unique within your organization in any case. | | `shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in, which is EA for SERVICE and DEVICE items. | ## ItemAccounting | Field | Type | Required | Description | | --- | --- | --- | --- | | `allocatedIndirect` | [Currency](schemas.md#currency), or null | no | The default share of overhead for one unit. | | `billOfMaterials` | [Currency](schemas.md#currency), or null | no | The default parts cost for one unit. | | `costCurrencyCode` | [CurrencyCode](schemas.md#currencycode), or null | no | The ISO 4217 code the default cost amounts are denominated in, or null when none is recorded. | | `depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The default method one unit is depreciated by. | | `directLabor` | [Currency](schemas.md#currency), or null | no | The default labor cost to build one unit. | | `freightInbound` | [Currency](schemas.md#currency), or null | no | The default shipping cost to receive one unit. | | `freightOutbound` | [Currency](schemas.md#currency), or null | no | The default shipping cost to deliver one unit. | | `installation` | [Currency](schemas.md#currency), or null | no | The default cost to install one unit. | | `interest` | [Currency](schemas.md#currency), or null | no | The default financing cost for one unit. | | `salvageValue` | [Currency](schemas.md#currency), or null | no | The default value one unit keeps at the end of its useful life. | | `simpleCostBasis` | [Currency](schemas.md#currency), or null | no | A single default cost for one unit, used instead of the cost components. | | `tariffs` | [Currency](schemas.md#currency), or null | no | The default import duty paid on one unit. | | `tax` | [Currency](schemas.md#currency), or null | no | The default tax paid on one unit. | | `totalCOGS` | [Currency](schemas.md#currency), or null | no | The default cost of goods sold for one unit, which is the simple cost basis when set and otherwise the sum of the cost components. | | `usefulLife` | integer, or null | no | The default number of months one unit is depreciated over. | ## ItemBOMItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `item` | [SparseItem](schemas.md#sparseitem) | no | The BULK part the bill of materials uses. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `quantity` | integer | no | The number of the part one unit of the item uses. | ## ItemDetail | Field | Type | Required | Description | | --- | --- | --- | --- | | `acceptsBulkSerials` | boolean | no | Whether a BULK item records serial numbers on its units, which is false for SERVICE and DEVICE items. | | `accounting` | [ItemAccounting](schemas.md#itemaccounting) | no | The default costs and depreciation for a unit of a DEVICE item. | | `accounting.allocatedIndirect` | [Currency](schemas.md#currency), or null | no | The default share of overhead for one unit. | | `accounting.billOfMaterials` | [Currency](schemas.md#currency), or null | no | The default parts cost for one unit. | | `accounting.costCurrencyCode` | [CurrencyCode](schemas.md#currencycode), or null | no | The ISO 4217 code the default cost amounts are denominated in, or null when none is recorded. | | `accounting.depreciationModel` | [Depreciation](schemas.md#depreciation) | no | The default method one unit is depreciated by. | | `accounting.directLabor` | [Currency](schemas.md#currency), or null | no | The default labor cost to build one unit. | | `accounting.freightInbound` | [Currency](schemas.md#currency), or null | no | The default shipping cost to receive one unit. | | `accounting.freightOutbound` | [Currency](schemas.md#currency), or null | no | The default shipping cost to deliver one unit. | | `accounting.installation` | [Currency](schemas.md#currency), or null | no | The default cost to install one unit. | | `accounting.interest` | [Currency](schemas.md#currency), or null | no | The default financing cost for one unit. | | `accounting.salvageValue` | [Currency](schemas.md#currency), or null | no | The default value one unit keeps at the end of its useful life. | | `accounting.simpleCostBasis` | [Currency](schemas.md#currency), or null | no | A single default cost for one unit, used instead of the cost components. | | `accounting.tariffs` | [Currency](schemas.md#currency), or null | no | The default import duty paid on one unit. | | `accounting.tax` | [Currency](schemas.md#currency), or null | no | The default tax paid on one unit. | | `accounting.totalCOGS` | [Currency](schemas.md#currency), or null | no | The default cost of goods sold for one unit, which is the simple cost basis when set and otherwise the sum of the cost components. | | `accounting.usefulLife` | integer, or null | no | The default number of months one unit is depreciated over. | | `assetCount` | integer, or null | no | The number of unscrapped assets of a DEVICE item, and null for other types. | | `bom` | list of [ItemBOMItem](schemas.md#itembomitem), or null | no | The bill of materials, the BULK parts one unit of the item is built from, or null when it has none. | | `defaultPricing` | [ItemPricing](schemas.md#itempricing), or null | no | The pricing a project line item's billing plan starts from when it sells the item, or null when the item has none. | | `description` | string, or null | no | A free-form description of the item. | | `fields` | list of [ItemField](schemas.md#itemfield) | no | The custom fields each asset of a DEVICE item can hold. | | `hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `id` | string (uuid) | no | The item's unique identifier. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The item's links to integrated systems. | | `inventoryMovementCount` | integer, or null | no | The number of inventory movements of a BULK item, and null for other types. | | `isArchived` | boolean | no | Whether the item is archived. | | `isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `key` | string | no | The item's key, which the item endpoints take as itemKey. | | `lastUpdatedAt` | string (date-time), or null | no | When the item was last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | The person who last changed the item. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `name` | string | no | The item's display name, unique within your organization in any case. | | `shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in, which is EA for SERVICE and DEVICE items. | ## ItemField | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The field's unique identifier. | | `key` | string | no | The field's key, which the item field endpoints take as fieldKey. | | `label` | string | no | The field's display name. | | `metadataCount` | integer | no | The number of assets that hold a value for the field. | | `order` | integer | no | The field's position within its section, starting at 0. | | `section` | integer | no | The group the field is shown in, starting at 0. | | `type` | [ItemFieldType](schemas.md#itemfieldtype) | no | The kind of value the field holds. | ## ItemFieldOrderingUpdateItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `fieldId` | string (uuid) | yes | The ID of the item field to move. | | `order` | integer | no | The field's position within its section, starting at 0. | | `section` | integer | no | The group the field is shown in, starting at 0. | ## ItemFieldType The kind of value an item's custom field holds. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `BOOLEAN`, `DATE`, `DATE_TIME`, `INTEGER`, `MULTILINE_TEXT`, `NUMBER`, `TEXT`, `TIME`. ## ItemListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [Item](schemas.md#item) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## ItemPricing | Field | Type | Required | Description | | --- | --- | --- | --- | | `chargeFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a PERIODIC charge recurs. | | `chargeSchedule` | [BillingSchedule](schemas.md#billingschedule), or null | no | PERIODIC to charge on a recurring cadence, or MILESTONE to charge when a milestone is reached. | | `fixedPrice` | [Currency](schemas.md#currency), or null | no | The default price for the whole line, used when pricingMode is FIXED. | | `invoiceFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often the charges are invoiced. | | `invoiceMode` | [BillingTiming](schemas.md#billingtiming), or null | no | ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends. | | `pricingMode` | [PricingMode](schemas.md#pricingmode), or null | no | PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price for the line whatever its quantity. | | `unitPrice` | [Currency](schemas.md#currency), or null | no | The default price for each unit, used when pricingMode is PER_UNIT. | ## ItemType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `marked_bulk`, `service`, `tracked_device`, `unmarked_bulk`. ## LedgerAccountType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `FA_ACCUMULATED_DEPRECIATION`, `FA_CAPITALIZED_DEPLOYMENT`, `FA_DEPRECIATION`, `FA_DISPOSAL_CLEARING`, `FA_DISPOSAL_GAIN`, `FA_DISPOSAL_LOSS`, `FA_FIXED_ASSETS`, `INV_CLEARING`, `INV_COGS`, `INV_INVENTORY`, `INV_WRITE_OFF`, `ONBOARDING_ADJUSTMENT`. ## Location | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `archivedZoneCount` | integer | no | The number of archived zones at a site. | | `consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `description` | string, or null | no | A free-form description of a zone. | | `id` | string (uuid) | no | The location's unique identifier. | | `isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `isArchived` | boolean | no | Whether the location is archived. | | `isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `key` | string | no | The location's key, which the location endpoints take as locationKey. | | `name` | string | no | The location's display name. | | `thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `zoneCount` | integer | no | The number of zones at a site. | | `zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The location's links to integrated systems. | | `activeProjectCount` | integer | no | The number of active projects at the location. | | `assetCount` | integer | no | The number of assets currently at the location. | | `incompleteProjectCount` | integer | no | The number of incomplete projects at the location. | | `pastProjectCount` | integer | no | The number of past projects at the location. | | `upcomingProjectCount` | integer | no | The number of upcoming projects at the location. | ## LocationListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [Location](schemas.md#location) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## LocationType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `SITE`, `ZONE`, or null. ## MessageType What a notification says happened. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ASSET_SUMMARY`, `FULFILLMENT_ORDER_CANCELLED`, `FULFILLMENT_ORDER_DELIVERED`, `FULFILLMENT_ORDER_SHIPPED`, `INBOUND_SHIPMENT_DELIVERED`, `INBOUND_SHIPMENT_RECEIVED`, `INBOUND_SHIPMENT_SHIPPED`, `OUTBOUND_SHIPMENT_DELIVERED`, `OUTBOUND_SHIPMENT_SHIPPED`, `PURCHASE_ORDER_CANCELLED`, `PURCHASE_ORDER_DELIVERED`, `PURCHASE_ORDER_RECEIVED`, `PURCHASE_ORDER_SHIPPED`, `RETURN_ORDER_CANCELLED`, `RETURN_ORDER_DELIVERED`, `RETURN_ORDER_RECEIVED`, `RETURN_ORDER_SHIPPED`. ## Metadata | Field | Type | Required | Description | | --- | --- | --- | --- | | `errors` | list of [Error](schemas.md#error), or null | yes | | | `notices` | list of [Notice](schemas.md#notice) | no | What the client should know about its request, beside any error. A notice never fails a request. | | `requestId` | string | yes | The identifier to quote when asking Hardfin about this request. | | `requestTime` | string | yes | How long the server took to answer. | | `statusCode` | integer | yes | | ## MetadataLocationComponents | Field | Type | Required | Description | | --- | --- | --- | --- | | `addressLine1` | string, or null | no | The first line of the street address. | | `addressLine2` | string, or null | no | The second line of the street address, such as a suite. | | `city` | string, or null | no | The city. | | `country` | string, or null | no | The country. | | `formattedAddress` | string, or null | no | The whole address on one line. | | `postalCode` | string, or null | no | The postal or ZIP code. | | `state` | string, or null | no | The state or region. | ## MetadataLocationSite | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `shippingName` | string, or null | no | The person or business that receives shipments at the location. | ## MetadataMilestonePhaseEntry | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | no | The phase's name, which its charge takes as a label, 255 characters or less. | | `percentage` | string (decimal), or null | no | The share of the line item's total the phase bills, from 0 to 100. | ## MetadataMilestonePhases | Field | Type | Required | Description | | --- | --- | --- | --- | | `entries` | list of [MetadataMilestonePhaseEntry](schemas.md#metadatamilestonephaseentry) | no | The phases, in order. | | `mode` | string | no | PERCENTAGE, the only way a phase's share is expressed. | ## NonNegativeCurrency | Field | Type | Required | Description | | --- | --- | --- | --- | | `amount` | string (decimal) | no | The exact value as a decimal string, which cannot be negative, sent with at most two decimal places. | | `isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | ## Note | Field | Type | Required | Description | | --- | --- | --- | --- | | `content` | string | no | The note's text. | | `createdAt` | string (date-time) | no | When the note was written. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who wrote the note. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `id` | string (uuid) | no | The note's unique identifier. | | `key` | string | no | The note's key, which the note endpoints take as noteKey. | | `lastUpdatedAt` | string (date-time) | no | When the note last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | Who last changed the note. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | ## Notice | Field | Type | Required | Description | | --- | --- | --- | --- | | `code` | string | yes | What the notice is about. API_VERSION_OUTDATED means X-API-Version is behind the endpoint's last change. UNKNOWN_FIELD means the request sent a query parameter or body field the endpoint does not read, and it was ignored. Ignore a code that is not recognized. | | `field` | string | no | The query parameter, or the body field's path, that the endpoint ignored. Sent with UNKNOWN_FIELD only, and left out of the notice that counts the unknown fields past the first 20. | | `latestVersion` | string (date) | no | The X-API-Version to move to so the notice stops. Sent with API_VERSION_OUTDATED only. | | `message` | string | yes | A sentence describing the notice for a person to read. | ## NotificationChannel A way a person receives a notification. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `EMAIL`, `IN_APP`, `SLACK`. ## NotificationConfiguration | Field | Type | Required | Description | | --- | --- | --- | --- | | `activeChannels` | list of [NotificationChannel](schemas.md#notificationchannel) | no | Which channels the user has selected to receive notifications on | | `channels` | list of [NotificationChannel](schemas.md#notificationchannel) | no | Which channels the user can receive the notification on | | `id` | string | no | | | `messageType` | [MessageType](schemas.md#messagetype) | no | What the notification says happened | ## NotificationUpdate | Field | Type | Required | Description | | --- | --- | --- | --- | | `updates` | list of [NotificationUpdateItem](schemas.md#notificationupdateitem) | no | | ## NotificationUpdateItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `activeChannels` | list of [NotificationChannel](schemas.md#notificationchannel) | no | | | `messageType` | [MessageType](schemas.md#messagetype) | no | What the notification says happened | ## Organization | Field | Type | Required | Description | | --- | --- | --- | --- | | `accessEndDate` | string (date), or null | no | The first day on which the organization has no access, if one is recorded | | `assetMarker` | string, or null | no | An optional reference to the organization's asset marker | | `availableIntegrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | | | `billingAddress` | string, or null | no | The default bill-from address used for new invoices | | `billingContact` | [PersonOrganizationMember](schemas.md#personorganizationmember), or null | no | The member registered for billing questions, if one is recorded | | `contractContact` | [PersonOrganizationMember](schemas.md#personorganizationmember), or null | no | The member registered for contract questions, if one is recorded | | `defaultCurrency` | [CurrencyCode](schemas.md#currencycode) | no | The organization's invoicing default currency | | `defaultInvoiceMemo` | string, or null | no | The default customer-facing memo copied onto new invoices | | `defaultOriginLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The organization's default origin location, if set | | `defaultPaymentInstructions` | string, or null | no | The default remittance text copied onto new invoices | | `defaultPaymentTerm` | [PaymentTerm](schemas.md#paymentterm), or null | no | The fallback payment term used when a project has none | | `defaultReceiveLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The organization's default receive location, if set | | `defaultReturnLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The organization's default return location, if set | | `enabledIntegrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | | | `iconFileKey` | string, or null | no | An optional reference to the organization's icon file | | `id` | string | no | The unique identifier for the organization | | `integrationConfigurations` | list of [OrganizationIntegrationConfigurationEntry](schemas.md#organizationintegrationconfigurationentry) | no | | | `invoiceNumberPrefix` | string, or null | no | The prefix for future auto-generated invoice numbers | | `key` | string | no | A human-readable unique identifier for the organization | | `logoFileKey` | string, or null | no | An optional reference to the organization's logo file | | `name` | string | no | The display name of the organization | | `plan` | [PlanType](schemas.md#plantype) | no | Accepted in any case. The listed spelling is the one the API sends back. | | `serialPatterns` | list of [SerialPatternSpec](schemas.md#serialpatternspec) | no | | | `subscriptionEndDate` | string (date), or null | no | The last day of the organization's subscription, if one is recorded | | `subscriptionPhase` | string | no | ACTIVE, GRACE, or ENDED: where today, in the organization's timezone, falls against the subscription end date and the access end date | | `timezone` | string | no | The organization's preferred timezone for displaying dates and times | | `usesThirdPartyFulfillment` | boolean | no | | | `weightedAverageCostOfCapital` | string (decimal) | no | The organization's weighted average cost of capital expressed as a decimal in [0.01, 1.00] (1% .. 100%). Used by the billing lifecycle calculation to compute carrying costs. | ## OrganizationAttentionThresholdEntry | Field | Type | Required | Description | | --- | --- | --- | --- | | `criticalDays` | integer | no | How many whole days make it critical, at least warningDays. | | `entity` | [AttentionEntity](schemas.md#attentionentity) | no | The kind of record the reason applies to. | | `noticeDays` | integer | no | How many whole days in the reason's state make the record a notice, 0 or more. | | `reason` | [AttentionReason](schemas.md#attentionreason) | no | The attention reason to override. | | `warningDays` | integer | no | How many whole days make it a warning, at least noticeDays. | ## OrganizationAttentionThresholdSetting | Field | Type | Required | Description | | --- | --- | --- | --- | | `default` | [OrganizationAttentionThresholdTiers](schemas.md#organizationattentionthresholdtiers) | no | The day counts Hardfin uses when the organization stores no override. | | `default.criticalDays` | integer | no | How many whole days make it critical, at least warningDays. | | `default.noticeDays` | integer | no | How many whole days in the reason's state make the record a notice. | | `default.warningDays` | integer | no | How many whole days make it a warning, at least noticeDays. | | `entity` | [AttentionEntity](schemas.md#attentionentity) | no | The kind of record the reason applies to. | | `override` | [OrganizationAttentionThresholdTiers](schemas.md#organizationattentionthresholdtiers), or null | no | The organization's own day counts, or null when it uses the default. | | `reason` | [AttentionReason](schemas.md#attentionreason) | no | Why the record needs attention. | ## OrganizationAttentionThresholdTiers | Field | Type | Required | Description | | --- | --- | --- | --- | | `criticalDays` | integer | no | How many whole days make it critical, at least warningDays. | | `noticeDays` | integer | no | How many whole days in the reason's state make the record a notice. | | `warningDays` | integer | no | How many whole days make it a warning, at least noticeDays. | ## OrganizationAttentionThresholds | Field | Type | Required | Description | | --- | --- | --- | --- | | `thresholds` | list of [OrganizationAttentionThresholdSetting](schemas.md#organizationattentionthresholdsetting) | no | | ## OrganizationExternalUser | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the external user was created | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | The person who created this external user | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `email` | string | no | The email address of the external user | | `firstName` | string, or null | no | The first name of the external user | | `id` | string (uuid) | no | The unique identifier for the external user | | `key` | string | no | A human-readable unique identifier for the external user | | `label` | string | no | A descriptive label for the external user | | `lastName` | string, or null | no | The last name of the external user | | `lastUpdatedAt` | string (date-time) | no | When the external user was last updated | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | The person who last updated this external user | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `notifications` | list of [NotificationConfiguration](schemas.md#notificationconfiguration) | no | | ## OrganizationIntegrationConfigurationEntry | Field | Type | Required | Description | | --- | --- | --- | --- | | `configurationState` | list of any or boolean or number or object or string, or null | no | The integration's setup state, in the shape type names. | | `createdAt` | string (date-time) | no | When the integration was connected. | | `id` | string (uuid) | no | The connection's identifier. | | `name` | string | no | The connection's name. | | `type` | [IntegrationType](schemas.md#integrationtype) | no | The integrated system, which decides the shape of configurationState. | ## OrganizationLedgerAccounts | Field | Type | Required | Description | | --- | --- | --- | --- | | `ledgerAccounts` | object | no | | ## OrganizationQuickBooksIntegrationState | Field | Type | Required | Description | | --- | --- | --- | --- | | `allScopesPresent` | boolean | no | Whether the connection granted every permission Hardfin asks QuickBooks for. | | `companyName` | string, or null | no | The QuickBooks company's name, or null when QuickBooks did not send one. | | `connected` | boolean | no | Whether the organization's QuickBooks connection is active. | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last synced items from QuickBooks, or null before it has. | | `realmId` | string, or null | no | The QuickBooks company's ID. | ## OrganizationSalesforceConfiguration | Field | Type | Required | Description | | --- | --- | --- | --- | | `allScopesPresent` | boolean | no | Whether the connection granted every permission Hardfin asks Salesforce for. | | `connected` | boolean | no | Whether the organization's Salesforce connection is active. | | `connectedAt` | string (date-time), or null | no | When Salesforce was connected, or null before it connects. | | `enabled` | boolean | no | Whether Hardfin has turned Salesforce on for the organization. | | `instanceUrl` | string, or null | no | The Salesforce instance the organization connected, or null before it connects. | | `integrationDriver` | string, or null | no | | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last refreshed from Salesforce, or null before it has. | | `steps` | list of [OrganizationSetupStep](schemas.md#organizationsetupstep) | no | | ## OrganizationSetupStep | Field | Type | Required | Description | | --- | --- | --- | --- | | `completed` | boolean | no | Whether the step is done. | | `id` | string | no | The representation of the page that this setup is referencing | ## PaymentTerm | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The payment term's identifier. | | `key` | string | no | The payment term's key. | | `label` | string | no | The payment term's name as people read it. | | `netDays` | integer | no | The number of days after the invoice date that payment is due. | | `value` | string | no | The payment term's machine name. | ## Person | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string, or null | no | The person's primary email address used for communication and identification. | | `firstName` | string, or null | no | The person's first name | | `id` | string (uuid) | no | The unique identifier (UUID) for the person | | `key` | string | no | A human-readable unique identifier for the person | | `lastName` | string, or null | no | The person's last name | ## PersonOrganizationMember | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string, or null | no | The person's primary email address used for communication and identification. | | `firstName` | string, or null | no | The person's first name | | `id` | string (uuid) | no | The unique identifier (UUID) for the person | | `key` | string | no | A human-readable unique identifier for the person | | `lastName` | string, or null | no | The person's last name | | `defaultRate` | one of object, object | no | The hourly rate the member's time is charged at, or null when none is set. Sent as REMOVED with a null value unless the caller's role grants `view` on `time.rate`. | | `isAdmin` | boolean | no | Whether the member is an administrator of the organization. | | `isDeactivated` | boolean | no | Whether the member's access to the organization is turned off. | | `lastAdminStatusChangeAt` | string (date-time) | no | When the member was last promoted or demoted. | | `lastDeactivationChangeAt` | string (date-time) | no | When the member was last activated or deactivated. | | `userGroup` | one of object, object | no | The permission group the member acts with: ADMIN, FULL_ACCESS, STANDARD or NONE. Sent as REMOVED with a null value unless the caller's role grants `view` on `organization.admin`. | ## PlanType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `FREE`, `PAID`. ## PricingMode Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `FIXED`, `PER_UNIT`. ## Project | Field | Type | Required | Description | | --- | --- | --- | --- | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the project is for. | | `endOn` | string (date), or null | no | The day the project ends. | | `id` | string (uuid) | no | The project's unique identifier. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The project's links to integrated systems. | | `isArchived` | boolean | no | Whether the project is archived. | | `key` | string | no | The project's key. | | `name` | string | no | The project's display name. | | `paymentTermLabel` | string, or null | no | The name of the project's payment term. | | `purchaseOrderNumber` | string, or null | no | The customer's purchase order number, which new invoices for the project carry. | | `startOn` | string (date), or null | no | The day the project starts. | | `status` | [ProjectStatus](schemas.md#projectstatus) | no | Whether the project is upcoming, active, or past, judged from its dates. | | `acceptanceDate` | string (date), or null | no | The day the customer accepted the project. | | `activeWorkflow` | [SparseActiveWorkflow](schemas.md#sparseactiveworkflow), or null | no | The workflow the project is on, with the project's current stage marked active, or null when it has no workflow. | | `annualRecurringRevenue` | list of [Currency](schemas.md#currency) | no | The project's annual recurring revenue, with one total for each currency its recurring line items are priced in. | | `billingAddress` | string, or null | no | The billing address the project's invoices use in place of the customer's. | | `billingContactEmail` | string, or null | no | The billing contact email the project's invoices use in place of the customer's. | | `billingContactName` | string, or null | no | The billing contact name the project's invoices use in place of the customer's. | | `billingContactPhone` | string, or null | no | The billing contact phone number the project's invoices use in place of the customer's. | | `chargeCount` | integer | no | The number of charges on the project's line items. | | `completionClassification` | [ProjectCompletionClassification](schemas.md#projectcompletionclassification) | no | What follows the project for its customer: it was renewed, the customer kept a later-ending project, or nothing followed. | | `contractSignedOn` | string (date), or null | no | The day the contract was signed. | | `costCount` | integer | no | The number of costs recorded against the project. | | `currency` | [ProjectCurrency](schemas.md#projectcurrency), or null | no | The project's single currency and the field that established it, or null when no currency-bearing field is set. | | `defaultLocation` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The project's default location, which counts among its locations even when no line item names it. | | `description` | string, or null | no | The project's description. | | `discount` | [Currency](schemas.md#currency), or null | no | The discount applied to the project. | | `fileCount` | integer | no | The number of files attached to the project. | | `goLiveDate` | string (date), or null | no | The day the project goes live. | | `installDate` | string (date), or null | no | The day of the installation. | | `invoicedChargeCount` | integer | no | The number of the project's charges that have been invoiced. | | `items` | list of [ProjectLineItem](schemas.md#projectlineitem) | no | The project's line items, each an item the project sells or provides as a service. | | `locations` | list of [SparseLocationWithParent](schemas.md#sparselocationwithparent) | no | Every location the project names: the ones its line items ask for, and its default location. | | `memo` | string, or null | no | The memo new invoices for the project carry. | | `noteCount` | integer | no | The number of notes on the project. | | `paymentTerm` | [PaymentTerm](schemas.md#paymentterm), or null | no | The project's payment term. | | `previousProject` | [SparseProject](schemas.md#sparseproject), or null | no | The project this one renews. | | `projectFulfillmentStatus` | [ProjectFulfillmentStatus](schemas.md#projectfulfillmentstatus) | no | Accepted in any case. The listed spelling is the one the API sends back. \| Value \| Description \| \| --- \| --- \| \| `FULFILLED` \| Every item has as many assets assigned to the project as the line items ask for \| \| `OVER_FULFILLED` \| Every item has at least as many assets assigned to the project as the line items ask for, and some have more \| \| `PARTIALLY_FULFILLED` \| Some items have fewer assets assigned to the project than the line items ask for \| \| `UNFULFILLED` \| No item the line items ask for has an asset assigned to the project \| | | `siteVisitDate` | string (date), or null | no | The day of the site visit. | | `startClassification` | [ProjectStartClassification](schemas.md#projectstartclassification) | no | How the project relates to the customer's earlier projects: a renewal of a prior project, new business, or an expansion. | | `ticketCount` | integer | no | The number of tickets on the project. | | `timeActivityCount` | integer | no | The number of time activities recorded against the project. | | `totalContractValue` | [Currency](schemas.md#currency), or null | no | The contract's total value, as entered on the project. | | `trainingDate` | string (date), or null | no | The day of the training. | | `urlLinkCount` | integer | no | The number of URL links attached to the project. | ## ProjectChargeRequestItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `expectedBillableDate` | string (date), or null | no | The day the charge is planned to become billable, or null when it has no dates yet. | | `id` | string (uuid), or null | no | The charge to update, or null to add a new one, and no two charges in the list send the same one. | | `isCustomModified` | boolean | no | True when a person added, edited or split the charge, and false when it follows the line item's billing plan unchanged. | | `label` | string | no | The charge's display name, such as the period it covers or the milestone it follows, which is required and 255 characters or less once the spaces around it are trimmed. | | `pricingMode` | [PricingMode](schemas.md#pricingmode) | no | PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. | | `quantity` | integer | no | The number of units the charge bills, which is at least 1 when unitPrice is sent and 2,147,483,647 or less. | | `sequence` | integer | no | The charge's position among its line item's charges, in ascending order, which is zero or more and sent by one charge in the list. | | `servicePeriodEnd` | string (date), or null | no | The last day of the period the charge covers, on or after servicePeriodStart. | | `servicePeriodStart` | string (date), or null | no | The first day of the period the charge covers, or null when the charge has no dates yet. | | `status` | [ChargeStatus](schemas.md#chargestatus) | no | The charge's status: PLANNED, BILLABLE, INVOICED or CANCELLED. A charge becomes billable, invoiced or cancelled only through its own actions, so a new charge must be sent as PLANNED and a stored charge may keep its status or go back to PLANNED, which clears its billable and cancellation details. | | `totalPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency) | no | The amount the charge bills, which equals unitPrice times quantity when unitPrice is sent. | | `totalPrice.amount` | string (decimal) | no | The exact value as a decimal string, which cannot be negative, sent with at most two decimal places. | | `totalPrice.isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The value's ISO 4217 currency code. | | `triggerType` | [ChargeTriggerType](schemas.md#chargetriggertype) | no | TIME when the charge becomes billable on expectedBillableDate, or MANUAL when a person marks it billable, and is TIME when omitted. EVENT is refused. | | `unitPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The price of one unit, in the currency of totalPrice, and is null on a FIXED charge. | ## ProjectCompletionClassification What follows a project for its customer when it ends. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CHURN`, `CONTRACTION`, `RENEWED`. ## ProjectCurrency | Field | Type | Required | Description | | --- | --- | --- | --- | | `isoCode` | [CurrencyCode](schemas.md#currencycode) | no | The ISO 4217 code of the project's currency. | | `source` | [ProjectCurrencySource](schemas.md#projectcurrencysource) | no | What fixed the project's currency: an invoiced charge, the contract value, the line items, or the discount. | ## ProjectCurrencySource Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DISCOUNT`, `INVOICED_CHARGE`, `LINE_ITEMS`, `PROJECT_VALUE`. ## ProjectFulfillmentStatus Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `FULFILLED` | Every item has as many assets assigned to the project as the line items ask for | | `OVER_FULFILLED` | Every item has at least as many assets assigned to the project as the line items ask for, and some have more | | `PARTIALLY_FULFILLED` | Some items have fewer assets assigned to the project than the line items ask for | | `UNFULFILLED` | No item the line items ask for has an asset assigned to the project | Its value is one of `FULFILLED`, `OVER_FULFILLED`, `PARTIALLY_FULFILLED`, `UNFULFILLED`. ## ProjectItemBinding | Field | Type | Required | Description | | --- | --- | --- | --- | | `activationDate` | string (date), or null | no | The day a periodic line item's charge schedule is anchored on, from 1970-01-01 through 2099-12-31, which defaults to startOn. | | `aggregationKey` | string (uuid) | no | The identifier that makes line items consecutive phases of one commitment when they send the same one, and is assigned when a new line item omits it. | | `billingFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | The line item's single billing cadence, which fills chargeFrequency and invoiceFrequency on a periodic line item that omits them. | | `chargeFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a periodic line item creates a charge, and is refused unless chargeSchedule is PERIODIC. | | `chargeSchedule` | [BillingSchedule](schemas.md#billingschedule), or null | no | PERIODIC when charges recur at a regular frequency, or MILESTONE when each charge follows a project milestone. | | `details` | string, or null | no | A free-form note about the line item, 65,536 characters or less. | | `endOn` | string (date), or null | no | The last day of the line item's service window, on or after startOn and no later than 2099-12-31. A line item's dates change only through the project, because the line item update does not take them. | | `fixedPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The flat price when pricingMode is FIXED, and is not sent together with unitPrice. | | `id` | string (uuid), or null | no | The line item to update, or omitted to add a new one. | | `invoiceFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a periodic line item's charges are invoiced, which is never more often than chargeFrequency. | | `invoiceMode` | [BillingTiming](schemas.md#billingtiming), or null | no | ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends, and is refused unless chargeSchedule is PERIODIC. | | `itemId` | string (uuid) | yes | The catalog item the line item is for. | | `locationId` | string (uuid), or null | no | The location the line item is for. | | `milestonePhases` | [MetadataMilestonePhases](schemas.md#metadatamilestonephases), or null | no | The named phases of a milestone line item and each one's share of its total. | | `pricingMode` | [PricingMode](schemas.md#pricingmode), or null | no | PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price whatever the quantity. | | `quantity` | integer | no | The number of units the line item covers, which is zero or more and 100,000,000 or less. | | `startOn` | string (date), or null | no | The first day of the line item's own service window, from 1970-01-01 through 2099-12-31, sent together with endOn on a new line item, while a line item sent with its id may send either alone. A line item's dates change only through the project, because the line item update does not take them. | | `totalOverride` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | A negotiated total for a periodic line item that replaces the computed one, in the project's currency. | | `transactionType` | [TransactionType](schemas.md#transactiontype) | yes | SALE to sell the item, which only a physical item allows, or SERVICE to provide it as a service. | | `unitPrice` | [NonNegativeCurrency](schemas.md#nonnegativecurrency), or null | no | The price of one unit for each charge, and is not sent together with fixedPrice. | ## ProjectLineItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `activationDate` | string (date), or null | no | The day a periodic line item's charge schedule is anchored on, or null while chargeMode is PENDING and on a milestone line item. | | `aggregationKey` | string (uuid) | no | The identifier shared by line items that are consecutive phases of one commitment, and unique to a line item that stands alone. | | `billingFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | The line item's single billing cadence, which predates chargeFrequency and invoiceFrequency. | | `chargeFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a periodic line item creates a charge, and is null on a milestone line item. | | `chargeMode` | [ChargeMode](schemas.md#chargemode) | no | CONFIRMED when a periodic line item has an activation date or the line item is a milestone one, or PENDING when a periodic line item's activation date is not yet known. | | `chargeSchedule` | [BillingSchedule](schemas.md#billingschedule), or null | no | PERIODIC when charges recur at a regular frequency, or MILESTONE when each charge follows a project milestone, and is null until the line item has a billing plan. | | `charges` | list of [Charge](schemas.md#charge) | no | The line item's charges, in sequence order. | | `details` | string, or null | no | A free-form note about the line item. | | `endOn` | string (date), or null | no | The last day of the line item's service window. | | `fixedPrice` | [Currency](schemas.md#currency), or null | no | The flat price when pricingMode is FIXED: the amount of each charge on a periodic line item, and the total its phases split on a milestone one. | | `hasInvoicedCharges` | boolean | no | True when any of the line item's charges is invoiced, which stops the line item from being removed. | | `id` | string (uuid) | no | The line item's unique identifier. | | `invoiceFrequency` | [BillingFrequency](schemas.md#billingfrequency), or null | no | How often a periodic line item's charges are invoiced, which is never more often than chargeFrequency. | | `invoiceMode` | [BillingTiming](schemas.md#billingtiming), or null | no | ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends, on a periodic line item. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The catalog item the line item is for. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The line item's key. | | `location` | [SparseLocationWithParent](schemas.md#sparselocationwithparent), or null | no | The location the line item is for, or null when it has none. | | `milestonePhases` | [MetadataMilestonePhases](schemas.md#metadatamilestonephases), or null | no | The named phases of a milestone line item and each one's share of its total, or null on any other line item. | | `phaseRowNumber` | integer | no | The line item's position among the line items sharing its aggregationKey, counted from 1 in order of startOn. | | `pricingMode` | [PricingMode](schemas.md#pricingmode), or null | no | PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price whatever the quantity, and is null until the line item has a billing plan. | | `quantity` | integer, or null | no | The number of units the line item covers. | | `startOn` | string (date), or null | no | The first day of the line item's own service window, or null when it has no dates. | | `totalOverride` | [Currency](schemas.md#currency), or null | no | A negotiated total for a periodic line item that replaces the computed one, or null to use the computed total. | | `transactionType` | [TransactionType](schemas.md#transactiontype) | no | SALE when the item is sold, or SERVICE when it is provided as a service. | | `unitPrice` | [Currency](schemas.md#currency), or null | no | The price of one unit for each charge, or null when the line item is priced at a fixed price. | ## ProjectListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [Project](schemas.md#project) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## ProjectStartClassification How a project relates to the customer's earlier projects when it starts. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `EXPANSION`, `NEW_BUSINESS`, `RENEWAL`. ## ProjectStatus Where a project stands against its dates, which is computed and never stored. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ACTIVE`, `DATE_RANGE_INCOMPLETE`, `PAST`, `UPCOMING`. ## ProjectStatusFilter A project status the project list and the fulfillment report filter by. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ACTIVE`, `DATE_RANGE_INCOMPLETE`, `PAST`, `UPCOMING`. ## PurchaseOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string, or null | no | Why the order was cancelled, or null while it has not been. | | `cancelledAt` | string (date-time), or null | no | When the order was cancelled, or null while it has not been. | | `cancelledBy` | [SparsePerson](schemas.md#sparseperson), or null | no | Who cancelled the order, or null while it has not been cancelled. | | `createdAt` | string (date-time) | no | When the order was created. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who created the order. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `externalPurchaseOrderNumber` | string, or null | no | The supplier's own number for the order, or null when it has none. | | `fileCount` | integer | no | The number of files attached to the order. | | `fromLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration), or null | no | The location the supplier ships from, or null when none is on record. | | `id` | string (uuid) | no | The purchase order's unique identifier. | | `items` | list of [PurchaseOrderLineItem](schemas.md#purchaseorderlineitem) | no | The order's lines. | | `key` | string | no | The purchase order's key, which the purchase order endpoints take as purchaseOrderKey. | | `lastUpdatedAt` | string (date-time) | no | When the order last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | Who last changed the order. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `mostRecentDeliveredAt` | string (date-time), or null | no | When an inbound shipment for the order was last delivered, or null while none has been. | | `mostRecentReceivedAt` | string (date-time), or null | no | When an inbound shipment for the order was last received, or null while none has been. | | `mostRecentShippedAt` | string (date-time), or null | no | When an inbound shipment for the order last shipped, or null while none has. | | `orderNotes` | string, or null | no | A note about the order, or null. | | `promiseDeliveryDate` | string (date), or null | no | The day the supplier promised the order would arrive, or null when it has not said. | | `promiseShipDate` | string (date), or null | no | The day the supplier promised to ship the order, or null when it has not said. | | `purchaseOrderNumber` | string | no | The number the purchase order is known by, which an inbound shipment names to fill it. | | `status` | [PurchaseOrderStatus](schemas.md#purchaseorderstatus) | no | Where the order is in its life, by the furthest stage any of its lines has reached on the order's inbound shipments. | | `supplier` | [SparseCustomer](schemas.md#sparsecustomer) | no | The company the items are ordered from. | | `supplier.id` | string (uuid) | no | The customer's unique identifier. | | `supplier.isArchived` | boolean | no | Whether the customer is archived. | | `supplier.isCustomer` | boolean | no | Whether the company is a customer. | | `supplier.isSupplier` | boolean | no | Whether the company is a supplier. | | `supplier.key` | string | no | The customer's key, which the customer endpoints take as customerKey. | | `supplier.name` | string | no | The customer's display name, unique within your organization in any case. | | `thirdParty` | [PurchaseOrderThirdParty](schemas.md#purchaseorderthirdparty) | no | The order's receiving by a third-party logistics (3PL) provider and its sync state. | | `thirdParty.hasSyncError` | boolean | no | Whether the last sync with the 3PL provider failed. | | `thirdParty.isEnabled` | boolean | no | Whether the order was sent to a 3PL provider, which then receives it and keeps it from being edited. | | `thirdParty.lastSyncedAt` | string (date-time), or null | no | When Hardfin last checked the order with its 3PL provider, or null when it has never checked. | | `thirdParty.lastUpdateAt` | string (date-time), or null | no | When the 3PL provider last reported a change to the order, or null when it has reported none. | | `thirdParty.syncErrorMessage` | string, or null | no | Why the last sync with the 3PL provider failed, or null when it did not. | | `toLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration) | no | The location the order is delivered to. | | `toLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `toLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `toLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `toLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `toLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `toLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `toLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `toLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `toLocation.description` | string, or null | no | A free-form description of a zone. | | `toLocation.id` | string (uuid) | no | The location's unique identifier. | | `toLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `toLocation.isArchived` | boolean | no | Whether the location is archived. | | `toLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `toLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `toLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `toLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `toLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `toLocation.name` | string | no | The location's display name. | | `toLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `toLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `toLocation.zoneCount` | integer | no | The number of zones at a site. | | `toLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `toLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `toLocation.integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The location's links to integrated systems. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the supplier ships the order with and its transport reference, or null when none of them is set. | ## PurchaseOrderItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `itemId` | string (uuid) | yes | The ID of the physical item the line orders, which may appear on only one line. | | `requestedQuantity` | integer | yes | How many units of the item to order, which must be greater than 0 and 1,000,000,000 or less. | ## PurchaseOrderLineItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredQuantity` | integer | no | How many units are on the order's inbound shipments that have been delivered and not yet received. | | `id` | string (uuid) | no | The line's unique identifier. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the line orders. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The line's key. | | `openQuantity` | integer | no | How many units are on the order's inbound shipments that have not yet shipped. | | `receivedQuantity` | integer | no | How many units have been received on the order's inbound shipments. | | `requestedQuantity` | integer | no | How many units of the item were ordered. | | `shippedQuantity` | integer | no | How many units are on the order's inbound shipments that have shipped and not yet been delivered. | | `status` | [PurchaseOrderLineItemStatus](schemas.md#purchaseorderlineitemstatus) | no | The furthest stage the line's units have reached on the order's inbound shipments, and whether fewer, exactly, or more units than were ordered reached it. | ## PurchaseOrderLineItemStatus The status of a line item on a purchase order. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `DELIVERED_FULL` | The ordered units have been delivered | | `DELIVERED_OVERAGE` | More units than were ordered have been delivered | | `DELIVERED_PARTIAL` | Fewer units than were ordered have been delivered | | `DRAFT` | None of the line's units are on a shipment yet | | `OPEN_FULL` | The ordered units are on shipments that have not left | | `OPEN_OVERAGE` | More units than were ordered are on shipments that have not left | | `OPEN_PARTIAL` | Fewer units than were ordered are on shipments that have not left | | `RECEIVED_FULL` | The ordered units have been received | | `RECEIVED_OVERAGE` | More units than were ordered have been received | | `RECEIVED_PARTIAL` | Fewer units than were ordered have been received | | `SHIPPED_FULL` | The ordered units have shipped | | `SHIPPED_OVERAGE` | More units than were ordered have shipped | | `SHIPPED_PARTIAL` | Fewer units than were ordered have shipped | Its value is one of `DELIVERED_FULL`, `DELIVERED_OVERAGE`, `DELIVERED_PARTIAL`, `DRAFT`, `OPEN_FULL`, `OPEN_OVERAGE`, `OPEN_PARTIAL`, `RECEIVED_FULL`, `RECEIVED_OVERAGE`, `RECEIVED_PARTIAL`, `SHIPPED_FULL`, `SHIPPED_OVERAGE`, `SHIPPED_PARTIAL`. ## PurchaseOrderListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [PurchaseOrder](schemas.md#purchaseorder) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## PurchaseOrderResync3PLFilesResult | Field | Type | Required | Description | | --- | --- | --- | --- | | `failedFiles` | integer | no | How many of those files the 3PL did not accept, which a later resync tries again. | | `successfulFiles` | integer | no | How many of those files the 3PL accepted. | | `totalFiles` | integer | no | How many of the order's files the 3PL had not yet received. | ## PurchaseOrderStatus The status of a purchase order. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `AWAITING_3PL` | The order was sent to a third-party logistics provider, which has not yet reported a shipment | | `CANCELLED` | The order was cancelled | | `DELIVERED_FULL` | Every line's ordered units have been delivered | | `DELIVERED_OVERAGE` | Every line's ordered units have been delivered, and some line delivered more than was ordered | | `DELIVERED_PARTIAL` | Units have been delivered, and not every line has been delivered in full | | `DRAFT` | No units are on a shipment yet, and the order can still be edited or cancelled | | `OPEN_FULL` | Every line's ordered units are on shipments that have not left | | `OPEN_OVERAGE` | Every line's ordered units are on shipments that have not left, and some line has more than was ordered | | `OPEN_PARTIAL` | Units are on shipments that have not left, and not every line is there in full | | `RECEIVED_FULL` | Every line's ordered units have been received | | `RECEIVED_OVERAGE` | Every line's ordered units have been received, and some line received more than was ordered | | `RECEIVED_PARTIAL` | Units have been received, and not every line has been received in full | | `SHIPPED_FULL` | Every line's ordered units have shipped | | `SHIPPED_OVERAGE` | Every line's ordered units have shipped, and some line shipped more than was ordered | | `SHIPPED_PARTIAL` | Units have shipped, and not every line has shipped in full | Its value is one of `AWAITING_3PL`, `CANCELLED`, `DELIVERED_FULL`, `DELIVERED_OVERAGE`, `DELIVERED_PARTIAL`, `DRAFT`, `OPEN_FULL`, `OPEN_OVERAGE`, `OPEN_PARTIAL`, `RECEIVED_FULL`, `RECEIVED_OVERAGE`, `RECEIVED_PARTIAL`, `SHIPPED_FULL`, `SHIPPED_OVERAGE`, `SHIPPED_PARTIAL`. ## PurchaseOrderThirdParty | Field | Type | Required | Description | | --- | --- | --- | --- | | `hasSyncError` | boolean | no | Whether the last sync with the 3PL provider failed. | | `isEnabled` | boolean | no | Whether the order was sent to a 3PL provider, which then receives it and keeps it from being edited. | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last checked the order with its 3PL provider, or null when it has never checked. | | `lastUpdateAt` | string (date-time), or null | no | When the 3PL provider last reported a change to the order, or null when it has reported none. | | `syncErrorMessage` | string, or null | no | Why the last sync with the 3PL provider failed, or null when it did not. | ## QuarantineResolutionBlockReason The condition that stops a resolution the hold's type allows from running. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `SERIAL_ALREADY_TAKEN`. ## QuarantineResolutionKind How a user resolved a quarantined serial. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ACCEPTED_SERIAL`, `CORRECTED_SERIAL`, `CREATED_ASSET`, `KEPT_HARDFIN_ITEM`. ## QuarantineType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `DUPLICATE_ALREADY_EXISTS`, `DUPLICATE_IN_ORDER`, `MISSING_SERIAL`, `SERIAL_PATTERN_MISMATCH`, `SKU_TRANSMUTATION`, `UNKNOWN_SERIAL`. ## RedactionStatus Whether a redacted field carries its value or had it removed for the caller. | Value | Description | | --- | --- | | `VISIBLE` | The caller's role allows the field, and value holds it. | | `REMOVED` | The caller's role does not allow the field, and value is null. | Its value is one of `VISIBLE`, `REMOVED`. ## RequestedItemType The item type a request asks an item to become. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `BULK`, `DEVICE`, `SERVICE`. ## ReturnOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string, or null | no | Why the order was cancelled, or null while it has not been. | | `cancelledAt` | string (date-time), or null | no | When the order was cancelled, or null while it has not been. | | `cancelledBy` | [SparsePerson](schemas.md#sparseperson), or null | no | Who cancelled the order, or null while it has not been cancelled. | | `createdAt` | string (date-time) | no | When the order was created. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who created the order. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `exchangeGroup` | [SparseExchangeGroup](schemas.md#sparseexchangegroup), or null | no | The exchange the order belongs to, or null when it belongs to none. | | `fileCount` | integer | no | The number of files attached to the order. | | `fromLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration), or null | no | The location the items are returned from, or null when none is on record. | | `id` | string (uuid) | no | The return order's unique identifier. | | `items` | list of [ReturnOrderOrderItem](schemas.md#returnorderorderitem) | no | The order's lines. | | `key` | string | no | The return order's key, which the return order endpoints take as returnOrderKey. | | `lastUpdatedAt` | string (date-time) | no | When the order last changed. | | `lastUpdatedBy` | [SparsePerson](schemas.md#sparseperson) | no | Who last changed the order. | | `lastUpdatedBy.firstName` | string, or null | no | The person's first name. | | `lastUpdatedBy.id` | string (uuid) | no | The person's unique identifier. | | `lastUpdatedBy.key` | string | no | The person's key. | | `lastUpdatedBy.lastName` | string, or null | no | The person's last name. | | `mostRecentDeliveredAt` | string (date-time), or null | no | When a shipment for the order was last delivered, or null while none has been. | | `mostRecentReceivedAt` | string (date-time), or null | no | When a shipment for the order was last received, or null while none has been. | | `mostRecentShippedAt` | string (date-time), or null | no | When a shipment for the order last shipped, or null while none has. | | `orderNotes` | string, or null | no | A note about the order, or null. | | `promiseDeliveryDate` | string (date), or null | no | The day the items were promised to arrive, or null when none was promised. | | `promiseShipDate` | string (date), or null | no | The day the items were promised to ship, or null when none was promised. | | `returnOrderNumber` | string | no | The number the return order is known by, which a shipment names to fill it. | | `returnReason` | string, or null | no | A description of why the items are coming back, or null when none was given. | | `returnType` | [ReturnOrderType](schemas.md#returnordertype) | no | Why the items are coming back. | | `status` | [ReturnOrderStatus](schemas.md#returnorderstatus) | no | Where the order is in its life, by the furthest stage any of its lines has reached on the order's shipments. | | `thirdParty` | [ReturnOrderThirdParty](schemas.md#returnorderthirdparty) | no | The order's receiving by a third-party logistics (3PL) provider and its sync state. | | `thirdParty.hasSyncError` | boolean | no | Whether the last sync with the 3PL provider failed. | | `thirdParty.isEnabled` | boolean | no | Whether the order was sent to a 3PL provider to receive. | | `thirdParty.lastSyncedAt` | string (date-time), or null | no | When Hardfin last checked the order with its 3PL provider, or null when it has never checked. | | `thirdParty.lastUpdateAt` | string (date-time), or null | no | When the 3PL provider last reported a change to the order, or null when it has reported none. | | `thirdParty.syncErrorMessage` | string, or null | no | Why the last sync with the 3PL provider failed, or null when it did not. | | `toLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration) | no | The location the items are returned to. | | `toLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `toLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `toLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `toLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `toLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `toLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `toLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `toLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `toLocation.description` | string, or null | no | A free-form description of a zone. | | `toLocation.id` | string (uuid) | no | The location's unique identifier. | | `toLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `toLocation.isArchived` | boolean | no | Whether the location is archived. | | `toLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `toLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `toLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `toLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `toLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `toLocation.name` | string | no | The location's display name. | | `toLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `toLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `toLocation.zoneCount` | integer | no | The number of zones at a site. | | `toLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `toLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `toLocation.integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The location's links to integrated systems. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the items are returned with and its transport reference, or null when none of them is set. | ## ReturnOrderCreate | Field | Type | Required | Description | | --- | --- | --- | --- | | `fromLocationId` | string (uuid) | yes | The ID of the location the items are returned from. | | `items` | list of [ReturnOrderItem](schemas.md#returnorderitem) | yes | The order's lines, from 1 to 50 of them, each naming a different item. | | `orderNotes` | string, or null | no | A note about the order, where blank text is stored as null. | | `promiseDeliveryDate` | string (date), or null | no | The day the items are promised to arrive. | | `promiseShipDate` | string (date), or null | no | The day the items are promised to ship. | | `returnReason` | string, or null | no | A description of why the items are coming back, which is required when returnType is OTHER. | | `returnType` | [ReturnOrderType](schemas.md#returnordertype) | yes | Why the items are coming back. | | `toLocationId` | string (uuid) | yes | The ID of the location the items are returned to, which must differ from fromLocationId. | | `transportReferenceDetails` | [CarrierTransportReferenceDetails](schemas.md#carriertransportreferencedetails), or null | no | The carrier the items are returned with and its transport reference, or null when none of them is set. | ## ReturnOrderItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `itemId` | string (uuid) | yes | The ID of the physical item the line returns, which may appear on only one line. | | `requestedQuantity` | integer | yes | How many units of the item to return, which must be greater than 0 and 1,000,000,000 or less. | ## ReturnOrderLineItemStatus The status of a line item on a return order. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `DELIVERED_FULL` | The requested units have been delivered | | `DELIVERED_OVERAGE` | More units than were requested have been delivered | | `DELIVERED_PARTIAL` | Fewer units than were requested have been delivered | | `DRAFT` | None of the line's units are on a shipment yet | | `OPEN_FULL` | The requested units are on shipments that have not left | | `OPEN_OVERAGE` | More units than were requested are on shipments that have not left | | `OPEN_PARTIAL` | Fewer units than were requested are on shipments that have not left | | `RECEIVED_FULL` | The requested units have been received | | `RECEIVED_OVERAGE` | More units than were requested have been received | | `RECEIVED_PARTIAL` | Fewer units than were requested have been received | | `SHIPPED_FULL` | The requested units have shipped | | `SHIPPED_OVERAGE` | More units than were requested have shipped | | `SHIPPED_PARTIAL` | Fewer units than were requested have shipped | Its value is one of `DELIVERED_FULL`, `DELIVERED_OVERAGE`, `DELIVERED_PARTIAL`, `DRAFT`, `OPEN_FULL`, `OPEN_OVERAGE`, `OPEN_PARTIAL`, `RECEIVED_FULL`, `RECEIVED_OVERAGE`, `RECEIVED_PARTIAL`, `SHIPPED_FULL`, `SHIPPED_OVERAGE`, `SHIPPED_PARTIAL`. ## ReturnOrderListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [ReturnOrder](schemas.md#returnorder) | no | The page of records. | | `totalCount` | integer | no | The number of records that match the filters, across every page. | ## ReturnOrderOrderItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredQuantity` | integer | no | How many units are on the order's shipments that have been delivered and not yet received. | | `id` | string (uuid) | no | The line's unique identifier. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the line returns. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The line's key. | | `openQuantity` | integer | no | How many units are on the order's shipments that have not yet shipped. | | `receivedQuantity` | integer | no | How many units have been received on the order's shipments. | | `requestedQuantity` | integer | no | How many units of the item are to come back. | | `shippedQuantity` | integer | no | How many units are on the order's shipments that have shipped and not yet been delivered. | | `status` | [ReturnOrderLineItemStatus](schemas.md#returnorderlineitemstatus) | no | The furthest stage the line's units have reached on the order's shipments, and whether fewer, exactly, or more units than were requested reached it. | ## ReturnOrderResync3PLFilesResult | Field | Type | Required | Description | | --- | --- | --- | --- | | `failedFiles` | integer | no | How many of those files the 3PL did not accept, which a later resync tries again. | | `successfulFiles` | integer | no | How many of those files the 3PL accepted. | | `totalFiles` | integer | no | How many of the order's files the 3PL had not yet received. | ## ReturnOrderStatus The status of a return order. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `AWAITING_3PL` | The order was sent to a third-party logistics provider, which has not yet reported a shipment | | `CANCELLED` | The order was cancelled | | `DELIVERED_FULL` | Every line's requested units have been delivered | | `DELIVERED_OVERAGE` | Every line's requested units have been delivered, and some line delivered more than was requested | | `DELIVERED_PARTIAL` | Units have been delivered, and not every line has been delivered in full | | `DRAFT` | No units are on a shipment yet, and the order can still be edited or cancelled | | `OPEN_FULL` | Every line's requested units are on shipments that have not left | | `OPEN_OVERAGE` | Every line's requested units are on shipments that have not left, and some line has more than was requested | | `OPEN_PARTIAL` | Units are on shipments that have not left, and not every line is there in full | | `RECEIVED_FULL` | Every line's requested units have been received | | `RECEIVED_OVERAGE` | Every line's requested units have been received, and some line received more than was requested | | `RECEIVED_PARTIAL` | Units have been received, and not every line has been received in full | | `SHIPPED_FULL` | Every line's requested units have shipped | | `SHIPPED_OVERAGE` | Every line's requested units have shipped, and some line shipped more than was requested | | `SHIPPED_PARTIAL` | Units have shipped, and not every line has shipped in full | Its value is one of `AWAITING_3PL`, `CANCELLED`, `DELIVERED_FULL`, `DELIVERED_OVERAGE`, `DELIVERED_PARTIAL`, `DRAFT`, `OPEN_FULL`, `OPEN_OVERAGE`, `OPEN_PARTIAL`, `RECEIVED_FULL`, `RECEIVED_OVERAGE`, `RECEIVED_PARTIAL`, `SHIPPED_FULL`, `SHIPPED_OVERAGE`, `SHIPPED_PARTIAL`. ## ReturnOrderThirdParty | Field | Type | Required | Description | | --- | --- | --- | --- | | `hasSyncError` | boolean | no | Whether the last sync with the 3PL provider failed. | | `isEnabled` | boolean | no | Whether the order was sent to a 3PL provider to receive. | | `lastSyncedAt` | string (date-time), or null | no | When Hardfin last checked the order with its 3PL provider, or null when it has never checked. | | `lastUpdateAt` | string (date-time), or null | no | When the 3PL provider last reported a change to the order, or null when it has reported none. | | `syncErrorMessage` | string, or null | no | Why the last sync with the 3PL provider failed, or null when it did not. | ## ReturnOrderType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CUSTOMER_CANCELLATION`, `DAMAGED`, `DEFECTIVE`, `END_OF_SERVICE`, `INCORRECT_SPEC`, `NOT_NEEDED`, `OTHER`, `PROVISIONING`, `UPGRADE`, `WRONG_ITEM`. ## ScrappedState Accepted in any case, and also as t, f, 1, 0, or 2 for all. The listed spelling is the one the API sends back. Its value is one of `all`, `false`, `true`. ## SerialPatternKind One of the shapes an organization can require a serial to take. Each kind expands to a regular expression stored in organization.serial_patterns. Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ALPHA`, `ALPHANUMERIC`, `HEX`, `MAC_ADDRESS`, `NUMERIC`, `UUID`. ## SerialPatternSpec | Field | Type | Required | Description | | --- | --- | --- | --- | | `kind` | [SerialPatternKind](schemas.md#serialpatternkind) | no | The shape the serial must take. | | `length` | integer, or null | no | The number of characters after the prefix, 1 to 32, for ALPHA, ALPHANUMERIC, NUMERIC and HEX, and null for MAC_ADDRESS and UUID. | | `prefix` | string, or null | no | The literal text the serial starts with, up to 16 letters, digits, dots, dashes or underscores, or null for none. | ## SharedBool | Field | Type | Required | Description | | --- | --- | --- | --- | | `success` | boolean | no | Whether the operation completed. | ## SharedIntegration | Field | Type | Required | Description | | --- | --- | --- | --- | | `errorCode` | integer, or null | no | The Hardfin error code of the failed sync, or null when the sync did not fail. | | `id` | [IntegrationID](schemas.md#integrationid) | no | The integrated system, such as SFDC or HUBSPOT. | | `inError` | boolean | no | Whether the last sync with the external system failed. | | `isSyncing` | boolean | no | Whether a sync with the external system is pending. | | `label` | string | no | The system's display name. | | `link` | string, or null | no | A URL to the linked record in the external system. | | `needsReview` | boolean | no | Whether the record differs from the external system and needs a person to review it. | | `type` | [IntegrationCategory](schemas.md#integrationcategory) | no | The kind of system, CRM or ERP. | ## Shipment | Field | Type | Required | Description | | --- | --- | --- | --- | | `cancellationReason` | string, or null | no | Why the shipment was cancelled, or null while it has not been. | | `cancelledAt` | string (date-time), or null | no | When the shipment was cancelled, or null while it has not been. | | `cancelledBy` | string (uuid), or null | no | The ID of the user who cancelled the shipment, or null while it has not been cancelled. | | `createdAt` | string (date-time) | no | When the shipment was created. | | `createdBy` | [SparsePerson](schemas.md#sparseperson) | no | Who created the shipment. | | `createdBy.firstName` | string, or null | no | The person's first name. | | `createdBy.id` | string (uuid) | no | The person's unique identifier. | | `createdBy.key` | string | no | The person's key. | | `createdBy.lastName` | string, or null | no | The person's last name. | | `cycleTime` | [ShipmentCycleTime](schemas.md#shipmentcycletime) | no | How long the shipment spent in each stage. | | `cycleTime.createdToShippedDays` | string (decimal), or null | no | The days from the shipment's creation to its ship time, or null while it has not shipped. | | `cycleTime.shippedToDeliveredDays` | string (decimal), or null | no | The days from the shipment's ship time to its delivery, or null while it has not been delivered. | | `deliveredAt` | string (date-time), or null | no | When the shipment arrived, or null while it has not. | | `deliveredAtTimezone` | string, or null | no | The IANA time zone deliveredAt was recorded in, or null when none was recorded. | | `deliveryNote` | string, or null | no | The note written when the shipment was delivered, or null. | | `estimatedTotalValue` | string (decimal), or null | no | The sum of the lines' estimated values, or null when no line has an estimate. | | `eta` | string (date-time), or null | no | When the carrier now expects to deliver, or null when it says nothing. | | `expectedDeliveredOn` | string (date), or null | no | The day the shipment is expected to arrive, or null when no one has said. | | `expectedShippedOn` | string (date), or null | no | The day the shipment is expected to leave, or null when no one has said. | | `fromLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration), or null | no | Where the shipment leaves from, or null when an inbound shipment names no origin. | | `fulfillmentOrder` | [SparseFulfillment](schemas.md#sparsefulfillment), or null | no | The fulfillment order an outbound shipment fills, or null when it fills none. | | `id` | string (uuid) | no | The shipment's unique identifier. | | `items` | list of [ShipmentLineItem](schemas.md#shipmentlineitem) | no | The shipment's line items. | | `key` | string | no | The shipment's key, which the shipment endpoints take as shipmentKey. | | `purchaseOrder` | [SparsePurchaseOrder](schemas.md#sparsepurchaseorder), or null | no | The purchase order an inbound shipment fills, or null when it fills none. | | `receiptNote` | string, or null | no | The note written when the shipment was received, or null. | | `receivedAt` | string (date-time), or null | no | When an inbound shipment's items were received, or null while they have not been. | | `receivedAtTimezone` | string, or null | no | The IANA time zone receivedAt was recorded in, or null when none was recorded. | | `returnOrder` | [SparseReturnOrder](schemas.md#sparsereturnorder), or null | no | The return order an inbound shipment fills, or null when it fills none. | | `serviceLevelName` | string, or null | no | The carrier's service the shipment travels on, or null when the carrier names none. | | `shipmentNote` | string, or null | no | The note written about the shipment itself, or null. | | `shipmentNumber` | string | no | The number the shipment is known by. | | `shipmentType` | [ShipmentType](schemas.md#shipmenttype), or null | no | Whether the shipment is INBOUND to the organization or OUTBOUND from it. | | `shippedAt` | string (date-time), or null | no | When the shipment left, or null while it has not. | | `shippedAtTimezone` | string, or null | no | The IANA time zone shippedAt was recorded in, or null when none was recorded. | | `shippingCost` | [Currency](schemas.md#currency), or null | no | What the shipment cost to send, or null when no cost is recorded. | | `status` | [ShipmentStatus](schemas.md#shipmentstatus) | no | Where the shipment is in its life: OPEN, SHIPPED, DELIVERED, RECEIVED or CANCELLED. | | `thirdPartyBound` | boolean | no | Whether a third-party provider holds the shipment, which refuses API calls that ship, receive, or cancel it or change its line items. | | `timeInStatusDays` | string (decimal), or null | no | How many days the shipment has held its status, or null once it is received, cancelled, or an outbound shipment is delivered. | | `toLocation` | [SparseLocationWithIntegration](schemas.md#sparselocationwithintegration) | no | Where the shipment is going. | | `toLocation.address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `toLocation.googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `toLocation.latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `toLocation.longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `toLocation.shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `toLocation.archivedZoneCount` | integer | no | The number of archived zones at a site. | | `toLocation.consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `toLocation.customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `toLocation.description` | string, or null | no | A free-form description of a zone. | | `toLocation.id` | string (uuid) | no | The location's unique identifier. | | `toLocation.isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `toLocation.isArchived` | boolean | no | Whether the location is archived. | | `toLocation.isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `toLocation.isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `toLocation.isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `toLocation.isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `toLocation.key` | string | no | The location's key, which the location endpoints take as locationKey. | | `toLocation.name` | string | no | The location's display name. | | `toLocation.thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `toLocation.type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `toLocation.zoneCount` | integer | no | The number of zones at a site. | | `toLocation.zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `toLocation.parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `toLocation.integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The location's links to integrated systems. | | `totalValue` | string (decimal), or null | no | What the shipment's assets were worth when an outbound shipment shipped or an inbound one was received, or null before then or when it has none to value. | | `trackingNumberDetails` | [CarrierTrackingNumberDetails](schemas.md#carriertrackingnumberdetails), or null | no | Who carries the shipment and its tracking number, or null when none of them is set. | ## ShipmentCycleTime | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdToShippedDays` | string (decimal), or null | no | The days from the shipment's creation to its ship time, or null while it has not shipped. | | `shippedToDeliveredDays` | string (decimal), or null | no | The days from the shipment's ship time to its delivery, or null while it has not been delivered. | ## ShipmentItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `externalReference` | string, or null | no | The line's identifier in another system, or null when it has none. | | `itemId` | string (uuid) | yes | The ID of the item the line carries. | | `quantity` | integer, or null | no | How many units the line ships, which creating an outbound shipment requires above 0 and an inbound shipment may leave null, and is 1,000,000,000 or less. | | `serials` | list of string | no | The serial numbers of the units, which only marking the shipment as shipped records and none of which may be blank. A DEVICE item's serials name its assets. A BULK item's serials are kept as notes on the line and are not checked against its units. | ## ShipmentLineItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `estimatedValue` | string (decimal), or null | no | What the line was estimated to be worth while the shipment was open, or null when no estimate was made. | | `externalReference` | string, or null | no | The line's identifier in the system that reported it, or null when it has none. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The item the line carries. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `pendingSerialCount` | integer | no | The number of the line's pending serial numbers, counted in the shipment list too. | | `pendingSerials` | list of string | no | The serial numbers a third-party provider has reported but not yet confirmed as shipped, which is empty in the shipment list. | | `quantity` | integer, or null | no | How many units the line ships, or null when the line was added without one. | | `receivedQuantity` | integer, or null | no | How many units arrived, or null until an inbound shipment is received. | | `serialCount` | integer | no | The number of the line's serial numbers, counted in the shipment list too. | | `serials` | list of string | no | The serial numbers of the line's units, which is empty for an item that is not tracked by serial and in the shipment list. | | `value` | string (decimal), or null | no | What the line's assets were worth when an outbound shipment shipped or an inbound one was received, or null before then or when it has none to value. | ## ShipmentListing | Field | Type | Required | Description | | --- | --- | --- | --- | | `results` | list of [Shipment](schemas.md#shipment) | no | The shipments on the page. | | `totalCount` | integer | no | The number of shipments the filters match, across every page. | ## ShipmentReceiveItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `externalReference` | string, or null | no | The line's identifier in another system, or null when it has none. | | `itemId` | string (uuid) | no | The ID of the item that arrived, which may be named once. | | `quantity` | integer, or null | no | How many units arrived, which is required, may be 0 for a line that did not arrive, and is 1,000,000,000 or less. | | `serials` | list of string | no | The serial numbers of the units that arrived, none of which may be blank. A DEVICE item's serials name its assets. A BULK item's serials are kept as notes on the line and are not checked against its units. | ## ShipmentStatus Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CANCELLED`, `DELIVERED`, `OPEN`, `RECEIVED`, `SHIPPED`. ## ShipmentType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `INBOUND`, `OUTBOUND`. ## SortOrder Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `ASC`, `DESC`. ## SparseActiveWorkflow | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The workflow's unique identifier. | | `key` | string | no | The workflow's key. | | `name` | string | no | The workflow's display name. | | `stages` | list of [SparseWorkflowStage](schemas.md#sparseworkflowstage) | no | The workflow's stages. | ## SparseAsset | Field | Type | Required | Description | | --- | --- | --- | --- | | `functionalStatus` | [AssetFunctionalStatus](schemas.md#assetfunctionalstatus) | no | Whether the asset works, is broken, awaits review, or has been scrapped. | | `id` | string (uuid) | no | The asset's unique identifier. | | `inInventoryDate` | string (date) | no | The day the asset entered inventory. | | `isArchived` | boolean | no | Whether the asset is archived. | | `isInTransit` | boolean | no | Whether the asset has shipped and not yet been delivered. | | `item` | [SparseItem](schemas.md#sparseitem) | no | The catalog item the asset is a unit of. | | `item.hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `item.id` | string (uuid) | no | The item's unique identifier. | | `item.isArchived` | boolean | no | Whether the item is archived. | | `item.isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `item.key` | string | no | The item's key, which the item endpoints take as itemKey. | | `item.name` | string | no | The item's display name. | | `item.shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `item.sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `item.type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `item.unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | | `key` | string | no | The asset's key, which the asset endpoints take as assetKey. | | `serial` | string | no | The asset's serial number, unique within your organization in any case. | ## SparseBatch | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The batch's ID. | | `receiveType` | one of `PURCHASE`, `TRANSFER`, `ADJUSTMENT`, `SHIPMENT` | no | How the batch arrived: SHIPMENT when a shipment was received, or ADJUSTMENT when an inventory adjustment added it. PURCHASE and TRANSFER are reserved and not written today. | | `receivedAt` | string (date-time) | no | When the batch was received into inventory. | | `receivedQuantity` | integer | no | The number of units the batch arrived with. | | `shipmentReference` | string, or null | no | The external reference on the shipment line that brought the batch in, and null when there is none. | ## SparseContact | Field | Type | Required | Description | | --- | --- | --- | --- | | `comments` | string, or null | no | A note about the contact, or null. | | `createdAt` | string (date-time) | no | When the contact was created. | | `customer` | [SparseCustomer](schemas.md#sparsecustomer) | no | The customer the contact works for. | | `customer.id` | string (uuid) | no | The customer's unique identifier. | | `customer.isArchived` | boolean | no | Whether the customer is archived. | | `customer.isCustomer` | boolean | no | Whether the company is a customer. | | `customer.isSupplier` | boolean | no | Whether the company is a supplier. | | `customer.key` | string | no | The customer's key, which the customer endpoints take as customerKey. | | `customer.name` | string | no | The customer's display name, unique within your organization in any case. | | `email` | string, or null | no | The contact's email address, or null. | | `firstName` | string | no | The contact's first name. | | `id` | string (uuid) | no | The contact's unique identifier. | | `isArchived` | boolean | no | Whether the contact is archived. | | `key` | string | no | The contact's key. | | `lastName` | string | no | The contact's last name. | | `phone` | string, or null | no | The contact's phone number, or null. | | `title` | string, or null | no | The contact's job title, or null. | | `updatedAt` | string (date-time) | no | When the contact last changed. | ## SparseCustomer | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The customer's unique identifier. | | `isArchived` | boolean | no | Whether the customer is archived. | | `isCustomer` | boolean | no | Whether the company is a customer. | | `isSupplier` | boolean | no | Whether the company is a supplier. | | `key` | string | no | The customer's key, which the customer endpoints take as customerKey. | | `name` | string | no | The customer's display name, unique within your organization in any case. | ## SparseExchangeGroup | Field | Type | Required | Description | | --- | --- | --- | --- | | `exchangeNumber` | string | no | The number the exchange is known by. | | `fulfillmentOrders` | list of [SparseExchangeGroupFulfillmentOrder](schemas.md#sparseexchangegroupfulfillmentorder) | no | The fulfillment orders that send replacement units. | | `id` | string (uuid) | no | The exchange's unique identifier. | | `key` | string | no | The exchange's key. | | `returnOrders` | list of [SparseExchangeGroupReturnOrder](schemas.md#sparseexchangegroupreturnorder) | no | The return orders that bring units back. | | `status` | [ExchangeGroupStatus](schemas.md#exchangegroupstatus) | no | Where the exchange stands: DRAFT, IN_PROGRESS, COMPLETE or CANCELLED. | ## SparseExchangeGroupFulfillmentOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `fulfillmentOrderNumber` | string | no | The number the fulfillment order is known by. | | `id` | string (uuid) | no | The fulfillment order's unique identifier. | | `key` | string | no | The fulfillment order's key. | ## SparseExchangeGroupReturnOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The return order's unique identifier. | | `key` | string | no | The return order's key. | | `returnOrderNumber` | string | no | The number the return order is known by. | ## SparseFulfillment | Field | Type | Required | Description | | --- | --- | --- | --- | | `fulfillmentOrderNumber` | string | no | The number the fulfillment order is known by. | | `id` | string (uuid) | no | The fulfillment order's unique identifier. | | `isThirdPartyFulfilled` | boolean | no | Whether a third-party provider fulfills the order. | | `key` | string | no | The fulfillment order's key. | ## SparseItem | Field | Type | Required | Description | | --- | --- | --- | --- | | `hasAssets` | boolean | no | Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. | | `id` | string (uuid) | no | The item's unique identifier. | | `isArchived` | boolean | no | Whether the item is archived. | | `isPhysical` | boolean | no | Whether the item is physical, which is true for DEVICE and BULK items. | | `key` | string | no | The item's key, which the item endpoints take as itemKey. | | `name` | string | no | The item's display name. | | `shouldRenderSerialFields` | boolean | no | Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. | | `sku` | string | no | The item's stock keeping unit, unique within your organization in any case. | | `type` | [FrontendItemType](schemas.md#frontenditemtype) | no | SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. | | `unitOfMeasure` | [UnitOfMeasure](schemas.md#unitofmeasure) | no | The unit the item's quantities are counted in. | ## SparseLocation | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `archivedZoneCount` | integer | no | The number of archived zones at a site. | | `consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `description` | string, or null | no | A free-form description of a zone. | | `id` | string (uuid) | no | The location's unique identifier. | | `isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `isArchived` | boolean | no | Whether the location is archived. | | `isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `key` | string | no | The location's key, which the location endpoints take as locationKey. | | `name` | string | no | The location's display name. | | `thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `zoneCount` | integer | no | The number of zones at a site. | | `zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | ## SparseLocationWithIntegration | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `archivedZoneCount` | integer | no | The number of archived zones at a site. | | `consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `description` | string, or null | no | A free-form description of a zone. | | `id` | string (uuid) | no | The location's unique identifier. | | `isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `isArchived` | boolean | no | Whether the location is archived. | | `isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `key` | string | no | The location's key, which the location endpoints take as locationKey. | | `name` | string | no | The location's display name. | | `thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `zoneCount` | integer | no | The number of zones at a site. | | `zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The location's links to integrated systems. | ## SparseLocationWithParent | Field | Type | Required | Description | | --- | --- | --- | --- | | `address` | [MetadataLocationComponents](schemas.md#metadatalocationcomponents), or null | no | The location's structured address, which is null for a zone. | | `googlePlaceId` | string, or null | no | Google's place ID for the address, when it was found through Google. | | `latitude` | string (decimal), or null | no | The location's latitude, sent as a decimal string. | | `longitude` | string (decimal), or null | no | The location's longitude, sent as a decimal string. | | `shippingName` | string, or null | no | The person or business that receives shipments at the location. | | `archivedZoneCount` | integer | no | The number of archived zones at a site. | | `consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer a zone is designated for, such as for reservations, provisioning or a 3PL. | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. | | `description` | string, or null | no | A free-form description of a zone. | | `id` | string (uuid) | no | The location's unique identifier. | | `isAddressGeocoded` | boolean | no | Whether Google resolved the site's address, which is always false for a zone. | | `isArchived` | boolean | no | Whether the location is archived. | | `isInventory` | boolean | no | Whether assets at the location count as inventory for reporting. | | `isInventoryOverride` | boolean | no | Whether a zone sets its own isInventory rather than inheriting its parent site's. | | `isThirdPartyEnabled` | boolean | no | Whether a third-party logistics (3PL) provider fulfills orders from the location. | | `isTransient` | boolean | no | Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. | | `key` | string | no | The location's key, which the location endpoints take as locationKey. | | `name` | string | no | The location's display name. | | `thirdPartyIdentifier` | string, or null | no | The 3PL provider's identifier for the location. | | `type` | [LocationType](schemas.md#locationtype) | no | SITE for a site, or ZONE for a zone within a site. | | `zoneCount` | integer | no | The number of zones at a site. | | `zones` | list of [SparseZone](schemas.md#sparsezone) | no | The site's zones. | | `parentLocation` | [SparseLocation](schemas.md#sparselocation), or null | no | The site a zone belongs to, or null for a site. | ## SparseOrganization | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The organization's ID | | `key` | string | no | The public identifier that can be used in URLs | | `name` | string | no | The name of the organization | ## SparsePerson | Field | Type | Required | Description | | --- | --- | --- | --- | | `firstName` | string, or null | no | The person's first name. | | `id` | string (uuid) | no | The person's unique identifier. | | `key` | string | no | The person's key. | | `lastName` | string, or null | no | The person's last name. | ## SparseProject | Field | Type | Required | Description | | --- | --- | --- | --- | | `customer` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the project is for. | | `endOn` | string (date), or null | no | The day the project ends. | | `id` | string (uuid) | no | The project's unique identifier. | | `integrations` | list of [SharedIntegration](schemas.md#sharedintegration) | no | The project's links to integrated systems. | | `isArchived` | boolean | no | Whether the project is archived. | | `key` | string | no | The project's key. | | `name` | string | no | The project's display name. | | `paymentTermLabel` | string, or null | no | The name of the project's payment term. | | `purchaseOrderNumber` | string, or null | no | The customer's purchase order number, which new invoices for the project carry. | | `startOn` | string (date), or null | no | The day the project starts. | | `status` | [ProjectStatus](schemas.md#projectstatus) | no | Whether the project is upcoming, active, or past, judged from its dates. | ## SparsePurchaseOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `externalPurchaseOrderNumber` | string, or null | no | The supplier's own number for the purchase order, or null when it has none. | | `id` | string (uuid) | no | The purchase order's unique identifier. | | `key` | string | no | The purchase order's key. | | `purchaseOrderNumber` | string | no | The number the purchase order is known by. | ## SparseReturnOrder | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | no | The return order's unique identifier. | | `key` | string | no | The return order's key. | | `returnOrderNumber` | string | no | The number the return order is known by. | ## SparseShipment | Field | Type | Required | Description | | --- | --- | --- | --- | | `deliveredAt` | string (date-time), or null | no | When the shipment arrived, or null while it has not. | | `id` | string (uuid) | no | The shipment's unique identifier. | | `key` | string | no | The shipment's key. | | `shipmentNumber` | string | no | The number the shipment is known by. | | `shipmentType` | string | no | What kind of movement the shipment carries. | | `shippedAt` | string (date-time), or null | no | When the shipment left, or null while it has not. | ## SparseWorkflowStage | Field | Type | Required | Description | | --- | --- | --- | --- | | `active` | boolean | no | True when the stage is the project's current stage. | | `id` | string (uuid) | no | The stage's unique identifier. | | `key` | string | no | The stage's key. | | `name` | string | no | The stage's display name. | | `order` | integer | no | The stage's position in its workflow. | ## SparseZone | Field | Type | Required | Description | | --- | --- | --- | --- | | `assetCount` | integer | no | The number of assets in the zone. | | `consignee` | [SparseCustomer](schemas.md#sparsecustomer), or null | no | The customer the zone is designated for, such as for reservations, provisioning or a 3PL. | | `description` | string, or null | no | A free-form description of the zone. | | `id` | string (uuid) | no | The zone's unique identifier. | | `isArchived` | boolean | no | Whether the zone is archived. | | `isInventory` | boolean | no | Whether assets in the zone count as inventory for reporting. | | `key` | string | no | The zone's key. | | `name` | string | no | The zone's display name, unique within its site. | ## Token | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the API key was created, the application was connected, or the person signed in. | | `expiresAt` | string (date-time), or null | no | When the access token or session expires, or null for an API key, which does not. | | `identifier` | string, or null | no | The API key's public identifier or the application's client_id, or null for a session. | | `label` | string, or null | no | The API key's label or the application's name, or null when there is none. | | `lastRegeneratedAt` | string (date-time), or null | no | When the API key was last regenerated or the access token was issued, or null for a session. | | `organization` | [SparseOrganization](schemas.md#sparseorganization) | no | The organization the credential acts in. | | `organization.id` | string (uuid) | no | The organization's ID | | `organization.key` | string | no | The public identifier that can be used in URLs | | `organization.name` | string | no | The name of the organization | | `person` | [SparsePerson](schemas.md#sparseperson) | no | The person the credential acts for. | | `person.firstName` | string, or null | no | The person's first name. | | `person.id` | string (uuid) | no | The person's unique identifier. | | `person.key` | string | no | The person's key. | | `person.lastName` | string, or null | no | The person's last name. | | `scopes` | list of string | no | What the credential may do, within the person's own permissions. | | `type` | [CredentialType](schemas.md#credentialtype) | no | The kind of credential. | ## TransactionType Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `SALE`, `SERVICE`. ## TransientState Accepted in any case, and also as t, f, 1, 0, or 2 for all. The listed spelling is the one the API sends back. Its value is one of `all`, `false`, `true`. ## TransitStatus Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `IN_TRANSIT`, `IN_TRANSIT_TO_FIELD`, `IN_TRANSIT_TO_INVENTORY`, `NOT_IN_TRANSIT`. ## URLLink | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the link was created. | | `id` | string (uuid) | no | The URL link's unique identifier. | | `key` | string | no | The URL link's key, which the URL link endpoints take as linkKey. | | `name` | string, or null | no | The link's display name, or null when the link shows its address instead. | | `updatedAt` | string (date-time) | no | When the link was last changed. | | `url` | string | no | The address the link points to. | ## UnitOfMeasure The unit a quantity is counted in, sent as its UNECE Recommendation 20 code. A request may also name the unit or give its symbol, such as each or lb. Send KGM for kilogram, because KG is the code for keg. See: https://unece.org/trade/uncefact/cl-recommendations Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `BG` | Bag | | `BO` | Bottle | | `BX` | Box | | `C62` | Unit | | `CMK` | Square centimeter (cm2) | | `CMT` | Centimeter (cm) | | `CR` | Crate | | `CS` | Case | | `CT` | Carton | | `DMQ` | Cubic decimeter (dm3) | | `DR` | Drum | | `DZN` | Dozen (doz) | | `EA` | Each (ea) | | `EN` | Envelope | | `FOT` | Foot (ft) | | `FTK` | Square foot (ft2) | | `FTQ` | Cubic foot (ft3) | | `GLL` | Gallon (gal) | | `GRM` | Gram (g) | | `GRO` | Gross | | `H87` | Piece (pc) | | `INH` | Inch (in) | | `INK` | Square inch (in2) | | `INQ` | Cubic inch (in3) | | `KG` | Keg | | `KGM` | Kilogram (kg) | | `KMT` | Kilometer (km) | | `KT` | Kit | | `LBR` | Pound (lb) | | `LO` | Lot | | `LTR` | Liter (L) | | `MGM` | Milligram (mg) | | `MLT` | Milliliter (mL) | | `MMK` | Square millimeter (mm2) | | `MMT` | Millimeter (mm) | | `MTK` | Square meter (m2) | | `MTQ` | Cubic meter (m3) | | `MTR` | Meter (m) | | `ONZ` | Ounce (oz) | | `OZA` | Fluid ounce (fl oz) | | `PK` | Pack | | `PR` | Pair (pr) | | `PTI` | Pint (pt) | | `PX` | Pallet | | `QTI` | Quart (qt) | | `RL` | Reel | | `RO` | Roll | | `SET` | Set | | `SMI` | Mile (mi) | | `ST` | Sheet | | `STN` | Ton US (NT) | | `SV` | Skid | | `TNE` | Tonne metric (t) | | `TU` | Tube | | `YDK` | Square yard (yd2) | | `YDQ` | Cubic yard (yd3) | | `YRD` | Yard (yd) | Its value is one of `BG`, `BO`, `BX`, `C62`, `CMK`, `CMT`, `CR`, `CS`, `CT`, `DMQ`, `DR`, `DZN`, `EA`, `EN`, `FOT`, `FTK`, `FTQ`, `GLL`, `GRM`, `GRO`, `H87`, `INH`, `INK`, `INQ`, `KG`, `KGM`, `KMT`, `KT`, `LBR`, `LO`, `LTR`, `MGM`, `MLT`, `MMK`, `MMT`, `MTK`, `MTQ`, `MTR`, `ONZ`, `OZA`, `PK`, `PR`, `PTI`, `PX`, `QTI`, `RL`, `RO`, `SET`, `SMI`, `ST`, `STN`, `SV`, `TNE`, `TU`, `YDK`, `YDQ`, `YRD`. ## UsefulLifeRevisionReason Accepted in any case. The listed spelling is the one the API sends back. Its value is one of `CHANGE_IN_USE`, `DAMAGE`, `OBSOLESCENCE`, `OTHER`, `REASSESSMENT`, `REFURBISHMENT`, `REGULATORY`. ## Workflow | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the workflow was created. | | `id` | string (uuid) | no | The workflow's identifier. | | `isDefault` | boolean | no | Whether this is the organization's default workflow. At most one workflow is the default. | | `key` | string | no | The workflow's key. | | `name` | string | no | The workflow's name. | | `stages` | list of [WorkflowStage](schemas.md#workflowstage) | no | The stages a project on this workflow moves through, in order. | | `updatedAt` | string (date-time) | no | When the workflow was last changed. | ## WorkflowStage | Field | Type | Required | Description | | --- | --- | --- | --- | | `createdAt` | string (date-time) | no | When the stage was created. | | `id` | string (uuid) | no | The stage's identifier. | | `inUseCount` | integer | no | The number of projects on the stage. | | `key` | string | no | The stage's key. | | `name` | string | no | The stage's name. | | `orderIndex` | integer | no | The stage's position in its workflow. A lower value comes first. | | `updatedAt` | string (date-time) | no | When the stage was last changed. | ## WorkflowStageRequest | Field | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid), or null | no | | | `migrateTo` | string, or null | no | | | `name` | string | no | | | `orderIndex` | integer | no | | | `shouldDelete` | boolean | no | |