Product API

Product catalog documentation

Base URL: https://product.tpxapps.com

Product API

The Product API exposes TPx product data through a single, consistent HTTP endpoint. It retrieves a product record and returns it at a selectable depth, always including the four-level product hierarchy.

It exposes a single product-lookup endpoint, GET /product/{id}, with selectable detail levels.

Base URL

All endpoints are relative to the following base URL:

Base URL
https://product.tpxapps.com

Requests and responses use application/json.

Authentication

Every request must carry a bearer token in the Authorization header. The token is validated before any routing, so a request without a valid token is rejected with 401 Unauthorized regardless of the path or method.

Authorization header

Present the token using the HTTP Bearer scheme (RFC 6750):

Authorization header
Authorization: Bearer <your-access-token>

The header name and the Bearer keyword are matched case-insensitively and surrounding whitespace is ignored; the token value itself is compared exactly. An empty token (Bearer with nothing after it) is treated as no token.

Example request

cURL
curl "https://product.tpxapps.com/product/<productID>?detail=basic" \
     -H "Authorization: Bearer <your-access-token>"

Obtaining a token

The API authenticates callers with a shared access token — a single pre-shared secret, not per-user credentials and not an OAuth flow. Tokens are provisioned out-of-band by the TPx platform team and are not published here. Treat the token as a secret: send it only over HTTPS and never embed it in browser or other client-side code.

Failed authentication

A missing Authorization header, a non-Bearer scheme, an empty token, or a token the service does not recognise all produce the same result — an empty-bodied 401 Unauthorized:

Response
HTTP/1.1 401 Unauthorized
(empty body)
Why a health check sees 401

Because authorization is checked ahead of routing, an unauthenticated probe to any path returns 401 — that is exactly how the upstream proxy's health check confirms the service is alive.

Internal use

This is an internal API, network-restricted to trusted callers; the bearer token is an additional required control, not a replacement for that restriction. Endpoints and record IDs are environment-specific — IDs shown in examples are illustrative only.


Detail levels

The detail query parameter selects how much of the product graph is returned. Each level is a superset of the previous one. An omitted or invalid value falls back to basic.

LevelIncludes
basic Core product fields (id, name, productCode, description, isActive), the four-level hierarchy, and the standard-pricebook listPrice.
full Everything in basic, plus related features and options — each option carries its optional-SKU id + name and its configuration attributes.
extended Everything in full, plus the fuller definition of each option's product (productCode, description, isActive, family).
One query, every level

The product and all its related data — list price, features, options, and each option's product — are fetched in a single Salesforce query, so higher detail levels add depth without extra round trips.

Response format

The format query parameter selects the shape of the response, independently of detail. An omitted or invalid value falls back to default.

FormatShape
default The product as modelled in the catalog — the fields, hierarchy, pricing, features, and options documented throughout this page.
spec A TMF-aligned product: a Product carrying a flat productCharacteristic array and a productSpecification reference.

format=spec is served from the same single query as default and is orthogonal to detail — it always returns the product-level spec, so detail has no effect when format=spec.

Spec example

200 OKformat=spec
Response
{
  "@type": "Product",
  "productCharacteristic": [
    { "name": "Device Type",            "value": [ "Physical", "Virtual" ] },
    { "name": "Virtual Infrastructure", "value": [ "Azure", "AWS", "GCP" ] },
    { "name": "WAN Equipment Vendor",   "value": [ "VMware (Velocloud)", "Aruba (Silver Peak)" ] }
  ],
  "productSpecification": {
    "name": "Network Edge Appliance",
    "@type": "ProductSpecificationRef"
  }
}

Fields

@typestring
Always "Product".
productCharacteristicarray
Product characteristics as { name, value }. A characteristic is present only when the product has a value for it; a product with none returns [].
productCharacteristic[].namestring
The characteristic's display name (e.g. Device Type).
productCharacteristic[].valuestring · array
The value(s). Characteristics that allow multiple selections return an array of the allowed values; single-valued characteristics return a scalar string.
productSpecificationobject
A reference to the product specification.
productSpecification.namestring
The specification name.
productSpecification.@typestring
Always "ProductSpecificationRef".
Characteristic values are the allowed set

In the catalog a multi-select characteristic carries the menu of permitted values (hence an array), not a single chosen value — the selection is made downstream at order time.

Product hierarchy

Every response includes a hierarchy object carrying Levels 1–4 — Company, Category, Group, Family. Each level has a numeric level, a label (the display text for that level), and an id.

LevelNameID
1Companylabel only
2Categorylabel only
3Grouplabel only
4Familyregistry id

