Rei-skills azure-ai-document-intelligence-dotnet
install
source · Clone the upstream repo
git clone https://github.com/rootcastleco/rei-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/rootcastleco/rei-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/azure-ai-document-intelligence-dotnet" ~/.claude/skills/rootcastleco-rei-skills-azure-ai-document-intelligence-dotnet && rm -rf "$T"
manifest:
skills/azure-ai-document-intelligence-dotnet/SKILL.mdsource content
Azure.AI.DocumentIntelligence (.NET)
Extract text, tables, and structured data from documents using prebuilt and custom models.
Installation
dotnet add package Azure.AI.DocumentIntelligence dotnet add package Azure.Identity
Current Version: v1.0.0 (GA)
Environment Variables
DOCUMENT_INTELLIGENCE_ENDPOINT=https://<resource-name>.cognitiveservices.azure.com/ DOCUMENT_INTELLIGENCE_API_KEY=<your-api-key> BLOB_CONTAINER_SAS_URL=https://<storage>.blob.core.windows.net/<container>?<sas-token>
Authentication
Microsoft Entra ID (Recommended)
using Azure.Identity; using Azure.AI.DocumentIntelligence; string endpoint = Environment.GetEnvironmentVariable("DOCUMENT_INTELLIGENCE_ENDPOINT"); var credential = new DefaultAzureCredential(); var client = new DocumentIntelligenceClient(new Uri(endpoint), credential);
Note: Entra ID requires a custom subdomain (e.g.,
), not a regional endpoint.https://<resource-name>.cognitiveservices.azure.com/
API Key
string endpoint = Environment.GetEnvironmentVariable("DOCUMENT_INTELLIGENCE_ENDPOINT"); string apiKey = Environment.GetEnvironmentVariable("DOCUMENT_INTELLIGENCE_API_KEY"); var client = new DocumentIntelligenceClient(new Uri(endpoint), new AzureKeyCredential(apiKey));
Client Types
| Client | Purpose |
|---|---|
| Analyze documents, classify documents |
| Build/manage custom models and classifiers |
Prebuilt Models
| Model ID | Description |
|---|---|
| Extract text, languages, handwriting |
| Extract text, tables, selection marks, structure |
| Extract invoice fields (vendor, items, totals) |
| Extract receipt fields (merchant, items, total) |
| Extract ID document fields (name, DOB, address) |
| Extract business card fields |
| Extract W-2 tax form fields |
| Extract health insurance card fields |
Core Workflows
1. Analyze Invoice
using Azure.AI.DocumentIntelligence; Uri invoiceUri = new Uri("https://example.com/invoice.pdf"); Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync( WaitUntil.Completed, "prebuilt-invoice", invoiceUri); AnalyzeResult result = operation.Value; foreach (AnalyzedDocument document in result.Documents) { if (document.Fields.TryGetValue("VendorName", out DocumentField vendorNameField) && vendorNameField.FieldType == DocumentFieldType.String) { string vendorName = vendorNameField.ValueString; Console.WriteLine($"Vendor Name: '{vendorName}', confidence: {vendorNameField.Confidence}"); } if (document.Fields.TryGetValue("InvoiceTotal", out DocumentField invoiceTotalField) && invoiceTotalField.FieldType == DocumentFieldType.Currency) { CurrencyValue invoiceTotal = invoiceTotalField.ValueCurrency; Console.WriteLine($"Invoice Total: '{invoiceTotal.CurrencySymbol}{invoiceTotal.Amount}'"); } // Extract line items if (document.Fields.TryGetValue("Items", out DocumentField itemsField) && itemsField.FieldType == DocumentFieldType.List) { foreach (DocumentField item in itemsField.ValueList) { var itemFields = item.ValueDictionary; if (itemFields.TryGetValue("Description", out DocumentField descField)) Console.WriteLine($" Item: {descField.ValueString}"); } } }
2. Extract Layout (Text, Tables, Structure)
Uri fileUri = new Uri("https://example.com/document.pdf"); Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync( WaitUntil.Completed, "prebuilt-layout", fileUri); AnalyzeResult result = operation.Value; // Extract text by page foreach (DocumentPage page in result.Pages) { Console.WriteLine($"Page {page.PageNumber}: {page.Lines.Count} lines, {page.Words.Count} words"); foreach (DocumentLine line in page.Lines) { Console.WriteLine($" Line: '{line.Content}'"); } } // Extract tables foreach (DocumentTable table in result.Tables) { Console.WriteLine($"Table: {table.RowCount} rows x {table.ColumnCount} columns"); foreach (DocumentTableCell cell in table.Cells) { Console.WriteLine($" Cell ({cell.RowIndex}, {cell.ColumnIndex}): {cell.Content}"); } }
3. Analyze Receipt
Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync( WaitUntil.Completed, "prebuilt-receipt", receiptUri); AnalyzeResult result = operation.Value; foreach (AnalyzedDocument document in result.Documents) { if (document.Fields.TryGetValue("MerchantName", out DocumentField merchantField)) Console.WriteLine($"Merchant: {merchantField.ValueString}"); if (document.Fields.TryGetValue("Total", out DocumentField totalField)) Console.WriteLine($"Total: {totalField.ValueCurrency.Amount}"); if (document.Fields.TryGetValue("TransactionDate", out DocumentField dateField)) Console.WriteLine($"Date: {dateField.ValueDate}"); }
4. Build Custom Model
var adminClient = new DocumentIntelligenceAdministrationClient( new Uri(endpoint), new AzureKeyCredential(apiKey)); string modelId = "my-custom-model"; Uri blobContainerUri = new Uri("<blob-container-sas-url>"); var blobSource = new BlobContentSource(blobContainerUri); var options = new BuildDocumentModelOptions(modelId, DocumentBuildMode.Template, blobSource); Operation<DocumentModelDetails> operation = await adminClient.BuildDocumentModelAsync( WaitUntil.Completed, options); DocumentModelDetails model = operation.Value; Console.WriteLine($"Model ID: {model.ModelId}"); Console.WriteLine($"Created: {model.CreatedOn}"); foreach (var docType in model.DocumentTypes) { Console.WriteLine($"Document type: {docType.Key}"); foreach (var field in docType.Value.FieldSchema) { Console.WriteLine($" Field: {field.Key}, Confidence: {docType.Value.FieldConfidence[field.Key]}"); } }
5. Build Document Classifier
string classifierId = "my-classifier"; Uri blobContainerUri = new Uri("<blob-container-sas-url>"); var sourceA = new BlobContentSource(blobContainerUri) { Prefix = "TypeA/train" }; var sourceB = new BlobContentSource(blobContainerUri) { Prefix = "TypeB/train" }; var docTypes = new Dictionary<string, ClassifierDocumentTypeDetails>() { { "TypeA", new ClassifierDocumentTypeDetails(sourceA) }, { "TypeB", new ClassifierDocumentTypeDetails(sourceB) } }; var options = new BuildClassifierOptions(classifierId, docTypes); Operation<DocumentClassifierDetails> operation = await adminClient.BuildClassifierAsync( WaitUntil.Completed, options); DocumentClassifierDetails classifier = operation.Value; Console.WriteLine($"Classifier ID: {classifier.ClassifierId}");
6. Classify Document
string classifierId = "my-classifier"; Uri documentUri = new Uri("https://example.com/document.pdf"); var options = new ClassifyDocumentOptions(classifierId, documentUri); Operation<AnalyzeResult> operation = await client.ClassifyDocumentAsync( WaitUntil.Completed, options); AnalyzeResult result = operation.Value; foreach (AnalyzedDocument document in result.Documents) { Console.WriteLine($"Document type: {document.DocumentType}, confidence: {document.Confidence}"); }
7. Manage Models
// Get resource details DocumentIntelligenceResourceDetails resourceDetails = await adminClient.GetResourceDetailsAsync(); Console.WriteLine($"Custom models: {resourceDetails.CustomDocumentModels.Count}/{resourceDetails.CustomDocumentModels.Limit}"); // Get specific model DocumentModelDetails model = await adminClient.GetModelAsync("my-model-id"); Console.WriteLine($"Model: {model.ModelId}, Created: {model.CreatedOn}"); // List models await foreach (DocumentModelDetails modelItem in adminClient.GetModelsAsync()) { Console.WriteLine($"Model: {modelItem.ModelId}"); } // Delete model await adminClient.DeleteModelAsync("my-model-id");
Key Types Reference
| Type | Description |
|---|---|
| Main client for analysis |
| Model management |
| Result of document analysis |
| Single document within result |
| Extracted field with value and confidence |
| String, Date, Number, Currency, etc. |
| Page info (lines, words, selection marks) |
| Extracted table with cells |
| Custom model metadata |
| Training data source |
Build Modes
| Mode | Use Case |
|---|---|
| Fixed layout documents (forms) |
| Variable layout documents |
Best Practices
- Use DefaultAzureCredential for production
- Reuse client instances — clients are thread-safe
- Handle long-running operations — Use
for simplicityWaitUntil.Completed - Check field confidence — Always verify
propertyConfidence - Use appropriate model — Prebuilt for common docs, custom for specialized
- Use custom subdomain — Required for Entra ID authentication
Error Handling
using Azure; try { var operation = await client.AnalyzeDocumentAsync( WaitUntil.Completed, "prebuilt-invoice", documentUri); } catch (RequestFailedException ex) { Console.WriteLine($"Error: {ex.Status} - {ex.Message}"); }
Related SDKs
| SDK | Purpose | Install |
|---|---|---|
| Document analysis (this SDK) | |
| Legacy SDK (deprecated) | Use DocumentIntelligence instead |
Reference Links
| Resource | URL |
|---|---|
| NuGet Package | https://www.nuget.org/packages/Azure.AI.DocumentIntelligence |
| API Reference | https://learn.microsoft.com/dotnet/api/azure.ai.documentintelligence |
| GitHub Samples | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/documentintelligence/Azure.AI.DocumentIntelligence/samples |
| Document Intelligence Studio | https://documentintelligence.ai.azure.com/ |
| Prebuilt Models | https://aka.ms/azsdk/formrecognizer/models |
When to Use
This skill is applicable to execute the workflow or actions described in the overview.
🏰 Rei Skills — Curated by Rootcastle Engineering & Innovation | Batuhan Ayrıbaş
Engineering Beyond Boundaries | admin@rootcastle.com