Skip to main content
Back

Document Intelligence for Akumina AI

Document Intelligence for Akumina AI
Configuring Azure AI Document Intelligence, directly and through Azure API Management
A step-by-step configuration, reasoning, and validation guide
Creating the resource, configuring Akumina AI, and optionally publishing the v4.0 API through a dedicated APIM gateway
Requires Akumina AI Build 7.0.2602.0316 or later

Introduction

Akumina AI uses Azure AI Document Intelligence (formerly Form Recognizer) to read the documents it indexes — extracting text, tables, key–value pairs, and structured fields from PDFs, images, and Office files so that their content can be chunked, embedded, and searched. Every Akumina AI deployment that indexes documents needs a Document Intelligence resource.

How Akumina AI reaches that resource is a deployment choice, and this guide covers both supported options:

   Direct (no gateway). Akumina AI calls the Document Intelligence endpoint and authenticates with the resource key. This is the default and the shortest path to a working configuration. Getting started with Document Intelligence covers it from resource creation to validation.
   Fronted by Azure API Management (APIM). Akumina AI calls an APIM gateway instead; the gateway holds the resource key and forwards each request to Document Intelligence. Choose this when policy requires outbound Azure AI traffic to pass through a managed gateway, when each consuming application needs its own revocable key, or when you want central logging, throttling, and quotas. Everything from Overview of the APIM configuration onwards covers it.

Both paths start the same way: create the Document Intelligence resource and copy its key and endpoint. A direct configuration stops there. An APIM configuration takes the same key and endpoint and places them in the gateway rather than in the client, so that the client only ever holds a gateway subscription key.

Scope. This guide covers the Document Intelligence v4.0 API (api-version=2024-11-30) and requires Akumina AI Build 7.0.2602.0316 or later. Document Intelligence is a separate Azure resource from Azure AI Foundry — a different host, a different API surface, and its own key — so it is created and configured on its own, and nothing in the Foundry configuration changes.

Getting started with Document Intelligence

Follow this section for every deployment, whether or not you intend to put a gateway in front of the service. It produces a working, directly connected configuration.

Create the Document Intelligence resource

In the Azure portal, choose Create a resource, search for Document Intelligence, and select Create. Supply the subscription, resource group, region, and a resource name, choose a pricing tier — F0 (free) is adequate for evaluation, S0 for production — and complete the wizard. Deployment takes a minute or two.

   The region determines the endpoint host and which API versions are available. The v4.0 API (2024-11-30) is not offered in every region, so confirm availability before you settle on one.
   The resource name becomes part of the endpoint: https://<docintel-resource>.cognitiveservices.azure.com
   The F0 tier is limited to 500 pages per month and caps a single request at 4 MB and 2 pages, which is enough to validate the configuration but not to index a live document library.

Copy the keys and endpoint

Open the resource and go to Keys and Endpoint. This blade holds the values that every other part of this guide refers to.

Value Where to find it Notes
Endpoint Keys and Endpoint › Endpoint Of the form https://<docintel-resource>.cognitiveservices.azure.com. Copy it with no trailing slash and no path — the client appends /documentintelligence itself.
KEY 1 / KEY 2 Keys and Endpoint › KEY 1 or KEY 2 Either key works. Two are issued so one can be rotated while the other stays in service. Treat both as secrets.
Location / Region Keys and Endpoint › Location Needed only by SDKs and tools that take a region separately; the endpoint already encodes it.
Keep the key out of shared documents and source control. Paste it straight into the Akumina AI settings or into your secret store. If a key is ever exposed, use Regenerate Key on this blade — regenerating KEY 1 does not affect KEY 2, so you can roll one at a time without an outage.

Configure the Embeddings section in Akumina AI settings

In the Akumina AI settings, go to Settings › AI Settings and open the EmbeddingConfiguration section. The two values you just copied go into the AzureDocumentIntelligence block inside it:

Setting Value to enter Notes
Enabled true Ships as false. Document Intelligence is not used until this is turned on.
Extensions e.g. png, jpeg, jpg, xlsx The file extensions routed through Document Intelligence. Add or remove entries to suit the content being indexed.
ApiKey KEY 1 or KEY 2 The resource key from Keys and Endpoint. In a direct configuration this is the only credential involved.
Endpoint The Endpoint from Keys and Endpoint Of the form https://<docintel-resource>.cognitiveservices.azure.com, with no trailing slash and no path.
AdditionalHeaders Omit for a direct connection Required only when the Document Intelligence request is fronted by APIM — see Client configuration. For a direct connection ApiKey and Endpoint are all that is needed.