Only Family resolves to a registry id; Company, Category, and Group carry "id": null because no such link exists in the source data.


Get Product by ID

Retrieves a single product at the requested detail level, including the four-level product hierarchy.

GET /product/{id}

Path Parameters

ParameterTypeDescription
id required string The product record ID (15- or 18-char), e.g. <productID>.

Query Parameters

ParameterTypeDescription
detail optional basic · full · extended Depth of the returned graph. Default basic; invalid/omitted → basic.
format optional default · spec Response shape (see Response format). Default default; invalid/omitted → default. spec returns the TMF product shape and ignores detail.

Example Request

cURL
curl "https://product.tpxapps.com/product/<productID>?detail=basic" \
     -H "Authorization: Bearer <your-access-token>"
200 OKdetail=basic
Response
{
  "id": "<productID>",
  "name": "Managed Microsoft 365 - Commercial",
  "productCode": "SSN1-TECH-O365-COM",
  "description": "Managed Microsoft 365 subscription with TPx onboarding and support.",
  "isActive": true,
  "integrationStatus": "Pending Changes",
  "inventoryID": null,
  "hierarchy": {
    "company":  { "level": 1, "label": "TPx",            "id": null },
    "category": { "level": 2, "label": "Collaboration",  "id": null },
    "group":    { "level": 3, "label": "Cloud Services", "id": null },
    "family":   { "level": 4, "label": "Microsoft 365",  "id": "<familyID>" }
  },
  "listPrice": {
    "unitPrice": 0,
    "floorPrice": 0,
    "cost": 0,
    "isActive": true,
    "pricebookId": "<pricebookID>",
    "pricebookEntryId": "<pricebookEntryID>"
  }
}
200 OKdetail=full — adds features + options (truncated)
Response
{
  "id": "<productID>",
  "name": "Managed Microsoft 365 - Commercial",
  "productCode": "SSN1-TECH-O365-COM",
  "description": "Managed Microsoft 365 subscription with TPx onboarding and support.",
  "isActive": true,
  "hierarchy": { /* … as above … */ },
  "listPrice": { /* … as above … */ },
  "features": [
    {
      "id": "<featureID>",
      "name": "Commercial Subscriptions - Monthly Term, Monthly Billing",
      "number": 10,
      "minOptionCount": 0,
      "maxOptionCount": null,
      "configuredSkuId": "<productID>",
      "category": "1M1M",
      "externalId": null,
      "wanEquipSource": null,
      "wanEquipVendor": null
    }
  ],
  "options": [
    {
      "id": "<optionID>",
      "name": "PO-008021",
      "number": 3,
      "required": false,
      "quantity": null,
      "type": null,
      "featureId": "<featureID>",
      "bundled": false,
      "selected": false,
      "quantityEditable": true,
      "optionProductCode": "SSN1-TECH-O365-COM-ADD-AGENT-1M1M",
      "componentCode": null,
      "componentDescription": null,
      "attributes": {
        "solution": "HB - Microsoft 365",
        "ucxSolution": null,
        "formFactor": null,
        "operatingSystem": null,
        "deviceType": null,
        "firewallDevice": null,
        "sdWanDevice": null,
        "wanDeviceType": null
      },
      "product": {
        "id": "<optionProductID>",
        "name": "Agent 365"
      }
    }
  ]
}
200 OKdetail=extended — option products enriched
Response (options[].product)
"product": {
  "id": "<optionProductID>",
  "name": "Microsoft 365 Business Standard",
  "productCode": "M365-BUS-STD",
  "description": "Microsoft 365 Business Standard seat.",
  "isActive": true,
  "family": "Microsoft 365"
}
200 OKformat=spec — TMF product shape
Response
{
  "@type": "Product",
  "productCharacteristic": [
    { "name": "Device Type", "value": [ "Physical", "Virtual" ] }
  ],
  "productSpecification": {
    "name": "Network Edge Appliance",
    "@type": "ProductSpecificationRef"
  }
}

See Response format for the full spec shape and field definitions.

404 Not Foundunknown or malformed product ID
503 Service Unavailableupstream product source unavailable
502 Bad Gatewayunexpected upstream response

Error responses have an empty body; the HTTP status carries the outcome.


Get Order by ID

Retrieves a single order and, at higher detail levels, its line items and each line's product. The order and all of its line items are fetched in a single query.

GET /order/{id}

Path Parameters

ParameterTypeDescription
id required string The order record ID (15- or 18-char), e.g. <orderID>.

Query Parameters

