Skip to main content

Migrate from Azure Entity Linking to resolve()

Azure AI Language retires Entity Linking on 1 September 2028 (Microsoft notice). This guide moves an Azure Entity Linking call to resolve() in under an hour: one endpoint, one header, and a field map. The main difference is the identifier: Azure returns a Wikipedia page, resolve() returns a Wikidata ID, or unresolved with a reason.

What changes​

Azure Entity Linkingresolve()
IdentifierWikipedia title and URL (id, url)Wikidata QID (entity.id), plus same_as links to Wikidata and DBpedia
When unsureReturns a link with a low confidenceScore, or nothingReturns status: "unresolved" with one of four reasons
Your own entitiesNot supportedYour WordLift graph, or up to 5,000 entities sent with the request
MentionsDetected by the serviceDetected by the service, or your own spans
BatchingSeveral documents per requestOne text per request, up to 100,000 characters
LanguagesEnglish and Spanish only (Azure language support)English, Italian, French, German, Spanish, Portuguese; Japanese and Chinese at a lower level

1. Get a key​

Request a free key at wordlift.io/resolve: 1,000 requests a month for individual developers, delivered immediately. A call costs one request plus one per 1,000 characters (Requests and limits). Read your accountId once:

curl -s https://api.wordlift.io/accounts/me -H "Authorization: Key $WL_KEY"

2. Change the call​

Before, Azure Entity Linking:

curl -X POST "$LANGUAGE_ENDPOINT/language/:analyze-text?api-version=2022-05-01" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $LANGUAGE_KEY" \
-d '{"kind":"EntityLinking","parameters":{"modelVersion":"latest"},
"analysisInput":{"documents":[{"id":"1","language":"en",
"text":"Microsoft was founded by Bill Gates and Paul Allen."}]}}'

After, resolve():

curl -X POST "https://api.wordlift.io/accounts/$WL_ACCOUNT_ID/resolve" \
-H "Content-Type: application/json" \
-H "Authorization: Key $WL_KEY" \
-d '{"language":"en",
"text":"Microsoft was founded by Bill Gates and Paul Allen."}'

The same in Python:

import os, requests

def link(text, language="en"):
r = requests.post(
f"https://api.wordlift.io/accounts/{os.environ['WL_ACCOUNT_ID']}/resolve",
headers={"Authorization": f"Key {os.environ['WL_KEY']}"},
json={"text": text, "language": language},
timeout=30,
)
r.raise_for_status()
return r.json()["mentions"]

for m in link("Microsoft was founded by Bill Gates and Paul Allen."):
if m["status"] == "resolved":
print(m["text"], m["entity"]["id"], m["entity"]["label"])
else:
print(m["text"], "unresolved:", m.get("reason"))

3. Map the response​

Azure fieldresolve() fieldNote
results.documents[].entities[]mentions[]resolve() returns one entry per mention, not per entity
entities[].matches[].textmentions[].text
matches[].offsetmentions[].startCharacter position in text; when comparing, call Azure with stringIndexType UnicodeCodePoint
matches[].offset + lengthmentions[].end
entities[].namementions[].entity.label
entities[].id, entities[].url (Wikipedia)mentions[].entity.id (Wikidata QID)No Wikipedia URL is returned; Wikidata and DBpedia links are in entity.same_as
matches[].confidenceScorementions[].scoreRelevance, not a calibrated probability; compare only within the same signals.path
entities[].dataSourcedataset_uriwikidata://public by default
bingIdnone
(no equivalent)status, reasonunresolved with no_candidates, no_suitable_candidate, type_conflict or low_relevance
parameters.modelVersionnoneThe engine is versioned on our side

4. Convert the IDs you already stored​

If your database holds Azure's Wikipedia URLs, convert them once with the Wikidata API. One call takes up to 50 titles:

import requests

def wikipedia_to_qid(titles, lang="en"):
r = requests.get("https://www.wikidata.org/w/api.php", params={
"action": "wbgetentities", "sites": f"{lang}wiki",
"titles": "|".join(titles), "props": "sitelinks",
"sitefilter": f"{lang}wiki", "redirects": "yes", "format": "json",
}, headers={"User-Agent": "your-app/1.0 (you@example.com)"}, timeout=30)
out = {}
for qid, e in r.json().get("entities", {}).items():
if qid.startswith("Q"):
out[e["sitelinks"][f"{lang}wiki"]["title"]] = qid
return out

print(wikipedia_to_qid(["Microsoft", "Bill Gates"])) # {'Microsoft': 'Q2283', 'Bill Gates': 'Q5284'}

5. Decide what "unresolved" does in your code​

Azure rarely says no. resolve() does, and the reason tells you what to do next:

ReasonMeaningTypical handling
no_candidatesNothing in the dataset has that nameFlag as possibly new; do not create a record automatically
no_suitable_candidateCandidates exist, none fits the contextSend to review, or pass the type with the mention
type_conflictThe best candidate has the wrong typeCheck the mention type you sent
low_relevanceThe evidence is too weakLeave unlinked

If many of your entities are missing from Wikidata, resolve against your own graph first: add "dataset_uri": "wordlift://dataset/me,wikidata://public", or send your own list with "dataset_uri": "inline" and "dataset" (up to 5,000 entities). See Three worlds to resolve against.

6. Run both side by side before you switch​

Run a sample of your own texts through both services and compare the answers mention by mention before you switch. Azure answers English and Spanish only.

The open comparison harness scores both services on the same gold mentions with one rule, on our six development sets or on your own:

git clone https://github.com/wordlift/content-analysis && cd content-analysis && make setup
export WL_KEY=... AZURE_LANGUAGE_ENDPOINT=... AZURE_LANGUAGE_KEY=...
.venv/bin/python tools/compare.py --datasets datasets --systems resolve,azure --out results

Errors​

Every error is an RFC 9457 Problem Details document with a stable code; the codes and what to do about each are on Resolve API Errors.