A direct — non-APIM — Document Intelligence configuration therefore looks like this:

"EmbeddingConfiguration": {
    "TextEmbeddingType": "AzureOpenAI",
    "AudioEmbeddingType": "AzureOpenAIWhisper",
    "AzureDocumentIntelligence": {
        "Enabled": true,
        "Extensions": [ "png", "jpeg", "jpg", "xlsx" ],
        "ApiKey": "<KEY 1 or KEY 2 from Keys and Endpoint>",
        "Endpoint": "https://<docintel-resource>.cognitiveservices.azure.com"
    },
    "ChunkSize": {
        "ParagraphsPerPage": 10,
        "LinesPerPage": 40,
        "TokensPerPage": 0
    }
}

Save the settings. Note that AdditionalHeaders is absent here: the resource key is the credential and the client sends it itself. That block exists for the gateway case, where a second credential — the APIM subscription key — has to travel alongside every request under a header name the gateway chooses.

Validate the direct connection

Before pointing Akumina AI at the resource, confirm that the endpoint and key work together. Analysis is a long-running operation, so validation is two calls: submit a document, then poll for the result. The examples use Windows cmd.exe continuation (^) and escaped double quotes; on bash use \ and single quotes instead.

curl -i -X POST "https://<docintel-resource>.cognitiveservices.azure.com/documentintelligence/documentModels/prebuilt-layout:analyze?api-version=2024-11-30" ^
  -H "Ocp-Apim-Subscription-Key: YOUR-DOCUMENT-INTELLIGENCE-KEY" ^
  -H "Content-Type: application/json" ^
  -d "{\"urlSource\":\"https://YOUR-HOST/sample.pdf\"}"
Pass: 202 Accepted, an empty body, a Retry-After header, and an Operation-Location header pointing at your resource host. -i is what makes the test meaningful — the body is empty, so the headers are the entire result. A 401 means the key is wrong or was sent under the wrong header name: the resource reads its key from Ocp-Apim-Subscription-Key. A 404 usually means the endpoint was pasted with a trailing slash or an extra path segment.

Then GET the Operation-Location value returned by the POST, with the same key:

curl "https://<docintel-resource>.cognitiveservices.azure.com/documentintelligence/documentModels/prebuilt-layout/analyzeResults/RESULT-ID?api-version=2024-11-30" ^
  -H "Ocp-Apim-Subscription-Key: YOUR-DOCUMENT-INTELLIGENCE-KEY"
Pass: the first calls return "status": "running"; within a few seconds the payload reports "status": "succeeded" and carries an analyzeResult object with content, pages, and — for prebuilt-layout — tables. Results are retained by the service for 24 hours.
Next. With those two calls passing and the endpoint and key saved in the Embeddings section, a direct configuration is complete and nothing further is required. If you want to front the Document Intelligence service through APIM — so that clients hold a revocable gateway key instead of the resource key — continue with Overview of the APIM configuration. The remainder of this guide covers that gateway.

Overview of the APIM configuration

Azure AI Document Intelligence (formerly Form Recognizer) extracts text, tables, key–value pairs, and structured fields from documents. This guide publishes it through Azure API Management (APIM) so that client applications call it through a managed gateway and never hold the resource key.

Document Intelligence is a separate Azure resource from Foundry — a different host, a different API surface, and its own key — so it is configured as its own APIM API. Nothing in the Foundry APIM guide changes.

The configuration is deliberately thin. Both operations use a wildcard frontend path, so the request path and query string pass through to the resource unchanged and all of the work is done by two API-level policies: the inbound policy attaches the resource key, and the outbound policy repoints the Operation-Location header at the gateway. There are no operation-level policies and no path rewriting.

How a request flows

   Stage 1 – Operation matching (frontend). APIM matches the incoming URL against gateway host + API URL suffix + operation URL template. If nothing matches, APIM returns 404 before any policy runs, so a policy can never rescue an unmatched path.
   Stage 2 – Backend forwarding (policy). Once an operation matches, the API-level inbound policy runs and the request is forwarded to the Document Intelligence endpoint.

