GET /api/now/table/ast_contract/[contract_sys_id]?sysparm_fields=sys_id,number,short_description,description,contract_type,vendor,starts,ends,renewal_date,payment_amount,total_cost,state,terms_and_conditions,auto_renew,notice_period,assigned_to,department,contract_administrator,parent_contract,governing_law,currency,payment_terms&sysparm_display_value=true
Step 2: Retrieve Contract Documents
Fetch associated contract documents and attachments for content analysis.
GET /api/now/table/clm_contract_doc?sysparm_query=contract=[contract_sys_id]^ORDERBYDESCdocument_version&sysparm_fields=sys_id,document_version,status,doc_type,effective_date,content,file_name&sysparm_limit=10
GET /api/now/table/core_company/[vendor_sys_id]?sysparm_fields=sys_id,name,vendor_type,primary_contact,street,city,state,country,phone,website&sysparm_display_value=true
Step 4: Extract and Catalog Obligations
Query existing obligations or create them from contract analysis.
GET /api/now/table/clm_obligation?sysparm_query=contract=[contract_sys_id]^active=true&sysparm_fields=sys_id,short_description,obligation_type,responsible_party,due_date,state,compliance_status,clause_reference,frequency&sysparm_limit=50&sysparm_display_value=true
Step 5: Build Metadata Extraction Report
Generate a comprehensive metadata extraction:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var contractNumber = 'CON0045678'; // Replace with target contract
var gr = new GlideRecord('ast_contract');
gr.addQuery('number', contractNumber);
gr.query();
if (gr.next()) {
var metadata = {
extraction_date: new GlideDateTime().toString(),
contract_id: gr.number.toString(),
parties: {
buyer: {
name: gs.getProperty('glide.servlet.uri', 'Your Organization'),
contact: gr.contract_administrator.getDisplayValue()
},
vendor: {
name: gr.vendor.getDisplayValue(),
contact: ''
}
},
dates: {
effective_date: gr.starts.toString(),
expiration_date: gr.ends.toString(),
renewal_date: gr.renewal_date.toString(),
execution_date: gr.sys_created_on.toString()
},
financials: {
total_value: gr.total_cost.toString(),
payment_amount: gr.payment_amount.toString(),
currency: gr.currency.getDisplayValue() || 'USD',
payment_terms: gr.payment_terms.getDisplayValue() || 'Not specified'
},
renewal: {
auto_renew: gr.auto_renew.toString() == 'true',
notice_period_days: gr.notice_period.toString() || 'Not specified',
notice_deadline: ''
},
governing_law: gr.governing_law.getDisplayValue() || 'Not specified',
contract_type: gr.contract_type.getDisplayValue(),
state: gr.state.getDisplayValue(),
obligations: [],
metadata_completeness: 0
};
// Calculate notice deadline
if (metadata.renewal.auto_renew && gr.ends.toString() && gr.notice_period.toString()) {
var endDate = new GlideDateTime(gr.ends.toString());
var noticeDays = parseInt(gr.notice_period.toString()) || 0;
endDate.addDaysUTC(-noticeDays);
metadata.renewal.notice_deadline = endDate.toString();
}
// Get vendor contact
var vendor = new GlideRecord('core_company');
if (vendor.get(gr.vendor.toString())) {
metadata.parties.vendor.contact = vendor.primary_contact.getDisplayValue();
}
// Get obligations
var obl = new GlideRecord('clm_obligation');
obl.addQuery('contract', gr.sys_id.toString());
obl.addQuery('active', true);
obl.query();
while (obl.next()) {
metadata.obligations.push({
description: obl.short_description.toString(),
type: obl.obligation_type.getDisplayValue(),
responsible: obl.responsible_party.getDisplayValue(),
due_date: obl.due_date.toString(),
status: obl.compliance_status.getDisplayValue()
});
}
// Metadata completeness score
var fields = ['total_cost', 'starts', 'ends', 'vendor', 'contract_type', 'governing_law', 'notice_period', 'payment_terms'];
var filled = 0;
for (var i = 0; i < fields.length; i++) {
if (gr.getValue(fields[i])) filled++;
}
metadata.metadata_completeness = Math.round((filled / fields.length) * 100);
gs.info('CONTRACT METADATA EXTRACTION:\n' + JSON.stringify(metadata, null, 2));
}
description: "CLM: Extract comprehensive metadata from a contract record"
Step 6: Create Missing Obligations from Analysis
Create obligation records discovered during extraction:
Tool: SN-Create-Record
Parameters:
table_name: clm_obligation
fields:
contract: [contract_sys_id]
short_description: "Annual SOC 2 Type II report delivery"
obligation_type: vendor_obligation
responsible_party: [vendor_sys_id]
due_date: 2026-06-30
frequency: annual
clause_reference: "Section 9.3 - Audit and Compliance"
state: active
compliance_status: pending
Using REST API:
POST /api/now/table/clm_obligation
Content-Type: application/json
{
"contract": "[contract_sys_id]",
"short_description": "Annual SOC 2 Type II report delivery",
"obligation_type": "vendor_obligation",
"responsible_party": "[vendor_sys_id]",
"due_date": "2026-06-30",
"frequency": "annual",
"clause_reference": "Section 9.3",
"state": "active"
}
Step 7: Update Contract Record with Extracted Metadata
Consistent Taxonomy: Use standardized obligation types and clause categories to enable portfolio-wide analysis
Completeness Scoring: Track metadata completeness percentage for each contract; target 90%+ for active contracts
Renewal Calendar: Build a centralized renewal calendar from extracted dates; alert 90 days before notice deadlines
Party Normalization: Ensure vendor names are linked to core_company records to avoid duplicate vendor entries
Version Control: Always extract metadata from the most recent executed version of the contract document
Obligation Ownership: Assign clear responsible parties (buyer vs. vendor) for each obligation
Financial Standardization: Normalize all financial values to a single currency for portfolio reporting
Audit Trail: Record who performed the extraction and when; note any assumptions or ambiguities
Troubleshooting
Contract Document Content Is Empty
Symptom:clm_contract_doc records exist but the content field is null
Cause: Contract content may be stored as attachments rather than inline in the content field
Solution: Query sys_attachment with table_name=clm_contract_doc^table_sys_id=[doc_sys_id] to find the actual document file.
Governing Law Field Not Available
Symptom: The governing_law field does not exist on ast_contractCause: This field may be a custom addition or use a different name like jurisdiction or applicable_lawSolution:
Search for fields containing "law", "jurisdiction", or "govern" in the element name or label.
Obligation Types Do Not Match Expected Values
Symptom: Obligation type choices do not include expected categories
Cause: Choice values are organization-specific and may differ from defaults
Solution: Query sys_choice with name=clm_obligation^element=obligation_type to see available choices. Add custom choices if needed.
Examples
Example 1: New Contract Metadata Population
Scenario: Legal assistant uploads a new vendor agreement and needs metadata extracted