.github/plugins/azure-sdk-java/skills/azure-ai-formrecognizer-java/SKILL.md
Build document analysis applications with Azure Document Intelligence (Form Recognizer) SDK for Java. Use when extracting text, tables, key-value pairs from documents, receipts, invoices, or building custom document models.
npx skillsauth add microsoft/skills azure-ai-formrecognizer-javaInstall 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.
Build document analysis applications using the Azure AI Document Intelligence SDK for Java.
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-ai-formrecognizer</artifactId>
<version>4.2.0-beta.1</version>
</dependency>
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;
import com.azure.core.credential.AzureKeyCredential;
DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
.credential(new AzureKeyCredential("{key}"))
.endpoint("{endpoint}")
.buildClient();
import com.azure.ai.formrecognizer.documentanalysis.administration.DocumentModelAdministrationClient;
import com.azure.ai.formrecognizer.documentanalysis.administration.DocumentModelAdministrationClientBuilder;
DocumentModelAdministrationClient adminClient = new DocumentModelAdministrationClientBuilder()
.credential(new AzureKeyCredential("{key}"))
.endpoint("{endpoint}")
.buildClient();
import com.azure.identity.DefaultAzureCredentialBuilder;
DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
.endpoint("{endpoint}")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
| Model ID | Purpose |
|----------|---------|
| prebuilt-layout | Extract text, tables, selection marks |
| prebuilt-document | General document with key-value pairs |
| prebuilt-receipt | Receipt data extraction |
| prebuilt-invoice | Invoice field extraction |
| prebuilt-businessCard | Business card parsing |
| prebuilt-idDocument | ID document (passport, license) |
| prebuilt-tax.us.w2 | US W2 tax forms |
import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.core.util.BinaryData;
import com.azure.core.util.polling.SyncPoller;
import java.io.File;
File document = new File("document.pdf");
BinaryData documentData = BinaryData.fromFile(document.toPath());
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocument("prebuilt-layout", documentData);
AnalyzeResult result = poller.getFinalResult();
// Process pages
for (DocumentPage page : result.getPages()) {
System.out.printf("Page %d: %.2f x %.2f %s%n",
page.getPageNumber(),
page.getWidth(),
page.getHeight(),
page.getUnit());
// Lines
for (DocumentLine line : page.getLines()) {
System.out.println("Line: " + line.getContent());
}
// Selection marks (checkboxes)
for (DocumentSelectionMark mark : page.getSelectionMarks()) {
System.out.printf("Checkbox: %s (confidence: %.2f)%n",
mark.getSelectionMarkState(),
mark.getConfidence());
}
}
// Tables
for (DocumentTable table : result.getTables()) {
System.out.printf("Table: %d rows x %d columns%n",
table.getRowCount(),
table.getColumnCount());
for (DocumentTableCell cell : table.getCells()) {
System.out.printf("Cell[%d,%d]: %s%n",
cell.getRowIndex(),
cell.getColumnIndex(),
cell.getContent());
}
}
String documentUrl = "https://example.com/invoice.pdf";
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("prebuilt-invoice", documentUrl);
AnalyzeResult result = poller.getFinalResult();
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("prebuilt-receipt", receiptUrl);
AnalyzeResult result = poller.getFinalResult();
for (AnalyzedDocument doc : result.getDocuments()) {
Map<String, DocumentField> fields = doc.getFields();
DocumentField merchantName = fields.get("MerchantName");
if (merchantName != null && merchantName.getType() == DocumentFieldType.STRING) {
System.out.printf("Merchant: %s (confidence: %.2f)%n",
merchantName.getValueAsString(),
merchantName.getConfidence());
}
DocumentField transactionDate = fields.get("TransactionDate");
if (transactionDate != null && transactionDate.getType() == DocumentFieldType.DATE) {
System.out.printf("Date: %s%n", transactionDate.getValueAsDate());
}
DocumentField items = fields.get("Items");
if (items != null && items.getType() == DocumentFieldType.LIST) {
for (DocumentField item : items.getValueAsList()) {
Map<String, DocumentField> itemFields = item.getValueAsMap();
System.out.printf("Item: %s, Price: %.2f%n",
itemFields.get("Name").getValueAsString(),
itemFields.get("Price").getValueAsDouble());
}
}
}
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("prebuilt-document", documentUrl);
AnalyzeResult result = poller.getFinalResult();
// Key-value pairs
for (DocumentKeyValuePair kvp : result.getKeyValuePairs()) {
System.out.printf("Key: %s => Value: %s%n",
kvp.getKey().getContent(),
kvp.getValue() != null ? kvp.getValue().getContent() : "null");
}
import com.azure.ai.formrecognizer.documentanalysis.administration.models.*;
String blobContainerUrl = "{SAS_URL_of_training_data}";
String prefix = "training-docs/";
SyncPoller<OperationResult, DocumentModelDetails> poller = adminClient.beginBuildDocumentModel(
blobContainerUrl,
DocumentModelBuildMode.TEMPLATE,
prefix,
new BuildDocumentModelOptions()
.setModelId("my-custom-model")
.setDescription("Custom invoice model"),
Context.NONE);
DocumentModelDetails model = poller.getFinalResult();
System.out.println("Model ID: " + model.getModelId());
System.out.println("Created: " + model.getCreatedOn());
model.getDocumentTypes().forEach((docType, details) -> {
System.out.println("Document type: " + docType);
details.getFieldSchema().forEach((field, schema) -> {
System.out.printf(" Field: %s (%s)%n", field, schema.getType());
});
});
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("my-custom-model", documentUrl);
AnalyzeResult result = poller.getFinalResult();
for (AnalyzedDocument doc : result.getDocuments()) {
System.out.printf("Document type: %s (confidence: %.2f)%n",
doc.getDocType(),
doc.getConfidence());
doc.getFields().forEach((name, field) -> {
System.out.printf("Field '%s': %s (confidence: %.2f)%n",
name,
field.getContent(),
field.getConfidence());
});
}
List<String> modelIds = Arrays.asList("model-1", "model-2", "model-3");
SyncPoller<OperationResult, DocumentModelDetails> poller =
adminClient.beginComposeDocumentModel(
modelIds,
new ComposeDocumentModelOptions()
.setModelId("composed-model")
.setDescription("Composed from multiple models"));
DocumentModelDetails composedModel = poller.getFinalResult();
// List models
PagedIterable<DocumentModelSummary> models = adminClient.listDocumentModels();
for (DocumentModelSummary summary : models) {
System.out.printf("Model: %s, Created: %s%n",
summary.getModelId(),
summary.getCreatedOn());
}
// Get model details
DocumentModelDetails model = adminClient.getDocumentModel("model-id");
// Delete model
adminClient.deleteDocumentModel("model-id");
// Check resource limits
ResourceDetails resources = adminClient.getResourceDetails();
System.out.printf("Models: %d / %d%n",
resources.getCustomDocumentModelCount(),
resources.getCustomDocumentModelLimit());
Map<String, ClassifierDocumentTypeDetails> docTypes = new HashMap<>();
docTypes.put("invoice", new ClassifierDocumentTypeDetails()
.setAzureBlobSource(new AzureBlobContentSource(containerUrl).setPrefix("invoices/")));
docTypes.put("receipt", new ClassifierDocumentTypeDetails()
.setAzureBlobSource(new AzureBlobContentSource(containerUrl).setPrefix("receipts/")));
SyncPoller<OperationResult, DocumentClassifierDetails> poller =
adminClient.beginBuildDocumentClassifier(docTypes,
new BuildDocumentClassifierOptions().setClassifierId("my-classifier"));
DocumentClassifierDetails classifier = poller.getFinalResult();
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginClassifyDocumentFromUrl("my-classifier", documentUrl, Context.NONE);
AnalyzeResult result = poller.getFinalResult();
for (AnalyzedDocument doc : result.getDocuments()) {
System.out.printf("Classified as: %s (confidence: %.2f)%n",
doc.getDocType(),
doc.getConfidence());
}
import com.azure.core.exception.HttpResponseException;
try {
client.beginAnalyzeDocumentFromUrl("prebuilt-receipt", "invalid-url");
} catch (HttpResponseException e) {
System.out.println("Status: " + e.getResponse().getStatusCode());
System.out.println("Error: " + e.getMessage());
}
FORM_RECOGNIZER_ENDPOINT=https://<resource>.cognitiveservices.azure.com/
FORM_RECOGNIZER_KEY=<your-api-key>
tools
KQL language expertise for writing correct, efficient Kusto Query Language queries. Covers syntax gotchas, join patterns, dynamic types, datetime pitfalls, regex patterns, serialization, memory management, result-size discipline, and advanced functions (geo, vector, graph). USE THIS SKILL whenever writing, debugging, or reviewing KQL queries — even simple ones — because the gotchas section prevents the most common errors that waste tool calls and cause expensive retry cascades. Trigger on: KQL, Kusto, ADX, Azure Data Explorer, Fabric Real-Time Intelligence, EventHouse, Log Analytics, log analysis, data exploration, time series, anomaly detection, summarize, where clause, join, extend, project, let statement, parse operator, extract function, any mention of pipe-forward query syntax.
development
Deploy, evaluate, and manage Foundry agents end-to-end: Docker build, ACR push, hosted/prompt agent create, container start, batch eval, prompt optimization, prompt optimizer workflows, agent.yaml, dataset curation from traces. USE FOR: deploy agent to Foundry, hosted agent, create agent, invoke agent, evaluate agent, run batch eval, optimize prompt, improve prompt, prompt optimization, prompt optimizer, improve agent instructions, optimize agent instructions, optimize system prompt, deploy model, Foundry project, RBAC, role assignment, permissions, quota, capacity, region, troubleshoot agent, deployment failure, create dataset from traces, dataset versioning, eval trending, create AI Services, Cognitive Services, create Foundry resource, provision resource, knowledge index, agent monitoring, customize deployment, onboard, availability. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure-prepare).
testing
Pre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure (Bicep or Terraform), RBAC role assignments, managed identity permissions, and prerequisites before deploying. WHEN: validate my app, check deployment readiness, run preflight checks, verify configuration, check if ready to deploy, validate azure.yaml, validate Bicep, test before deploying, troubleshoot deployment errors, validate Azure Functions, validate function app, validate serverless deployment, verify RBAC roles, check role assignments, review managed identity permissions, what-if analysis, validate Container Apps deployment.
testing
Check/manage Azure quotas and usage across providers. For deployment planning, capacity validation, region selection. WHEN: "check quotas", "service limits", "current usage", "request quota increase", "quota exceeded", "validate capacity", "regional availability", "provisioning limits", "vCPU limit", "how many vCPUs available in my subscription".