Skip to main content

Purchase Contract API

Create and manage long-term purchase agreements with vendors.


Endpoints

MethodEndpointDescription
GET/record/v1/purchaseContractList purchase contracts
GET/record/v1/purchaseContract/{id}Get specific contract
POST/record/v1/purchaseContractCreate contract
PATCH/record/v1/purchaseContract/{id}Update contract
DELETE/record/v1/purchaseContract/{id}Delete contract

Key Fields

FieldTypeDescriptionRequired
idstringInternal ID-
tranIdstringContract numberAuto-generated
entityobjectVendorYes
startDatestringContract start dateYes
endDatestringContract end dateYes
statusobjectContract statusRead-only
subsidiaryobjectSubsidiaryYes (OneWorld)
currencyobjectCurrencyYes
totalnumberTotal contract value (read-only)-
memostringContract notesNo
termsobjectPayment termsNo
locationobjectDefault locationNo
departmentobjectDepartmentNo
classobjectClassNo
itemcollectionContract itemsYes

Example: Create Purchase Contract

POST /record/v1/purchaseContract
Content-Type: application/json

Request Body

{
"entity": {
"id": "789"
},
"startDate": "2026-01-01",
"endDate": "2026-12-31",
"subsidiary": {
"id": "1"
},
"currency": {
"id": "1"
},
"location": {
"id": "1"
},
"department": {
"id": "10"
},
"terms": {
"id": "5"
},
"memo": "Annual supply agreement for widgets - 2026 pricing locked",
"item": {
"items": [
{
"item": { "id": "789" },
"quantity": 1200,
"rate": 24.00,
"amount": 28800.00,
"description": "Widget A - Contract rate for 2026"
},
{
"item": { "id": "790" },
"quantity": 600,
"rate": 48.00,
"amount": 28800.00,
"description": "Widget B - Volume discount applied"
}
]
}
}

Response

{
"id": "5001",
"tranId": "PC-2026-001",
"entity": {
"id": "789",
"refName": "Acme Suppliers Inc"
},
"startDate": "2026-01-01",
"endDate": "2026-12-31",
"status": {
"id": "A",
"refName": "Active"
},
"subsidiary": {
"id": "1",
"refName": "Parent Company"
},
"currency": {
"id": "1",
"refName": "USD"
},
"location": {
"id": "1",
"refName": "Main Warehouse"
},
"department": {
"id": "10",
"refName": "Operations"
},
"terms": {
"id": "5",
"refName": "Net 30"
},
"memo": "Annual supply agreement for widgets - 2026 pricing locked",
"total": 57600.00,
"item": {
"items": [
{
"item": { "id": "789", "refName": "Widget A - Standard" },
"quantity": 1200,
"rate": 24.00,
"amount": 28800.00,
"description": "Widget A - Contract rate for 2026"
},
{
"item": { "id": "790", "refName": "Widget B - Premium" },
"quantity": 600,
"rate": 48.00,
"amount": 28800.00,
"description": "Widget B - Volume discount applied"
}
]
},
"links": [
{
"rel": "self",
"href": "https://account.suitetalk.api.netsuite.com/services/rest/record/v1/purchaseContract/5001"
}
]
}

Example: Update Purchase Contract

PATCH /record/v1/purchaseContract/5001
Content-Type: application/json

Request Body

{
"endDate": "2027-01-31",
"memo": "Annual supply agreement for widgets - Extended through Jan 2027",
"item": {
"items": [
{
"item": { "id": "789" },
"quantity": 1500,
"rate": 23.50,
"amount": 35250.00,
"description": "Widget A - Revised contract rate with volume increase"
},
{
"item": { "id": "790" },
"quantity": 600,
"rate": 48.00,
"amount": 28800.00,
"description": "Widget B - Volume discount applied"
}
]
}
}

Line Items

Item Sublist Fields

FieldTypeDescriptionRequired
itemobjectItem in contractYes
quantitynumberContract quantityYes
ratenumberContract price per unitYes
amountnumberLine total (calculated)-
descriptionstringLine descriptionNo
locationobjectDelivery locationNo
departmentobjectDepartmentNo
classobjectClassNo
customerobjectCustomer (for job costing)No

Query Filters

Find Active Contracts

GET /record/v1/purchaseContract?q=status.id='A'

Find by Vendor

GET /record/v1/purchaseContract?q=entity='789'

Find Contracts Ending Soon

GET /record/v1/purchaseContract?q=endDate BETWEEN '2026-01-01' AND '2026-03-31' AND status.id='A'

Find by Date Range

GET /record/v1/purchaseContract?q=startDate >= '2026-01-01' AND endDate <= '2026-12-31'

Find Expired Contracts

GET /record/v1/purchaseContract?q=endDate < SYSDATE AND status.id='A'

Contract Statuses

StatusDescription
PendingContract not yet started
ActiveContract currently in effect
ExpiredContract end date has passed
CancelledContract cancelled before expiration

Create Purchase Order from Contract

Reference the contract when creating a PO to use contract pricing:

POST /record/v1/purchaseOrder
Content-Type: application/json
{
"entity": {
"id": "789"
},
"tranDate": "2026-02-15",
"subsidiary": {
"id": "1"
},
"currency": {
"id": "1"
},
"purchaseContract": {
"id": "5001"
},
"item": {
"items": [
{
"item": { "id": "789" },
"quantity": 100
}
]
}
}

Important Notes

  • Purchase contracts lock in pricing for specified items and quantities
  • When creating POs against a contract, the contract rate is automatically applied
  • Contracts can span multiple fiscal years
  • Line item quantities represent the total contracted amount, not per-order amounts
  • Multiple POs can be created against a single contract until quantities are fulfilled
  • The status field is automatically managed based on start/end dates
  • Contracts can be amended by updating them before they expire
  • Some NetSuite editions require the Advanced Procurement feature for contracts
  • Contract terms (payment terms, shipping terms) apply to all POs created from the contract
  • Volume discounts and special pricing are common uses for purchase contracts
  • Contracts help with budget planning and vendor negotiations
  • The total contract value is calculated automatically from line items

See Also