Purchase Contract API
Create and manage long-term purchase agreements with vendors.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /record/v1/purchaseContract | List purchase contracts |
GET | /record/v1/purchaseContract/{id} | Get specific contract |
POST | /record/v1/purchaseContract | Create contract |
PATCH | /record/v1/purchaseContract/{id} | Update contract |
DELETE | /record/v1/purchaseContract/{id} | Delete contract |
Key Fields
| Field | Type | Description | Required |
|---|---|---|---|
id | string | Internal ID | - |
tranId | string | Contract number | Auto-generated |
entity | object | Vendor | Yes |
startDate | string | Contract start date | Yes |
endDate | string | Contract end date | Yes |
status | object | Contract status | Read-only |
subsidiary | object | Subsidiary | Yes (OneWorld) |
currency | object | Currency | Yes |
total | number | Total contract value (read-only) | - |
memo | string | Contract notes | No |
terms | object | Payment terms | No |
location | object | Default location | No |
department | object | Department | No |
class | object | Class | No |
item | collection | Contract items | Yes |
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
| Field | Type | Description | Required |
|---|---|---|---|
item | object | Item in contract | Yes |
quantity | number | Contract quantity | Yes |
rate | number | Contract price per unit | Yes |
amount | number | Line total (calculated) | - |
description | string | Line description | No |
location | object | Delivery location | No |
department | object | Department | No |
class | object | Class | No |
customer | object | Customer (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
| Status | Description |
|---|---|
Pending | Contract not yet started |
Active | Contract currently in effect |
Expired | Contract end date has passed |
Cancelled | Contract 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
statusfield 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
- Purchase Order - Create POs against contracts
- Vendor - Vendor records
- Inventory Item - Contract items