agentlyleads docs
Offerings API

The Offering object

This object is an offering. Its type defaults to PRODUCT, but the same object also represents services, subscriptions, and contracts — see Offerings & types. The following fields are accepted on write and returned on read.

FieldTypeNotes
idstringCUID, assigned on create (read-only)
namestring (required)Max 200 characters
typeenumPRODUCT (default) · SERVICE · SUBSCRIPTION · CONTRACT
skustringMax 100 chars — catalog identity and primary upsert key
categorystring | nullBy name; created automatically if new (max 100 chars). Returns null when no category is set.
pricenumberNonnegative; defaults to 0 if omitted on create
costnumber | nullNonnegative; enables margin display (price − cost)
currencystringISO 4217 code; defaults to USD
unitstringe.g. each, GB, hour (max 40 chars)
billingPeriodenum | nullMONTHLY · YEARLY (for subscriptions)
termMonthsinteger | nullContract or subscription term in months (positive integer)
stockQtyinteger | nullOptional inventory count (min 0)
reorderLevelinteger | nullOptional inventory reorder threshold (min 0)
descriptionstringMax 10,000 characters
featuresstringMax 10,000 characters
activebooleanDefaults to true
externalIdstringYour system's ID — secondary upsert key and dedupe handle (max 200 chars)
createdAtstring (ISO 8601)Assigned on create (read-only)
updatedAtstring (ISO 8601)Updated on every write (read-only)

Example object

{
  "id": "cmq1abc2def3ghi4jkl5",
  "name": "4G Router",
  "type": "PRODUCT",
  "sku": "RTR-4G",
  "price": 199,
  "cost": 120,
  "currency": "USD",
  "unit": "each",
  "billingPeriod": null,
  "termMonths": null,
  "stockQty": 50,
  "reorderLevel": null,
  "description": null,
  "features": null,
  "active": true,
  "externalId": null,
  "category": "Electronics",
  "createdAt": "2025-06-01T12:00:00.000Z",
  "updatedAt": "2025-06-01T12:00:00.000Z"
}

Notes on specific fields

name is the only required field. All other fields are optional on write.

price defaults to 0 when omitted on create. On update, only fields explicitly included in the request body are changed.

category is sent and returned as a string name. The server resolves it to an internal category record, creating the category automatically if it does not exist yet.

sku and externalId are the two upsert keys. Lookup order: sku first, then externalId (if sku is absent from the row). If neither matches an existing product, a new one is created.

On this page