Cordex Relationship Map Cordex Relationship Map
Cordex Relationship Map · AI setup guide

AI Setup Guide

Every AI provider Cordex Relationship Map supports, end to end: sign up with the provider, configure it in Studio, connect a key, and (for the in-tenant option) build the Power Automate flow. Includes the exact request and response the map sends to each provider, the flow trigger contracts, and the read-only query tool schema.

AI Setup v1.2Solution 4.5.99.0Providers: Claude, Azure OpenAI, In-tenant flowCordex AI needs Tier 03 - AI Enablement

Download PDF opens your browser's print dialog - choose "Save as PDF".

Start here: pick your path

New to this? Read this one section, pick a path, and follow only that path's steps. You do not need to understand the rest of the guide to get it working - the reference sections are there if you want them later.

First, two words you will see a lot

  • API key - a long secret password (like sk-ant-...) that lets the map talk to the AI service. You get it from the AI provider's website.
  • Studio - the map's admin screen. Open the Cordex Relationship Map app, then in the left menu choose Cordex Relationship Map Admin › Config. Scroll to the Cordex AI box. That is "Studio" everywhere below.

Which path should I choose?

If this is youDo this pathHow hard
"I just want it working, fastest route"Path A - Claude, with one shared org keyEasiest
"My company is all-in on Microsoft / Azure"Path B - Azure OpenAIMedium
"Our security policy blocks external AI, or the key must stay hidden from users"Path C - In-tenant flowAdvanced
"I want each person to use their own AI account, not a company one"Path A - Claude, then turn on Self-serve (leave the org key blank)Easy

The 5-minute version (Path A, recommended)

  1. Go to console.anthropic.com, make an account, and add a little credit in Billing.
  2. Open Settings › API Keys › Create Key. Copy the key (starts with sk-ant-). Keep it safe - it is shown once.
  3. In Studio: set Enable Cordex AI = On, Provider = Claude, paste the key in Org API key, press Save encrypted, then Save.
  4. Open any record, open the map, click the button, and ask a question.

Worked? You get an answer in the panel. If not, jump to Troubleshooting - the first row usually explains it. The full Path A steps (with the optional workspace and self-serve) are in section 4.

Before you begin, you need: administrator access to open Studio (to save settings and keys), and the map already added to a form (see the Admin Guide if it is not). Cordex AI also needs a Tier 03 license - if the ✨ button is missing, that is why.

1. How Cordex AI works

Cordex AI is the sparkle () panel on the map. It writes an account brief, answers questions about the record and the map, suggests a next best action, and (optionally) reads related tables to form a sentiment. It calls a provider only when a user asks; the white-space card is computed locally and never leaves the tenant.

You choose one of three providers. Claude and Azure OpenAI call the service directly from the user's browser. The in-tenant flow keeps the key server-side and proxies through your own Power Automate flow, for organisations whose policy blocks direct external AI calls.

ProviderWhere the key livesBest for
Claude (Anthropic)User browser or encrypted org rowFastest setup, strongest analysis, the data-dive tool
Azure OpenAIUser browser or encrypted org rowTeams standardised on the Microsoft / Copilot stack
In-tenant flowServer-side (Key Vault), never in the browserPolicy blocks direct external AI; key must stay hidden from users
License gate. Cordex AI is a Tier 03 feature. If the panel is missing or greyed, the environment's license is below Tier 03. Everything below assumes Tier 03 is active.

2. Where everything lives

All AI configuration is on one screen: open the app Cordex Relationship Map, go to Cordex Relationship Map Admin › Config (Studio), and scroll to the Cordex AI section. Only administrators can open Studio and read the key rows.

  • Studio › Cordex AI - provider, org key, model, workspace, full system access, sentiment, self-serve.
  • Studio › Actions - the Power Automate action flows behind the map's Flow button (separate from AI).
  • The map › ✨ panel › 🔑 (key) button - where an individual user pastes their own key.