ParameterTypeDescription
detail optional basic · full · extended Depth of the returned order. Default basic; invalid/omitted → basic. See below.
LevelIncludes
basicOrder header only (id, number, status, dates, amount, account/contact refs, billing & shipping address).
fullEverything in basic, plus the orderItems array (core line fields).
extendedEverything in full, plus each line's product (id, name, productCode, description, isActive, family) and a dynamic attributes array (the product's CPQ configuration attributes).

Example Request

cURL
curl "https://product.tpxapps.com/order/<orderID>?detail=full" \
     -H "Authorization: Bearer <your-access-token>"
200 OKdetail=basic
Response
{
  "id": "<orderID>",
  "orderNumber": "00000892",
  "status": "Activated",
  "statusCode": "Activated",
  "type": "New",
  "description": null,
  "poNumber": null,
  "effectiveDate": "2026-06-01",
  "endDate": null,
  "createdDate": "2026-06-01T20:34:11.000+0000",
  "activatedDate": "2026-06-01T20:36:53.000+0000",
  "customerRequestedDueDate": null,
  "totalAmount": 13251.8,
  "interestRate": 6,
  "isReductionOrder": false,
  "ownerID": "<userID>",
  "accountID": "<accountID>",
  "contractID": "<contractID>",
  "opportunityID": "<opportunityID>",
  "billToContactID": null,
  "shipToContactID": null,
  "serviceNowOrderNumber": null,
  "customerOrderNarrative": "…",
  "locationActivity": "New Customer",
  "terminationType": null,
  "terminationSubtype": null,
  "customerProvisioningContactID": null,
  "quoteID": "<quoteID>",
  "billingAddress": {
    "street": "13590 University Blvd",
    "city": "Sugar Land",
    "state": "TX",
    "postalCode": "77479-6872",
    "country": "USA"
  },
  "shippingAddress": { /* … same shape … */ }
}
200 OKdetail=full — adds orderItems (truncated)
Response
{
  "id": "<orderID>",
  /* … header as above … */
  "orderItems": [
    {
      "id": "<orderItemID>",
      "orderItemNumber": "0000010399",
      "productID": "<productID>",
      "quantity": 1,
      "unitPrice": 0,
      "listPrice": 0,
      "totalPrice": 0,
      "serviceDate": "2026-06-01",
      "endDate": "2028-05-31",
      "description": null,
      "contractAction": "New"
    }
  ]
}
200 OKdetail=extended — each line gains product + attributes (varies per product)
Response (each orderItems[] entry)
  /* … line fields as in full … */
  "discountedMRC": 0,
  "discountedNRC": 0,
  "discountedCumulativeMRC": 0,
  "discountedCumulativeNRC": 0,
  "installment": 0,
  "totalInterestOverLifetime": 0,
  "isInstallmentPayment": false,
  "quoteSubscriptionTerm": 24,
  "serviceName": "MSx WAN Equipment",
  "productOfferingParentBundle": "MSx WAN Equipment",
  "productOfferingParentBundleID": null,
  "productSpecificationFeatureName": null,
  "productSpecificationFeatureID": null,
  "bundleRootID": null,
  "requiredByID": null,
  "revisedOrderProductID": null,
  "contractID": "<contractID>",
  "accountLocationID": "<accountLocationID>",
  "locationID": "<locationID>",
  "totalLineRevenueMRC": 76.8,
  "totalLineRevenueNRC": 0,
  "pqeNumber": null,
  "billingFrequency": null,
  "subscriptionID": "<subscriptionID>",
  "solution": [ "MSx WAN" ],
  "product": {
    "id": "<productID>",
    "name": "MSx WAN Equipment",
    "productCode": "SFSN-EQUIP-WAN",
    "description": "MSx WAN Equipment",
    "isActive": true,
    "family": "MSx WAN"
  },
  "attributes": [
    { "name": "Solution",         "value": "MSx WAN" },
    { "name": "Equipment Vendor", "value": "VMware (Velocloud)" },
    { "name": "Device Type",      "value": "Virtual" },
    { "name": "Deployment Type",  "value": "High Availability" }
  ]
404 Not Foundunknown or malformed order ID
503 Service Unavailableupstream order source unavailable
502 Bad Gatewayunexpected upstream response

Error responses have an empty body; the HTTP status carries the outcome.


Create Order Note

Creates a Salesforce note attached to an order. The note's title and content come from the request body; the order in the path becomes the note's parent record. Returns the new note's ID.

POST /order/{id}/note

Path Parameters

ParameterTypeDescription
id required string The order record ID (15- or 18-char) the note is attached to, e.g. <orderID>.