Analysis is a long-running operation, which is why two operations are needed. The client POSTs a document and the service replies 202 Accepted with an empty body and an Operation-Location header; the client then GETs that URL until the payload reports "status": "succeeded". Results are retained by the service for 24 hours.

Prerequisites

   An Azure API Management instance (any tier).
   An Azure AI Document Intelligence resource, and its endpoint and keys from the Keys and Endpoint blade — see Getting started with Document Intelligence.
   Permission to create APIs, named values, and subscriptions in the APIM instance.
   A sample document reachable over HTTPS, or a local PDF or image, for the checks in Validate with curl.

Configuring APIM

Store the Document Intelligence key as a named value

In the APIM instance, go to Named values+ Add and create a value named docintel-key of type Secret (or Key vault), using KEY 1 or KEY 2 from the resource’s Keys and Endpoint blade.

Why. Policies reference it as {{docintel-key}}, so the key never appears in the policy document, which is readable by anyone with contributor access and is often exported to source control. Rotation is a single edit in one place. A Key Vault–backed value goes further: rotation happens in the vault and APIM refreshes automatically.

Add the API

Go to APIs+ Add APIHTTP — the blank, manually defined option, not Azure AI Foundry or OpenAPI — select Full to reveal every field, and set:

Setting Example value Notes
Display name Document Intelligence Free text; shown in the portal.
Name document-intelligence The API’s resource name.
Web service URL https://<docintel-resource>.cognitiveservices.azure.com The endpoint from Keys and Endpoint, with no trailing path or slash. This is the backend — no separate backend entity is needed.
URL scheme HTTPS Never expose the gateway over plain HTTP; the subscription key travels in a header.
API URL suffix mydocintel The path segment that routes to this API. Clients build their base URL as gateway host + suffix.
Subscription required Checked Gives every consuming application its own revocable key.
Subscription header name api-key On the Settings tab after creation. Either name works — see the note under API-level inbound policy.

The resulting client base URL is https://<apim-host>.azure-api.net/mydocintel.

Add the two operations

On the Design tab, add two operations with + Add operation. Both use the same wildcard frontend template, and neither needs an operation-level inbound or outbound policy:

Display name Method URL template
Analyze document POST /documentintelligence/*
Get analyze result GET /documentintelligence/*

Why a wildcard. The * matches the whole remaining path, so one POST operation covers every analyze route for every model and one GET operation covers every result route. The path and the query string reach the resource exactly as the client sent them, which means:

   No rewrite-uri and no template parameters to maintain.
   The service’s own route forms work as-is, including the colon in documentModels/{modelId}:analyze.
   The api-version, and optional parameters such as pages, features, and outputContentFormat, are part of the client’s URL and pass straight through — the gateway does not supply or alter them.
   New models, prebuilt or custom, and new routes need no change in APIM.

Because both operations share one template, the method is what distinguishes them — which is exactly the split the analyze-and-poll cycle needs.

API-level inbound policy

Open All operationsInbound processing › policy code editor and set:

<inbound>
    <base />
    <set-header name="Ocp-Apim-Subscription-Key" exists-action="override">
        <value>{{docintel-key}}</value>
    </set-header>
</inbound>

Why. Document Intelligence reads its key from Ocp-Apim-Subscription-Key. This is the only change the request needs: the API’s web service URL already points at the resource and the wildcard leaves the path alone.

exists-action="override" matters. Ocp-Apim-Subscription-Key is also APIM’s own default subscription header name, so if you left the API’s subscription header at the default, the client’s APIM key arrives in the very header the backend reads. The override replaces it unconditionally, so a client can never influence what the resource receives — with either header name.

API-level outbound policy

In Outbound processing on the same All operations scope, set:

<outbound>
    <base />
    <choose>
        <when condition="@(context.Response.Headers.ContainsKey(&quot;Operation-Location&quot;))">
            <set-header name="Operation-Location" exists-action="override">
                <value>@(context.Response.Headers.GetValueOrDefault(&quot;Operation-Location&quot;,&quot;&quot;)
                    .Replace(&quot;https://YOUR-DOCINTEL-RESOURCE.cognitiveservices.azure.com&quot;,
                             &quot;https://YOUR-APIM-HOST.azure-api.net/mydocintel&quot;))</value>
            </set-header>
        </when>
    </choose>
</outbound>

Replace the first string with your Document Intelligence endpoint and the second with your gateway base URL — the host plus the API URL suffix from Add the API. Neither may have a trailing slash, and both must include the scheme; Replace is a literal, case-sensitive match, so a mismatch silently leaves the header untouched.

Why. The 202 response carries Operation-Location built from the resource’s own hostname. A client that follows it verbatim leaves the gateway, reaches the resource directly, and is rejected with 401 — it holds an APIM subscription key, not the resource key. Swapping the host in the header keeps the whole analyze-and-poll cycle inside the gateway.

The choose guard means responses without the header — the poll responses, and any error returned by the service — pass through untouched. Note also that the expression uses Replace rather than a comparison: a policy document is XML, so a bare < inside an expression makes the policy fail to save.

Validate with curl

Validate the gateway before pointing an application at it. The examples use Windows cmd.exe continuation (^) and escaped double quotes; on bash use \ and single quotes instead. The placeholders deliberately avoid angle brackets — < and > are redirection operators in cmd.exe.

POST — submit a document

curl -i -X POST "https://YOUR-APIM-HOST.azure-api.net/mydocintel/documentintelligence/documentModels/prebuilt-layout:analyze?api-version=2024-11-30" ^
  -H "api-key: YOUR-APIM-SUBSCRIPTION-KEY" ^
  -H "Content-Type: application/json" ^
  -d "{\"urlSource\":\"https://YOUR-HOST/sample.pdf\"}"
Pass: 202 Accepted, an empty body, a Retry-After header, and an Operation-Location header that carries your gateway host and API URL suffix — not cognitiveservices.azure.com. If it still shows the resource host, the two strings in the outbound Replace do not match your values exactly.

-i is what makes this test meaningful: the response body is empty, so the headers are the entire result. Swap prebuilt-layout for prebuilt-read, prebuilt-invoice, or a custom model id to confirm the wildcard covers them all.

To send bytes from disk instead of a URL, post the file with its own content type:

curl -i -X POST "https://YOUR-APIM-HOST.azure-api.net/mydocintel/documentintelligence/documentModels/prebuilt-read:analyze?api-version=2024-11-30" ^
  -H "api-key: YOUR-APIM-SUBSCRIPTION-KEY" ^
  -H "Content-Type: application/pdf" ^
  --data-binary "@sample.pdf"
Use --data-binary, never -d: -d strips newlines and corrupts binary content, which surfaces as a confusing 400 from the service. Document Intelligence limits a request to 4 MB and 2 pages on the free (F0) tier, and to 500 MB and 2,000 pages on the standard (S0) tier; prefer urlSource for large documents.

GET — poll for the result

Call the Operation-Location value returned by the POST, with the same subscription key:

curl "https://YOUR-APIM-HOST.azure-api.net/mydocintel/documentintelligence/documentModels/prebuilt-layout/analyzeResults/RESULT-ID?api-version=2024-11-30" ^
  -H "api-key: YOUR-APIM-SUBSCRIPTION-KEY"
Pass: the first calls return "status": "running"; within a few seconds the payload reports "status": "succeeded" and carries an analyzeResult object with content, pages, and — for prebuilt-layout — tables. Honour the Retry-After header rather than polling in a tight loop.

Two passing calls confirm the whole chain: the operations match, the subscription key is accepted, the resource key is injected, the wildcard forwards the path and query string intact, and the outbound rewrite keeps the client on the gateway.

Client configuration

Point the client at the gateway rather than at the resource. Three things must be correct:

   The endpoint is the gateway base URL — https://<apim-host>.azure-api.net/mydocintel — with no trailing slash and without the /documentintelligence segment, which the client appends itself.
   The credential is the APIM subscription key, not the Document Intelligence key. The resource key stays in the named value and is never distributed.
   The header name is the Subscription header name on the API’s Settings tab (api-key here). This is what most often goes wrong, because SDKs default to sending their credential as Authorization: Bearer, which APIM does not read.

In the Akumina AI settings (Settings › AI Settings), the AzureDocumentIntelligence block configured under Configure the Embeddings section in Akumina AI settings changes in two ways: Endpoint becomes the gateway base URL, and an AdditionalHeaders entry carries the APIM subscription key under the header name the API expects — the same mechanism the Foundry endpoint uses:

"AzureDocumentIntelligence": {
    "Enabled": true,
    "Extensions": [ "png", "jpeg", "jpg", "xlsx" ],
    "ApiKey": "<APIM_SUBSCRIPTION_KEY — not the resource key>",
    "Endpoint": "https://<apim-host>.azure-api.net/mydocintel",
    "AdditionalHeaders": {
        "api-key": "<APIM_SUBSCRIPTION_KEY>"
    }
}

Include AdditionalHeaders only when the endpoint is fronted by a gateway; a direct connection needs ApiKey and Endpoint alone. The header name must match the Subscription header name on the API’s Settings tab. ApiKey should no longer carry the Document Intelligence resource key — that key now lives only in the gateway’s named value, and whatever the client sends in that header is overridden by the inbound policy. Because the wildcard passes the service’s own route forms through unchanged, a client written against the official Document Intelligence SDK works against this gateway with only its endpoint and credential changed.

Troubleshooting

Enable the APIM trace first — the Test blade does this automatically — and replay the request. It shows whether an operation matched and prints the exact outbound URL sent to the resource, which resolves most of these in one look.

Symptom Root cause Fix
404 from the gateway The URL did not match either operation. Matching happens in Stage 1, before any policy runs. Check the API URL suffix, that the path continues with /documentintelligence/, and that the method is one of the two you defined.
401 – Access denied due to missing subscription key The key is not in the header APIM reads — commonly sent as Authorization: Bearer. Send it in the header named on the API’s Settings tab. Confirm the client is not also setting Authorization.
401 or 403 with a Document Intelligence error body The resource key was not injected, or the named value holds a stale or wrong key. Confirm in the trace that Ocp-Apim-Subscription-Key is on the outbound request and that {{docintel-key}} resolved. Keep exists-action="override". If a client sends Authorization: Bearer, add <set-header name="Authorization" exists-action="delete" /> to the inbound policy.
400 – the api-version query parameter is required Nothing pins an api-version, so the client must supply one. Add ?api-version=2024-11-30 to the client URL.
202 is returned, then the client’s poll 401s against cognitiveservices.azure.com The two strings in the outbound Replace do not match, so the header passed through unchanged. Copy the endpoint from Keys and Endpoint exactly, include https://, drop any trailing slash, and make sure the replacement includes the API URL suffix.
400 from the service on a file upload that opens fine locally The body was sent with -d, which strips newlines and corrupts binary content. Use --data-binary "@file.pdf" with the file’s own Content-Type, or send urlSource instead.
500 from the gateway, ExpressionValueEvaluationFailure A policy expression read a body or header that is not present — typically OpenAI token policies copied from a Foundry API. Remove OpenAI-specific policies from this API. Guard header reads with ContainsKey and GetValueOrDefault, as the outbound policy above does.

Security notes

   Treat the APIM subscription key and the Document Intelligence key as separate secrets with separate lifecycles. Clients only ever hold the APIM key, so revoking one application never requires rotating the resource key. Do not paste either into shared documents, tickets, or chat transcripts, and rotate any key that has been exposed.
   Prefer a Key Vault–backed named value for docintel-key over a plain secret: rotation happens in the vault, APIM refreshes automatically, and access is audited. To remove the key entirely, enable the APIM system-assigned managed identity, grant it the Cognitive Services User role on the resource, and replace the set-header with <authentication-managed-identity resource="https://cognitiveservices.azure.com" /> — this requires a custom subdomain on the resource.
   Keep Subscription required enabled and issue one subscription per consuming application, so usage is attributable and a single application can be revoked in isolation. Document Intelligence bills per page, so consider a rate-limit-by-key on the subscription to contain cost.
   Because the wildcard forwards whatever path the client sends, every route on the resource is reachable through the gateway. If clients are not fully trusted, narrow the operations to the specific routes you support, and be deliberate about urlSource — the service fetches whatever URL the client supplies.
Privacy. Documents routinely contain personal data. If you enable APIM diagnostics or Application Insights on this API, disable request and response body logging, or mask it — the default body capture would otherwise write document content into your logs.
^ Top