After you Save in Studio, open maps pick the change up on their next refresh.

3. Key resolution order

For Claude and Azure OpenAI, the runtime resolves a usable key in this exact order, using the first it finds:

  1. The user's own encrypted key row (they pasted it via the 🔑 button and it was saved to the AI Keys table, scoped to them).
  2. The organisation's encrypted key row (you saved one shared key in Studio).
  3. A key the user pasted this session into the panel, held in that browser only (never written to Dataverse).

So you can run one shared org key for everyone, let every user bring their own, or mix the two (a user's own key always wins over the org key). The in-tenant flow ignores this order entirely - it holds the key server-side.

4. Claude (Anthropic) Direct

Step 1 - Sign up and add credit

  1. Go to console.anthropic.com and create an account (or sign in).
  2. Open Settings › Billing (or Plans & Billing) and add a payment method / purchase credits. A new API key cannot call the model until the account has credit or an active plan.

Step 2 - Create a dedicated workspace (recommended)

  1. Open Settings › Workspaces and create a workspace, for example CordexMap.
  2. Set a monthly spend limit on that workspace so map usage is capped and billed separately from your other work.
Why a workspace. A key scoped to a single workspace carries its own spend cap and needs no workspace ID in Studio. Avoid Anthropic's Default workspace - its ID is hidden in the Console, and an identity-linked, multi-workspace key is the only case where the map has to send an anthropic-workspace-id header.

Step 3 - Create the API key

  1. Open Settings › API Keys and choose Create Key.
  2. Scope it to the CordexMap workspace from Step 2, name it, and copy the key now (it is shown once). It looks like sk-ant-....

Step 4 - Configure in Studio

  1. Enable Cordex AI = On.
  2. Provider = Claude (Anthropic).
  3. Claude model - leave on Default to let the map pick the recommended model, or press Load available (after pasting/saving a key) to fetch the live model list from Anthropic and pick one, or choose Custom to type an exact model ID such as claude-sonnet-4-5.
  4. Claude workspace ID - leave blank for a single-workspace key. Fill it only if Anthropic replies "anthropic-workspace-id is required" (an identity-linked key).
  5. Org API key - to run one shared key for everyone, paste it and press Save encrypted. To let users bring their own instead, leave it blank (see Self-serve).
  6. Save.

Step 5 - Connect and test

Open a record's map, open the panel, and ask a question or press Brief. If you left the org key blank, each user first presses the 🔑 button, pastes their own sk-ant-... key, and presses Use key - it stays in their browser.

You will know it worked when the ✨ panel returns a written answer or a brief within a few seconds. A red message instead usually means the key has no credit, or (for a multi-workspace key) needs a workspace ID - see Troubleshooting.

What the map sends

A direct POST to https://api.anthropic.com/v1/messages with these headers and body (deterministic: temperature 0, so the same input gives the same reading):

POST https://api.anthropic.com/v1/messages
x-api-key: sk-ant-...
anthropic-version: 2023-06-01
anthropic-dangerous-direct-browser-access: true
anthropic-workspace-id: wrkspc_...        (only when configured)
content-type: application/json

{
  "model": "<configured model>",
  "max_tokens": 1200,
  "temperature": 0,
  "system": "<Cordex system prompt (+ data-dive rules when full access is on)>",
  "messages": [ ...last 8 turns, then the map snapshot + the question ],
  "tools": [ <query tool> ]          // only when Full system access is On
}

Return value. The answer is the joined content[] text blocks. When full system access is on, the model may reply with stop_reason: "tool_use"; the map runs the requested read-only query and loops (up to 8 rounds), then forces a prose answer.

5. Azure OpenAI Direct

Steps confirmed against Microsoft Learn. The Azure portal and Foundry UI move labels around from time to time; the three things you need out of it never change: an endpoint, a deployment name, and a key.

Step 1 - Create the Azure OpenAI resource

  1. Sign in to the Azure portal.
  2. Create a resource, search Azure OpenAI, choose Create.
  3. On Basics: pick a subscription, resource group, region and a name; pricing tier Standard.
  4. Configure network access, add any tags, then Review + submitCreateGo to resource.

Step 2 - Deploy a model

  1. Open Microsoft Foundry and select your resource.
  2. Go to Deployments+ Deploy modelDeploy base model.
  3. Choose a chat model (for example gpt-4o) and Confirm.
  4. Give the deployment a name (for example MyModel) and Deploy. Note this name - Azure calls use the deployment name, not the model name.

Step 3 - Get the endpoint and key

  1. Back in the Azure portal, open your resource › Keys and Endpoint (under Resource Management).
  2. Copy the Endpoint (for example https://myresource.openai.azure.com/) and Key 1.

Step 4 - Configure in Studio

  1. Enable Cordex AI = On, Provider = Azure OpenAI.
  2. Azure endpoint = the resource endpoint from Step 3.
  3. Azure deployment = the deployment name from Step 2 (for example MyModel).
  4. Azure API version = default 2024-10-21 (a current, stable value is 2024-11-20; use the version your deployment supports).
  5. Org API key = paste Key 1 and Save encrypted, or leave blank for self-serve.
  6. Save, then test from a map's ✨ panel.
You will know it worked when the ✨ panel answers. The most common beginner slip is putting the model name where the deployment name goes - Azure wants the deployment name you chose in Step 2, not gpt-4o.

What the map sends

POST https://<endpoint>/openai/deployments/<deployment>/chat/completions?api-version=<version>
api-key: <Azure key>
content-type: application/json

{
  "max_tokens": 1000,
  "temperature": 0,
  "messages": [ {"role":"system","content":"<Cordex system prompt>"}, ...turns ]
}

Return value. The answer is choices[0].message.content.

Note. The read-only data-dive tool is a Claude capability. On Azure OpenAI the map answers from the visible snapshot and grounding context only.

6. In-tenant flow Key-free

For organisations whose policy blocks direct external AI. The question and a small map snapshot POST to your Power Automate flow; the flow holds the provider key server-side (Key Vault) and returns the answer. No key ever reaches the browser.

Ready-made router. The Cordex AI Helper Flow is an importable child flow that already routes to Anthropic, OpenAI, Microsoft Foundry, xAI Grok, Google Gemini or a custom endpoint. Import it, then put the thin HTTP-triggered wrapper described below in front of it - the wrapper handles the browser path, the helper flow does the AI work.

Step 1 - Build the flow

  1. In Power Automate, create an instant cloud flow with the trigger When an HTTP request is received.
  2. Set the request body JSON schema to what the map sends (below). This trigger's URL is generated after you save.
  3. Add an HTTP action that calls your provider (Anthropic or Azure OpenAI), reading the API key from Azure Key Vault - never hard-code it in the flow.
  4. Add a Response action: status 200, and a header Access-Control-Allow-Origin: * (required, see the CORS note), returning the answer as JSON.
  5. Save, then copy the trigger's HTTP POST URL.

Step 2 - What the map POSTs to your flow

POST <your flow trigger URL>
Content-Type: text/plain;charset=UTF-8      // a CORS "simple" request on purpose

{
  "question": "who is the biggest stakeholder here?",
  "system":   "<Cordex system prompt>",
  "context":  { ...map snapshot: focal record, people, links... },
  "history":  [ ...last 8 turns... ],
  "user":     "<signed-in user's name>",
  "source":   "cordex-map v<version>"
}
CORS is mandatory. The body is sent as text/plain so the browser treats it as a simple request and does not send a preflight. Your Response action still must add Access-Control-Allow-Origin: * or the browser blocks the map from reading the reply, and the panel shows a network error even though the flow ran.

Step 3 - What your flow returns

Return status 200. The map reads the answer in this order: JSON answer, then JSON text, then the raw body as plain text. So either of these works:

// JSON (preferred)
{ "answer": "Jim Glynn is the strongest stakeholder - Champion, negative sentiment." }

// or plain text
Jim Glynn is the strongest stakeholder - Champion, negative sentiment.

Step 4 - Configure in Studio

  1. Enable Cordex AI = On, Provider = In-tenant flow.
  2. AI flow URL = the HTTP trigger URL from Step 1. It must start with https://. Only administrators can read this row.
  3. Save, then test from a map's ✨ panel.
You will know it worked when the ✨ panel returns the answer your flow produced. If the flow shows a successful run in Power Automate but the panel shows a network error, the Response action is missing the Access-Control-Allow-Origin: * header - that one header is the usual culprit.

7. Self-serve keys Claude / Azure

Instead of one org key, you can let approved users bring their own. This spreads cost across users' own provider accounts and keeps you out of key custody.

Admin

  1. Leave the Org API key blank.
  2. Self-serve credentials - leave Open to all, or switch to Restricted and add the specific users and teams allowed to add a key.

User

  1. Open the map's panel and press the 🔑 button.
  2. Paste the API key (Claude sk-ant-... or the Azure key) and press Use key.
  3. The key stays in that browser. If the button says self-serve is limited, ask an administrator to add you.

8. Grounding context

House terms, product names, sales stages, anything the model should always know. It is injected on every question automatically - the user never pastes it.

  1. Studio › Cordex AI › Grounding context.
  2. Press Generate starter, then edit the Global box (shared by every form) and, optionally, a per-form box.
  3. Applies - choose Global only, this form only, both (default), or off.

Each box holds up to about 4000 characters.

9. Full system access (data dive) Claude

Off by default, Cordex AI sees only the visible map snapshot. Turn on Allow full system access and it can run read-only Dataverse queries to answer questions about activities, pipeline, cases, owners and aggregates - executed as the signed-in user, so their own security roles are the ceiling and nothing is ever written.

  1. Studio › Cordex AI › Allow full system access = On.
Data egress widens. Each query's results are sent to the AI provider. Government and compliance customers should re-sign the AI checklist in the Admin Guide before enabling this. It is a Claude capability (the tool loop); Azure OpenAI and the in-tenant flow answer from the snapshot and grounding context.

The exact tool the model is given - its OData surface and limits - is in section 13.

10. Sentiment trend Claude

Cordex AI can read a record's related tables (cases, opportunities, leads, activities/emails) plus widely known public context to form a sentiment, and save it as a dated point so a trend builds over time (▲ improving / ▼ declining). The AI suggests; a person confirms it into the sentiment tag.

  1. Turn on Allow full system access first (section 9) - sentiment needs it.
  2. Add the Cordex Relationship Map Sentiment table and grant the Cordex security role Create/Read on it.
  3. Studio › Cordex AI › Sentiment trend = On.
  4. Optionally Assess automatically (first map open each day) or a Monthly refresh (admin approval; first run of the month).
Cost. Every assessment spends tokens and widens egress. Leave the automatic options off unless you want a continuously refreshed trend.

11. Action flows (the Flow button)

Separate from Cordex AI: the map's inspector Flow button runs on-demand Power Automate flows against the record. This is where "flow triggers" beyond the AI proxy come in.

Build and map a flow

  1. Build the flow with the When an HTTP request is received trigger.
  2. The map POSTs a small JSON body identifying the record (below).
  3. Studio › Actions › enable Allow workflows & flows.
  4. Under Power Automate flows, press Load flows from this environment to list activated cloud flows, pick one by name, and paste its HTTPS trigger URL.

What the map POSTs to an action flow

POST <action flow trigger URL>

{ "table": "account", "id": "<record GUID>", "name": "A. Datum Corporation", "user": "<signed-in user>" }
Two kinds of flow. A flow on the Dataverse When a row is selected trigger already runs from the form's own Flow menu - map one here only to also run it from inside the map. A flow on the When an HTTP request is received trigger is one you map here to run on demand.

12. Request / return reference

ProviderEndpointAuth headerAnswer field
Claudeapi.anthropic.com/v1/messagesx-api-keycontent[] text blocks
Azure OpenAI<endpoint>/openai/deployments/<deployment>/chat/completions?api-version=<v>api-keychoices[0].message.content
In-tenant flowyour HTTP trigger URLnone (server-side key)answer, then text, then raw body
Setting (Studio)DefaultNotes
Claude modelDefault (claude-sonnet-4-5)Default, Load available, or Custom exact ID
Claude workspace IDblankOnly for identity-linked, multi-workspace keys
Azure API version2024-10-21Use the version your deployment supports
max_tokensClaude 1200 / Azure 1000temperature 0 on both (deterministic)
Tool loop roundsup to 8Claude data dive only; final round forces prose
History carriedlast 8 turnsSnapshot rides on the newest question only

13. Read-only query tool schema Claude data dive

When full system access is on, Claude is given exactly one tool. It is a read-only Dataverse Web API GET, run in the browser as the signed-in user. Writes are impossible.

{
  "name": "query",
  "input_schema": {
    "type": "object",
    "properties": {
      "path": { "type": "string",
        "description": "OData path + query after /api/data/v9.2/ (or an @odata.nextLink to page)" }
    },
    "required": ["path"]
  }
}

Supported OData surface: $select, $top (page cap 25; more via the @odata.nextLink returned), $filter (eq ne gt ge lt le, and/or/not, grouping, contains/startswith/endswith, the in operator, null tests, lookup _x_value GUID filters, collection lambdas with any()), $expand (join a lookup's fields in one call), $orderby (plain queries only), and $apply aggregates (sum, average, min, max, $count, groupby).

Return value: the raw OData JSON, trimmed to about 7000 characters with the @odata.nextLink kept visible so paging still works. Errors come back as ERROR: ... so the model can adjust.

Known limits the model is told about: $skip is not supported; $orderby is not allowed on an $apply query (sort the result yourself); no countdistinct and no groupby on datetime; aggregates over 50,000 rows fail with 8004E023 (narrow the filter); GET URLs cap near 32KB; statecode 0 = active/open, 1 = inactive/closed.

14. Key storage & security

Saved keys (org and per-user) live in the Cordex Relationship Map AI Keys table (mitaa_cordexmapaikeys), encrypted AES-256-GCM with a per-row random salt and IV. Clear text never touches Dataverse, and rows are importable between environments.

  • Provider is stored as a choice: Claude = 286640000, Azure = 286640001.
  • Scope distinguishes an organisation key from a personal (self-serve) key.
Honest limit. Encryption protects keys at rest, in exports, and from casual browsing. Any licensed runtime that can use the key can ultimately derive it. If a key must stay secret from users, use the in-tenant flow provider, where the key never leaves the server.

15. Troubleshooting

SymptomCause / fix
✨ panel missing or greyedLicense is below Tier 03, or Enable Cordex AI is Off.
"anthropic-workspace-id is required"Identity-linked, multi-workspace key. Put the workspace ID in Studio (or the user's 🔑 override), or scope the key to a single workspace.
"Azure OpenAI endpoint and deployment are not configured"Fill both Azure endpoint and deployment in Studio. Remember: deployment name, not model name.
Flow answer never arrives / network error, but the flow ranThe flow's Response action is missing Access-Control-Allow-Origin: *. Add it.
Flow returns 401 / 403The trigger URL is wrong or expired, or the server-side provider key is invalid. Re-copy the trigger URL and check Key Vault access.
"I can only see this map right now"Full system access is Off. Turn on Allow full system access (Claude) to query live data.
Aggregate fails with 8004E023The filtered set exceeds 50,000 rows. Add a tighter filter inside the $apply.
Console shows "Result is not PredictAPI" or a Collector 401Platform / telemetry noise from the host form, not Cordex Relationship Map. Safe to ignore.