Request Body (application/json)

FieldTypeDescription
title required string (≤ 80) The note title.
content optional string (≤ 32000) The note body.

Example Request

cURL
curl -X POST "https://product.tpxapps.com/order/<orderID>/note" \
     -H "Authorization: Bearer <your-access-token>" \
     -H "Content-Type: application/json" \
     -d '{ "title": "Provisioning update", "content": "Circuit scheduled for install." }'
201 Creatednote created; returns its ID
Response
{
  "id": "<noteID>"
}
400 Bad Requestmissing/blank title, title > 80 chars, content > 32000, or malformed JSON body
401 Unauthorizedmissing or invalid bearer token
404 Not Foundunknown or malformed order ID
503 Service Unavailableupstream order source unavailable
502 Bad Gatewayunexpected upstream response

A 400 carries a JSON body { "error": "…" }; the other error statuses have an empty body.


Response models

Product

idstring
Product record ID (18-char).
namestring
Product name.
productCodestring
SKU / product code.
descriptionstring · nullable
Long description.
isActiveboolean
Whether the product is active.
integrationStatusstring · nullable
Integration status (e.g. Pending Changes).
inventoryIDstring · nullable
Inventory ID.
hierarchyobject
Levels 1–4 (see below). Always present.
listPriceobject · nullable
Standard-pricebook list price (see below). Present at all detail levels; null if the product has no standard-pricebook entry.
featuresarray
full · extended Related feature groupings.
optionsarray
full · extended Bundle options, each with a nested product and attributes.

List price

The product's entry in the standard price book. Money values are 0 across the current data set — a source-data gap, not an API defect.

unitPricenumber
Standard list price.
floorPricenumber
Minimum sell-price floor.
costnumber
Unit cost.
isActiveboolean
Whether the price entry is active.
pricebookIdstring
ID of the standard price book.
pricebookEntryIdstring
ID of the price-book entry.

Hierarchy level

levelnumber
1 = Company, 2 = Category, 3 = Group, 4 = Family.
labelstring · nullable
Display text for the level.
idstring · nullable
Registry ID — populated for Family only; null otherwise.

Feature

idstring
Feature record ID.
namestring
Feature name.
numbernumber · nullable
Display order.
minOptionCountnumber · nullable
Minimum options selectable.
maxOptionCountnumber · nullable
Maximum options selectable.
configuredSkuIdstring
ID of the bundle product this feature belongs to.
categorystring · nullable
Feature category code (e.g. a term code like 1M1M).
externalIdstring · nullable
External integration id.
wanEquipSourcestring · nullable
WAN equipment source.
wanEquipVendorstring · nullable
WAN equipment vendor.

Option

idstring
Option record ID.
namestring
Option name.
numbernumber · nullable
Display order.
requiredboolean · nullable
Whether the option is required.
quantitynumber · nullable
Default quantity.
typestring · nullable
Option type (e.g. Component).
featureIdstring · nullable
Owning feature ID.
bundledboolean
Whether the option is bundled into the parent.
selectedboolean
Whether the option is selected by default.
quantityEditableboolean
Whether the quantity can be changed.
optionProductCodestring
Product code of the option's product.
componentCodestring · nullable
Component code.
componentDescriptionstring · nullable
Component description.
attributesobject
Configuration attributes for the option (see below).
productobject
The option's product — id + name; enriched with productCode/description/isActive/family under extended.

Option attributes

CPQ configuration values for an option. Populated mainly for network / SD-WAN products; often null otherwise.

solutionstring · nullable
CPQ solution grouping (e.g. HB - Microsoft 365).
ucxSolutionstring · nullable
UCx solution.
formFactorstring · nullable
Hardware form factor.
operatingSystemstring · nullable
Operating system.
deviceTypestring · nullable
Device type (e.g. Physical).
firewallDevicestring · nullable
Firewall device source (e.g. TPx Provided).
sdWanDevicestring · nullable
SD-WAN device.
wanDeviceTypestring · nullable
WAN device type.

Order

Returned by Get Order by ID.

