Azure Content Understanding
Azure Content Understanding is Microsoft's newest AI service in Foundry Tools — a unified pipeline that ingests and analyses any content modality: documents, images, videos, and audio. Unlike Document Intelligence (which specialises in structured form data) or AI Search (which makes content searchable), Content Understanding is built for multi-modal AI enrichment at scale — summarising, classifying, extracting, and understanding diverse content through a single, consistent API.
Content Understanding terms — defined before code
You have learned the async POST-then-poll pattern (from Document Intelligence in Topic 2), REST APIs and endpoints (from Part 1), and the concept of AI enrichment pipelines (from AI Search skillsets in Topic 1). Content Understanding uses all of these patterns — just applied to a wider range of content types. The new vocabulary below is specific to this service.
An Azure AI Foundry service that processes and extracts meaning from any content type — documents (PDFs, Word), images (JPEG, PNG), videos (MP4), and audio (WAV, MP3) — through a single, unified API. It applies AI operations like summarisation, classification, entity extraction, and OCR across all these modalities. Available through Azure AI Foundry portal and REST API.
The type of content being processed. Content Understanding supports four modalities: Document (PDFs, Word files, Excel, text files), Image (photos, diagrams, scanned pages), Video (MP4 files, video streams — analysed as sequences of keyframes + audio), Audio (spoken word recordings, phone calls, meeting audio). Most services only handle one modality — Content Understanding handles all four.
A configured AI processing pipeline you define inside Content Understanding. Think of it as a reusable "analysis template" — you define what operations to perform (summarise, classify, extract entities, run OCR) and on what modality. Once created, you submit content to the analyzer and get back structured results. One analyzer can be reused for many documents.
A predefined set of operations grouped together for common scenarios — pre-packaged analyzers for common document types. Examples: prebuilt-documentAnalysis (general document extraction), prebuilt-read (OCR text extraction), prebuilt-imageAnalysis (image understanding). Templates mean you don't always need to build a custom analyzer from scratch.
When building a custom analyzer, the field schema defines exactly which fields you want extracted and their data types. Example: you want to extract "ContractValue" (number), "ExpiryDate" (date), and "PartyNames" (list of strings) from legal contracts. The AI uses the field schema as instructions for what to look for in each document.
The text extraction step applied to documents and images. Content Understanding uses Azure's latest OCR engine to extract printed and handwritten text from documents before applying downstream AI operations. The OCR pipeline identifies text, its position, and its structure (paragraphs, tables, headings). Every document and image analysis begins with OCR as the foundation.
An AI operation that generates a concise summary of a long document — capturing the main points without requiring you to read the whole document. Content Understanding uses Azure OpenAI models under the hood to produce the summary. The summary length and style can be configured. Applied at the document level (one summary per document) or section level (summaries per section).
An AI operation that assigns a category label to a document based on its content. Example: you receive mixed correspondence — the classifier automatically labels each document as "Invoice", "Contract", "Complaint Letter", or "Support Request". You define the possible categories and optionally provide examples. The classifier then routes or tags incoming documents automatically.
For video content, Content Understanding doesn't analyse every single frame (that would be millions of images). Instead it extracts keyframes — representative frames that capture significant moments or scene changes — and analyses those. This dramatically reduces processing time while still capturing the important visual content of the video.
For audio and video content, Content Understanding automatically transcribes the spoken audio into text using Azure Speech services. The transcript includes speaker diarisation (identifying who is speaking when) and timestamps. This transcript then feeds into text-based AI operations — summarisation, entity extraction, sentiment — applied to the spoken content.
An AI operation that identifies and extracts named entities from content — people, organisations, locations, dates, amounts, product names — and returns them as structured fields. Applied to text from documents, image captions from pictures, and transcripts from audio/video. Same concept as Named Entity Recognition (NER) from Part 4 NLP, but applied here in the Content Understanding pipeline.
An AI operation that detects tables in documents or images and returns them as structured data — rows, columns, header labels, and cell values — in a format your code can directly process. Part of the OCR pipeline for documents. Enables you to extract financial tables, schedules, or data grids without writing custom parsing code.
The problem of multi-modal content at scale
Imagine a large media company that receives thousands of pieces of content every day: PDF reports from analysts,
photo submissions from journalists, recorded video interviews, and audio recordings from press conferences.
Previously, they needed four completely different tools and teams — one for each content type.
Each tool had its own API, its own output format, its own quirks.
Content Understanding is like hiring one expert assistant who can read any PDF, describe any photo,
transcribe and summarise any video, and extract insights from any audio recording — all using the same set of
instructions and returning results in the same output format.
That consistency and universality is what makes Content Understanding powerful. The same begin_analyze
call. The same structured output schema. One service, four modalities.
The four modalities — what Content Understanding processes
PDF, Word (.docx), Excel (.xlsx), PowerPoint (.pptx), plain text files. Operations: OCR (text extraction), summarisation, classification, entity extraction, table extraction, image extraction from embedded images. The most feature-rich modality.
JPEG, PNG, BMP, TIFF, GIF. Operations: OCR (text in images), caption generation (what is depicted), object and attribute detection, classification (what kind of image is this). Useful for processing scanned documents, photos, and diagrams.
MP4, MOV, AVI. Operations: keyframe extraction + analysis (what is shown), audio transcription (what is said), speaker diarisation (who said what when), scene summarisation. Covers both visual and audio content in a single pass.
WAV, MP3, M4A, OGG. Operations: speech-to-text transcription, speaker diarisation, sentiment analysis on spoken content, keyword and entity extraction from transcript. Ideal for call centre recordings, meeting audio, voice memos.
Choosing the right service for the job — the exam decision table
These three services (all in Part 5) are closely related and the exam will give you scenarios requiring you to choose between them. Here is the complete decision guide:
| Scenario | Best Service | Why |
|---|---|---|
| Extract "InvoiceTotal", "VendorName", "DueDate" from invoices | Document Intelligence | Purpose-built for structured field extraction from known document types. Prebuilt invoice model exists. High accuracy, field-level confidence scores. |
| Make 10,000 PDF reports searchable by keyword and meaning | Azure AI Search | Purpose-built for search — index, query, filter, facet. Skillset pipeline handles OCR and enrichment. Users query the index via a search bar. |
| Summarise a 200-page contract and extract clause entities | Content Understanding | Summarisation and entity extraction from long documents. Content Understanding uses LLMs for understanding, not just pattern-matching. |
| Transcribe a call centre recording and extract customer sentiment | Content Understanding | Audio modality — transcript, speaker diarisation, and downstream NLP (sentiment, entities) from speech in one pipeline. |
| Index video interviews so journalists can search by topic or keyword | Content Understanding + AI Search | Use Content Understanding to extract transcripts and keyframe descriptions, then feed enriched output into AI Search for full-text querying. |
| Classify incoming emails as "Invoice", "Contract", or "Complaint" | Content Understanding | Document classification feature — define categories, submit documents, get labels automatically. |
| Extract tables from financial reports — rows, columns, values | Content Understanding or Document Intelligence | Both can extract tables. Document Intelligence uses Layout model. Content Understanding uses table extraction as part of its document pipeline. Either is valid — context determines the best choice. |
| Process PDFs, images, videos, AND audio through one unified API | Content Understanding | Only Content Understanding handles all four modalities. Document Intelligence handles documents only. AI Search can index all via skillsets but is query-focused, not extraction-focused. |
"Extract specific named fields" (invoice total, vendor name) → Document Intelligence
"Search / query / find across documents" → Azure AI Search
"Summarise / classify / understand meaning" or "audio / video / multi-modal" → Content Understanding
When a scenario mentions processing audio recordings or video files with AI — it is always Content Understanding, not the other two services.
The analyzer pipeline — from content to structured output
Either use a prebuilt analyzer template (e.g. prebuilt-documentAnalysis) or create a custom analyzer by defining: which modality (document, image, video, audio), which operations (OCR, summarise, classify, extract entities), and a field schema describing what fields to extract. The analyzer definition is stored in your Azure AI Foundry resource.
POST the content to the analyzer — either as a file URL (from Azure Blob Storage) or as binary bytes. The service accepts the submission and returns an operation ID. This is the same async pattern you learned in Document Intelligence (Topic 2): you get a ticket number and poll for the result.
The service runs the foundation pass appropriate to the modality. For documents and images: OCR extracts all text and identifies structure. For audio: Speech-to-Text transcribes spoken content. For video: keyframes are extracted from each scene, and audio is transcribed. This foundation output feeds all subsequent AI operations.
Based on your analyzer configuration, AI models process the foundation output: a language model reads the text/transcript and generates a summary; a classification model assigns the document to one of your defined categories; an entity extraction model identifies named entities and maps them to your field schema. These operations run in parallel or in sequence as configured.
Poll the operation status URL using the operation ID from Step 2. When status is "succeeded", retrieve the result — a structured JSON object containing: the full OCR transcript, extracted tables, detected entities, classification label, generated summary, keyframe descriptions (for video), and any custom field values you defined in the schema. Your application processes this JSON directly.
What the output looks like — a document result example
After analysis completes, the result JSON contains sections like this:
{
"status": "succeeded",
"result": {
"contents": [
{
"kind": "document",
"markdown": "# Contract Agreement\n\nThis contract...", // Full OCR text as markdown
"fields": {
"ContractValue": { "valueNumber": 150000.00, "confidence": 0.95 },
"ExpiryDate": { "valueDate": "2026-12-31", "confidence": 0.98 },
"PartyNames": { "valueArray": ["Contoso Ltd", "Fabrikam Inc"], "confidence": 0.97 }
},
"summary": "This contract between Contoso Ltd and Fabrikam Inc...",
"classificationLabel": "LegalContract",
"tables": [ // Extracted tables
{ "rowCount": 5, "columnCount": 3, "cells": [...] }
]
}
]
}
}
Creating an analyzer and submitting documents for analysis
Content Understanding is a newer service and its dedicated Python SDK (azure-ai-contentunderstanding) is still evolving. The most reliable approach for the current exam is using the REST API directly with the requests library (which you already know from Part 1), or using the Azure AI Projects SDK as a wrapper. The code below shows both approaches so you recognise either in the exam.
Install: pip install requests azure-identity azure-ai-projects
import os
import time # The 'time' module lets us pause execution (time.sleep) while polling
import requests # The 'requests' library lets us make HTTP REST API calls
import json # The 'json' module converts Python dicts to JSON strings and back
# ── Connection details ─────────────────────────────────────────────────
# These come from your Azure AI Foundry resource in Azure portal
# Navigate to: Azure AI Foundry → your project → Settings → API Keys
ENDPOINT = os.environ.get("CONTENTUNDERSTANDING_ENDPOINT")
# The endpoint format is: https://<your-resource>.cognitiveservices.azure.com/
API_KEY = os.environ.get("CONTENTUNDERSTANDING_KEY")
# Store API keys in environment variables — never hardcode them in your script
# API version — Content Understanding requires a specific API version in the URL
# Always check Microsoft docs for the latest stable version
API_VERSION = "2024-12-01-preview"
# HTTP headers — sent with every request to authenticate and specify content type
headers = {
"Ocp-Apim-Subscription-Key": API_KEY, # The standard Azure key header
"Content-Type": "application/json" # We are sending JSON in the request body
}
# ══════════════════════════════════════════════════════════════════════
# STEP 1 — Create a custom Analyzer
# An analyzer is a reusable configuration that defines:
# - Which content modality (document, image, video, audio)
# - Which AI operations to perform
# - What fields to extract (the field schema)
# ══════════════════════════════════════════════════════════════════════
# A unique name for your analyzer (letters, numbers, hyphens only)
ANALYZER_NAME = "contract-analyzer-v1"
# The analyzer definition — a dictionary that becomes the JSON request body
analyzer_definition = {
# description: a human-readable name for this analyzer (optional)
"description": "Extracts key fields from legal contract documents",
# scenario: tells the service what kind of content this analyzer handles
# Options: "documentAnalysis" (docs/images), "videoAnalysis", "audioAnalysis"
"scenario": "documentAnalysis",
# fieldSchema: defines the specific fields you want extracted
# The AI will look for these fields in every document submitted to this analyzer
"fieldSchema": {
"fields": {
# Each key is the field name you want in the output
# "type" tells the service what data type this field contains
"ContractValue": {
"type": "number", # A numeric value (e.g. 150000.00)
"description": "The total monetary value of the contract"
},
"ExpiryDate": {
"type": "date", # A date value (e.g. "2026-12-31")
"description": "The date when the contract expires"
},
"PartyNames": {
"type": "array", # A list of values
"items": {"type": "string"}, # Each item in the list is a string
"description": "Names of all parties involved in the contract"
},
"GoverningLaw": {
"type": "string", # A text/string value
"description": "The jurisdiction or country whose law governs the contract"
}
}
}
}
# Build the URL for creating the analyzer
# Format: {endpoint}/contentunderstanding/analyzers/{name}?api-version={version}
create_url = (
f"{ENDPOINT}contentunderstanding/analyzers/{ANALYZER_NAME}"
f"?api-version={API_VERSION}"
)
# PUT request creates or updates the analyzer (idempotent — safe to run again)
# json.dumps() converts our Python dictionary into a JSON string for the HTTP body
response = requests.put(create_url, headers=headers, data=json.dumps(analyzer_definition))
# Check the response status code:
# 200 = updated existing, 201 = created new — both mean success
if response.status_code in (200, 201):
print(f"✅ Analyzer '{ANALYZER_NAME}' created/updated successfully.")
else:
# response.text contains the error message from the API
print(f"❌ Failed to create analyzer: {response.status_code} — {response.text}")
raise SystemExit(1) # Stop the script — no point continuing without the analyzer
# ══════════════════════════════════════════════════════════════════════
# STEP 2 — Submit a document for analysis
# Same async pattern as Document Intelligence: POST → get operation ID → poll
# ══════════════════════════════════════════════════════════════════════
# URL of the document to analyse — must be publicly accessible or in Azure Blob Storage
document_url = "https://your-storage.blob.core.windows.net/contracts/contract-001.pdf"
# Build the URL for submitting an analysis job to your analyzer
analyze_url = (
f"{ENDPOINT}contentunderstanding/analyzers/{ANALYZER_NAME}:analyze"
f"?api-version={API_VERSION}"
)
# The request body specifies what to analyse
# url: a publicly accessible URL to the document
analyze_body = {
"url": document_url
}
# POST request submits the analysis job
# The service does NOT process it immediately — it queues it and returns an operation ID
response = requests.post(analyze_url, headers=headers, data=json.dumps(analyze_body))
# 202 Accepted means the job was queued successfully (not completed yet)
if response.status_code != 202:
print(f"❌ Failed to submit document: {response.status_code} — {response.text}")
raise SystemExit(1)
# The operation URL is in the "Operation-Location" response header
# This is the URL we will poll to check the status and get results
operation_url = response.headers["Operation-Location"]
print(f"✅ Analysis job submitted. Operation URL: {operation_url}")
# ══════════════════════════════════════════════════════════════════════
# STEP 3 — Poll until the operation completes
# Keep checking the operation URL every few seconds until status = "succeeded"
# ══════════════════════════════════════════════════════════════════════
print("⏳ Waiting for analysis to complete...")
result = None
# A while loop runs repeatedly until we tell it to stop
# We loop until the operation status is "succeeded" or "failed"
while True:
# GET request to the operation URL — returns current status and (when done) results
poll_response = requests.get(operation_url, headers=headers)
poll_data = poll_response.json() # Parse the JSON response into a Python dictionary
status = poll_data.get("status") # "running", "notStarted", "succeeded", or "failed"
print(f" Status: {status}")
if status == "succeeded":
# Analysis is complete — save the full result dictionary
result = poll_data
break # Exit the while loop — we have our results
elif status == "failed":
# Something went wrong — print the error and stop
print(f"❌ Analysis failed: {poll_data.get('error', {}).get('message', 'Unknown error')}")
raise SystemExit(1)
else:
# Still processing — wait 3 seconds before checking again
# time.sleep(3) pauses the script for 3 seconds without using CPU
time.sleep(3)
# ══════════════════════════════════════════════════════════════════════
# STEP 4 — Read the results
# ══════════════════════════════════════════════════════════════════════
# result["result"]["contents"] is a list — one item per analysed content unit
# For a single document, it will have one item
contents = result.get("result", {}).get("contents", [])
for content in contents:
# content["kind"] tells you the modality: "document", "image", "video", "audio"
print(f"\n=== Content Kind: {content.get('kind')} ===")
# ── Extracted Fields (from your field schema) ──
fields = content.get("fields", {})
if fields:
print("\n📋 Extracted Fields:")
for field_name, field_data in fields.items():
# Each field has a value and a confidence score
# The value key varies by type: valueNumber, valueDate, valueString, valueArray
confidence = field_data.get("confidence", 0)
# Look for any key starting with "value" to get the actual extracted value
value = (field_data.get("valueNumber")
or field_data.get("valueDate")
or field_data.get("valueString")
or field_data.get("valueArray"))
print(f" {field_name}: {value} (confidence: {confidence:.2f})")
# ── Summary (if summarisation was enabled in the analyzer) ──
summary = content.get("summary")
if summary:
print(f"\n📝 Summary:\n {summary[:300]}...") # Print first 300 characters
# ── Classification Label (if classification was enabled) ──
label = content.get("classificationLabel")
if label:
print(f"\n🏷️ Classification: {label}")
# ── Tables (extracted table data) ──
tables = content.get("tables", [])
if tables:
print(f"\n📊 Tables found: {len(tables)}")
for i, table in enumerate(tables):
print(f" Table {i+1}: {table.get('rowCount')} rows × {table.get('columnCount')} cols")
# ── Full OCR Text (as markdown) ──
markdown = content.get("markdown")
if markdown:
# The full OCR text — headings, paragraphs, tables as markdown formatted text
print(f"\n📄 Full OCR text ({len(markdown)} chars) — first 200:\n {markdown[:200]}...")
Python — Submitting an Audio file for transcription and analysis
# ── Audio analyzer — transcription + entity extraction ──────────────────
# First: create an audio analyzer (same pattern as document analyzer above)
audio_analyzer_definition = {
"description": "Transcribes call recordings and extracts customer entities",
"scenario": "audioAnalysis", # Must be "audioAnalysis" for audio files
"fieldSchema": {
"fields": {
"CustomerName": {
"type": "string",
"description": "The name of the customer speaking in the recording"
},
"IssueType": {
"type": "string",
"description": "The type of issue the customer is reporting"
},
"Sentiment": {
"type": "string",
"description": "Overall customer sentiment: Positive, Neutral, or Negative"
}
}
}
}
AUDIO_ANALYZER_NAME = "call-center-audio-analyzer"
# Create the audio analyzer (PUT request — same pattern as document analyzer)
audio_create_url = (
f"{ENDPOINT}contentunderstanding/analyzers/{AUDIO_ANALYZER_NAME}"
f"?api-version={API_VERSION}"
)
requests.put(audio_create_url, headers=headers, data=json.dumps(audio_analyzer_definition))
# Submit an audio file for analysis
audio_analyze_url = (
f"{ENDPOINT}contentunderstanding/analyzers/{AUDIO_ANALYZER_NAME}:analyze"
f"?api-version={API_VERSION}"
)
# The audio file URL — must be a WAV, MP3, or M4A file in Azure Blob Storage
audio_body = {
"url": "https://your-storage.blob.core.windows.net/calls/call-20241201-001.wav"
}
response = requests.post(audio_analyze_url, headers=headers, data=json.dumps(audio_body))
# operation_url is in response.headers["Operation-Location"]
# Then poll the operation URL until status == "succeeded" (same loop as above)
# The result will contain:
# content["transcript"] → Full speech-to-text transcript with timestamps
# content["fields"]["CustomerName"] → Extracted customer name from the transcript
# content["fields"]["IssueType"] → Extracted issue type
# content["fields"]["Sentiment"] → Detected sentiment
print(f"Audio job submitted: {response.headers.get('Operation-Location', 'N/A')}")
Content Understanding — what the exam tests
1. Content Understanding = the only service for audio and video AI analysis — If a scenario mentions processing audio recordings, phone calls, or video files with AI to extract insights, classify, or summarise — the answer is Content Understanding. Document Intelligence and AI Search do not handle audio or raw video files.
2. Four modalities, one consistent API — Documents, Images, Videos, Audio. All are submitted via the same analyzer pattern. This is the unique selling point of Content Understanding vs the other services.
3. Field schema defines what to extract — like giving instructions — You define field names and types in the analyzer. The AI reads the document and fills in your fields. No pre-trained model for your specific fields exists — the LLM understands the field description you write in plain English.
4. Async pattern — same as Document Intelligence — POST → 202 Accepted → Operation-Location header → poll GET → "succeeded" → read results. If the exam asks how results are returned, it is always async polling for Content Understanding.
5. Content Understanding vs Document Intelligence — the key distinction — Document Intelligence: structured form extraction (invoice total, vendor name, fixed fields with high accuracy). Content Understanding: understanding meaning (summarise, classify, extract entities from any content, handle audio/video). When the scenario asks for "summarise" or involves multi-modal content, choose Content Understanding.
Test your understanding
Which Azure AI service should be used to build this solution?
C is correct. This scenario requires processing audio files end-to-end: transcription, entity extraction, classification, and sentiment — all from audio recordings. Content Understanding's audio modality handles exactly this pipeline in one service. Document Intelligence (B) has no audio capability — it analyses documents and images only. AI Language (D) processes text, not audio directly. AI Search (A) could index the transcripts but requires separate transcription and wouldn't classify or extract fields automatically.