skills/document/document-extraction/SKILL.md
Extract structured data from documents (invoices, forms, contracts) using ServiceNow Document Intelligence with extraction template configuration and validation rules
npx skillsauth add happy-technologies-llc/happy-servicenow-skills document-extractionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides a structured approach to extracting structured data from documents using ServiceNow Document Intelligence. It helps you:
sn_doc_template for different document types (invoices, contracts, forms, purchase orders)sn_doc_intelligence_extraction pipelinesn_doc_intelligence_field_map to map extracted data to ServiceNow table fieldssn_doc_intelligence_extraction_resultWhen to use: When you need to process documents at scale (batch invoice processing, contract metadata extraction, form digitization), when manually entering data from documents is error-prone or time-consuming, or when setting up new document processing pipelines.
Plugin required: com.sn_doc_intelligence
sn_doc_intelligence_admin, sn_doc_intelligence_user, or adminsn_doc_intelligence_extraction, sn_doc_template, sn_doc_intelligence_field_map, and sys_attachment tablescom.sn_doc_intelligence) must be activatedCheck which document extraction templates are already configured in your instance.
Using MCP (Claude Code/Desktop):
Tool: SN-Query-Table
Parameters:
table_name: sn_doc_template
query: active=true
fields: sys_id,name,description,document_type,target_table,state,extraction_model,confidence_threshold,field_count
limit: 50
order_by: name
Using REST API:
GET /api/now/table/sn_doc_template?sysparm_query=active=true^ORDERBYname&sysparm_fields=sys_id,name,description,document_type,target_table,state,extraction_model,confidence_threshold,field_count&sysparm_limit=50&sysparm_display_value=true
Common template types:
| Document Type | Target Table | Use Case |
|--------------|-------------|----------|
| Invoice | sn_proc_invoice | AP invoice processing |
| Purchase Order | proc_po | PO data entry |
| Contract | ast_contract | Contract metadata extraction |
| W-9 / Tax Form | core_company | Vendor tax information |
| ID Document | sys_user | Identity verification |
| Insurance Certificate | ast_contract | COI tracking |
| Work Order | wm_order | Field service documents |
If no template exists for your document type, create one.
Using MCP:
Tool: SN-Create-Record
Parameters:
table_name: sn_doc_template
fields:
name: "Vendor Invoice Template"
description: "Extracts header and line-item data from vendor invoices for accounts payable processing"
document_type: invoice
target_table: sn_proc_invoice
confidence_threshold: 0.85
active: true
state: draft
Using REST API:
POST /api/now/table/sn_doc_template
Content-Type: application/json
{
"name": "Vendor Invoice Template",
"description": "Extracts header and line-item data from vendor invoices",
"document_type": "invoice",
"target_table": "sn_proc_invoice",
"confidence_threshold": "0.85",
"active": "true",
"state": "draft"
}
Map document fields to ServiceNow table columns for each extraction template.
Using MCP:
Tool: SN-Create-Record
Parameters:
table_name: sn_doc_intelligence_field_map
fields:
template: [template_sys_id]
source_field: "Invoice Number"
target_table: sn_proc_invoice
target_field: number
field_type: string
required: true
validation_regex: "^INV-[0-9]{4,10}$"
order: 100
Repeat for each field mapping:
| Source Field (Document) | Target Field (Table) | Type | Required | Validation |
|------------------------|---------------------|------|----------|------------|
| Invoice Number | number | String | Yes | Pattern match |
| Invoice Date | invoice_date | Date | Yes | Valid date |
| Due Date | due_date | Date | Yes | After invoice date |
| Vendor Name | vendor | Reference | Yes | Match core_company |
| PO Number | po_number | String | No | Match proc_po |
| Subtotal | subtotal | Currency | Yes | Positive number |
| Tax Amount | tax | Currency | No | Non-negative |
| Total Amount | invoice_amount | Currency | Yes | subtotal + tax |
| Line Item Description | line_items.description | String | Yes | Non-empty |
| Line Quantity | line_items.quantity | Integer | Yes | Positive integer |
| Line Unit Price | line_items.unit_price | Currency | Yes | Positive number |
Using REST API:
POST /api/now/table/sn_doc_intelligence_field_map
Content-Type: application/json
{
"template": "[template_sys_id]",
"source_field": "Invoice Number",
"target_table": "sn_proc_invoice",
"target_field": "number",
"field_type": "string",
"required": "true",
"validation_regex": "^INV-[0-9]{4,10}$",
"order": "100"
}
Create an extraction request to process a document through the pipeline.
Using MCP:
Tool: SN-Create-Record
Parameters:
table_name: sn_doc_intelligence_extraction
fields:
template: [template_sys_id]
source_document: [attachment_sys_id]
document_type: invoice
state: submitted
priority: 3
requested_by: [user_sys_id]
short_description: "Extract data from vendor invoice INV-2026-0456"
Using REST API:
POST /api/now/table/sn_doc_intelligence_extraction
Content-Type: application/json
{
"template": "[template_sys_id]",
"source_document": "[attachment_sys_id]",
"document_type": "invoice",
"state": "submitted",
"priority": "3",
"requested_by": "[user_sys_id]",
"short_description": "Extract data from vendor invoice INV-2026-0456"
}
For batch processing, submit multiple documents:
# Iterate over attachments and create extraction records
for attachment_id in [list_of_attachment_sys_ids]; do
curl -X POST "https://[instance].service-now.com/api/now/table/sn_doc_intelligence_extraction" \
-H "Content-Type: application/json" \
-d "{\"template\":\"[template_sys_id]\",\"source_document\":\"$attachment_id\",\"document_type\":\"invoice\",\"state\":\"submitted\"}"
done
Track the status of submitted extraction requests.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_doc_intelligence_extraction
query: state=submitted^ORstate=processing^ORstate=review
fields: sys_id,number,short_description,state,template,document_type,source_document,confidence_score,sys_created_on,error_message
limit: 50
order_by: sys_created_on
Using REST API:
GET /api/now/table/sn_doc_intelligence_extraction?sysparm_query=state=submitted^ORstate=processing^ORstate=review^ORDERBYDESCsys_created_on&sysparm_fields=sys_id,number,short_description,state,template,document_type,source_document,confidence_score,sys_created_on,error_message&sysparm_limit=50&sysparm_display_value=true
Examine the extracted data and confidence scores for each field.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_doc_intelligence_extraction_result
query: extraction=[extraction_sys_id]
fields: sys_id,field_name,extracted_value,confidence_score,validation_status,mapped_field,needs_review
limit: 100
order_by: order
Using REST API:
GET /api/now/table/sn_doc_intelligence_extraction_result?sysparm_query=extraction=[extraction_sys_id]^ORDERBYorder&sysparm_fields=sys_id,field_name,extracted_value,confidence_score,validation_status,mapped_field,needs_review&sysparm_limit=100&sysparm_display_value=true
Evaluate results against thresholds:
| Confidence Level | Action Required | |-----------------|-----------------| | >= 0.95 | Auto-accept; no review needed | | 0.85 - 0.94 | Accept with spot-check | | 0.70 - 0.84 | Manual review required | | < 0.70 | Flag for re-extraction or manual entry |
For fields that need review, update the extraction results.
Using MCP:
Tool: SN-Update-Record
Parameters:
table_name: sn_doc_intelligence_extraction_result
sys_id: [result_sys_id]
data:
extracted_value: "INV-2026-0456"
validation_status: validated
needs_review: false
reviewer_notes: "Corrected invoice number; OCR misread '0' as 'O'"
Using REST API:
PATCH /api/now/table/sn_doc_intelligence_extraction_result/[result_sys_id]
Content-Type: application/json
{
"extracted_value": "INV-2026-0456",
"validation_status": "validated",
"needs_review": "false",
"reviewer_notes": "Corrected invoice number; OCR misread '0' as 'O'"
}
Once all fields are validated, mark the extraction as complete and create or update the target record.
Using MCP:
Tool: SN-Update-Record
Parameters:
table_name: sn_doc_intelligence_extraction
sys_id: [extraction_sys_id]
data:
state: completed
work_notes: "Extraction validated. 12/14 fields auto-accepted (>95% confidence). 2 fields manually corrected. Target record created in sn_proc_invoice."
Create the target record with extracted data:
Tool: SN-Create-Record
Parameters:
table_name: sn_proc_invoice
fields:
number: "INV-2026-0456"
vendor: [vendor_sys_id]
invoice_date: "2026-03-15"
due_date: "2026-04-14"
invoice_amount: "15750.00"
po_number: "PO0012345"
state: pending
source: document_intelligence
work_notes: "Record created via Document Intelligence extraction [extraction_number]"
Using REST API:
PATCH /api/now/table/sn_doc_intelligence_extraction/[extraction_sys_id]
Content-Type: application/json
{
"state": "completed",
"work_notes": "Extraction validated. Target record created."
}
| Tool | When to Use |
|------|-------------|
| SN-NL-Search | Find extraction records or templates by description |
| SN-Query-Table | Query templates, extractions, results, and field mappings |
| SN-Read-Record | Retrieve a specific extraction or template record |
| SN-Create-Record | Create templates, field mappings, and extraction requests |
| SN-Update-Record | Update extraction status, validate results, correct data |
| SN-Add-Work-Notes | Document extraction outcomes and processing notes |
| Endpoint | Method | Purpose |
|----------|--------|---------|
| /api/now/table/sn_doc_template | GET/POST | Query or create extraction templates |
| /api/now/table/sn_doc_intelligence_field_map | GET/POST | Query or create field mappings |
| /api/now/table/sn_doc_intelligence_extraction | GET/POST/PATCH | Manage extraction requests |
| /api/now/table/sn_doc_intelligence_extraction_result | GET/PATCH | Review and correct extraction results |
| /api/now/table/sys_attachment | GET | Query document attachments |
| /api/now/attachment/{sys_id}/file | GET | Download source documents |
sn_doc_intelligence_task for documents that fail extraction, routing them to data entry staffCause: Template is inactive or the document type does not match
Solution: Query sn_doc_template with active=true to see available templates. Verify the document_type field matches your submission.
Cause: Poor document quality (low resolution, skewed scan, handwritten text) or template mismatch Solution: Check document resolution (minimum 300 DPI for OCR). Verify the document matches the template's expected layout. Consider creating a new template for non-standard formats.
Cause: Extracted value does not match the validation regex or target field type
Solution: Review the validation rule in sn_doc_intelligence_field_map. Update the regex to accommodate legitimate variations (e.g., different invoice number formats across vendors).
Cause: Document Intelligence engine timeout or processing queue backup
Solution: Check the sn_doc_intelligence_extraction record for error messages. Verify the Document Intelligence engine is running: navigate to Document Intelligence > Dashboard. Re-submit the extraction if needed.
Cause: Same document submitted multiple times
Solution: Before submitting, query sn_doc_intelligence_extraction with source_document=[attachment_sys_id]^state!=failed to check for existing extractions.
Input: PDF invoice from Acme Corp uploaded to ServiceNow
Process:
sn_proc_invoiceInput: Signed MSA PDF for legal review
Process:
Tool: SN-Create-Record
Parameters:
table_name: sn_doc_intelligence_extraction
fields:
template: [contract_template_sys_id]
source_document: [attachment_sys_id]
document_type: contract
state: submitted
short_description: "Extract metadata from Acme Corp MSA"
Fields extracted: Contract parties, effective date, term length, total value, governing law, auto-renewal flag, notice period. Populates ast_contract record automatically.
Input: 50 W-9 forms uploaded for vendor onboarding
Process:
core_company with extracted TIN, legal name, addresssn_doc_intelligence_taskQuery for batch status:
Tool: SN-Query-Table
Parameters:
table_name: sn_doc_intelligence_extraction
query: template=[w9_template_sys_id]^sys_created_on>=2026-03-19
fields: sys_id,number,state,confidence_score,error_message
limit: 50
document/smart-documents - Manage document templates, versioning, and automated generationlegal/contract-analysis - Analyze extracted contract data for risks and termslegal/contract-obligation-extraction - Extract obligations from contract documentsprocurement/invoice-management - Process extracted invoice data through AP workflowsadmin/data-import - Bulk import extracted data into ServiceNow tablestesting
Manage supplier onboarding, qualification, performance monitoring, and offboarding with auditable lifecycle controls
tools
Identify emerging risks, prioritize intake signals, and route candidates into formal GRC risk assessment workflows
documentation
Screen inbound documents for completeness, policy risk, and routing readiness before extraction or case workflows
testing
Generate concise task summaries with status, timeline, blockers, SLA risk, and recommended next actions