idstring
Order record ID (18-char).
orderNumberstring
Human-readable order number.
statusstring
Order status (e.g. Draft, Activated).
statusCodestring
Status category.
typestring · nullable
Order type.
descriptionstring · nullable
Order description.
poNumberstring · nullable
Customer purchase-order number.
effectiveDatedate · nullable
Order start date.
endDatedate · nullable
Order end date.
createdDatedatetime
When the order was created.
activatedDatedatetime · nullable
When the order was activated.
customerRequestedDueDatedate · nullable
Customer-requested due date.
totalAmountnumber · nullable
Order total.
interestRatenumber · nullable
Interest rate (percent).
isReductionOrderboolean
Whether this is a reduction order.
ownerIDstring
Owner user ID.
accountIDstring · nullable
Account ID.
contractIDstring · nullable
Contract ID.
opportunityIDstring · nullable
Opportunity ID.
billToContactIDstring · nullable
Bill-to contact ID.
shipToContactIDstring · nullable
Ship-to contact ID.
serviceNowOrderNumberstring · nullable
Linked ServiceNow order number.
customerOrderNarrativestring · nullable
Free-text order narrative.
locationActivitystring · nullable
Location activity (e.g. New Customer).
terminationTypestring · nullable
Termination type.
terminationSubtypestring · nullable
Termination subtype.
customerProvisioningContactIDstring · nullable
Customer provisioning contact record ID.
quoteIDstring · nullable
Source CPQ quote record ID.
billingAddressobject
Billing address (see Address).
shippingAddressobject
Shipping address (see Address).
orderItemsarray
full · extended Order line items (see Order item).

Order item

idstring
Order line record ID.
orderItemNumberstring
Order line number.
productIDstring · nullable
ID of the product (service) on this line.
quantitynumber · nullable
Quantity ordered.
unitPricenumber · nullable
Unit price.
listPricenumber · nullable
List price.
totalPricenumber · nullable
Line total.
serviceDatedate · nullable
Line start date.
endDatedate · nullable
Line end date.
descriptionstring · nullable
Line description.
contractActionstring · nullable
Contract action (e.g. New).
discountedMRCnumber · nullable
extended Discounted monthly recurring charge.
discountedNRCnumber · nullable
extended Discounted non-recurring charge.
discountedCumulativeMRCnumber · nullable
extended Discounted cumulative MRC.
discountedCumulativeNRCnumber · nullable
extended Discounted cumulative NRC.
installmentnumber · nullable
extended Installment amount.
totalInterestOverLifetimenumber · nullable
extended Total interest over the line's lifetime.
isInstallmentPaymentboolean · nullable
extended Whether the line is paid in installments.
quoteSubscriptionTermnumber · nullable
extended Subscription term (months).
serviceNamestring · nullable
extended Service name.
productOfferingParentBundlestring · nullable
extended Parent bundle / product offering.
productOfferingParentBundleIDstring · nullable
extended Parent bundle record ID.
productSpecificationFeatureNamestring · nullable
extended Product specification / feature name.
productSpecificationFeatureIDstring · nullable
extended Product specification / feature record ID.
bundleRootIDstring · nullable
extended Bundle root record ID.
requiredByIDstring · nullable
extended Record ID of the line this one is required by.
revisedOrderProductIDstring · nullable
extended Record ID of the order product this revises.
contractIDstring · nullable
extended Contract record ID.
accountLocationIDstring · nullable
extended Account location record ID.
locationIDstring · nullable
extended Location record ID.
totalLineRevenueMRCnumber · nullable
extended Total line revenue (MRC).
totalLineRevenueNRCnumber · nullable
extended Total line revenue (NRC).
pqeNumberstring · nullable
extended PQE number.
billingFrequencystring · nullable
extended Billing frequency.
subscriptionIDstring · nullable
extended Subscription record ID.
solutionarray · nullable
extended The line's solution(s), a multi-value field returned as an array. Present on every line (unlike the Solution entry in attributes, which only appears for products configured with it).
productobject
extended The line's product — id, name, productCode, description, isActive, family.
attributesarray
extended The line's configuration attributes (see Order line attributes).

Order line attributes

A dynamic array, present only under extended. Each entry is { "name", "value" }, where name is one of the product's CPQ configuration-attribute names (e.g. Solution, Equipment Vendor, Device Type) and value is the line's value — a string, an array for multi-value fields, or null. The entries vary per product; a product with no configuration attributes returns [].

Address

streetstring · nullable
Street.
citystring · nullable
City.
statestring · nullable
State / province.
postalCodestring · nullable
ZIP / postal code.
countrystring · nullable
Country.

Error codes

The API uses standard HTTP status codes to indicate success or failure.

CodeMeaningWhen
200OKProduct found and returned.
404Not FoundNo product with that ID, or a malformed ID.
502Bad GatewayThe upstream product source returned an unexpected (non-200) response or an unparseable body.
503Service UnavailableThe upstream product source could not be reached (transport error or timeout).

Error responses carry no body — the status code is the signal.