This guide explains the IDMS Credential Lookup feature: what it does, how to switch it on, who can use it, how to call it from another application, and how to check that it is running well. It is written for administrators who are new to the feature. You do not need to edit any configuration files.
1. Overview
Credential Lookup lets another application, such as a badge reader station or an access control system, find a person in IDMS from a single value it has scanned or typed, such as a badge barcode. It sends the value to IDMS and gets back, in one quick answer:
|
Returned |
Meaning |
|---|---|
|
First, middle and last name |
The person's name, as stored in IDMS |
|
Network user ID |
The person's network or directory account ID |
|
Request status |
The status of the person's most recent credential request, for example |
|
Badge type |
The credential type (policy) the person is assigned to |
|
Matched field |
Which field the value was found in, for example |
2. What it does and how it works
2.1 Searchable fields
The values you look up come from the questions on a credential type's intake form, for example a "Badge barcode" question. An administrator chooses which intake questions can be searched by ticking Searchable next to them. Each credential type has its own choices, so different credential types can be searched by different fields.
2.2 How a lookup finds the person
-
When a person's answer to a searchable question is saved, IDMS creates a fingerprint of the value and stores it in a search index. The fingerprint is a one-way code made with a secret key, so the index never contains the readable value.
-
When an application looks up a value, IDMS makes the fingerprint of that value and finds the matching entry in the index. This takes a few milliseconds, even with very large numbers of people.
-
IDMS then reads the person's name, network user ID, latest request status and badge type, and returns them.
2.3 Things worth knowing
-
Exact match only. The value must match the stored answer exactly, except that spaces before and after the value are ignored and, for numbers, leading zeros are ignored (
000123matches123). Partial or "starts with" searches are not supported. -
Freshness. Answers are remembered for up to 60 seconds to keep lookups fast. A change in IDMS (for example a request moving to
ISSUED) appears in lookups within 60 seconds. -
Index upkeep is automatic. The index is updated whenever a person is enrolled, edited, moved to another credential type or expunged. When you tick Searchable on a credential type that already has people, IDMS indexes them in the background. A nightly job checks the whole index and repairs anything that is out of step (see section 7).
-
Privacy. Readable values are never stored in the index and never written to the log. Expunged people are removed from the index, so they cannot be found.
-
Duplicates. If two people have the same value in a searchable field, a lookup returns "ambiguous" (409) rather than guessing. The IDMS log names both people so you can correct the data.
-
Auditing. Every time someone ticks or unticks Searchable, IDMS writes an audit entry with the operator, credential type, field and change (audit transaction type
SrchIdxCfg).
3. Configuration requirements
There is nothing to install and no configuration file to edit.
|
Requirement |
Details |
|---|---|
|
Calling account |
An IDMS operator account with a client certificate and the |
3.1 Setup steps
Step 1: Choose the searchable field (needs the SystemManager role)
-
Go to Administration > Credential Types.
-
Open the credential type (policy) whose people you want to find.
-
In the Intake Form grid, find the question that holds the value, for example
barCode. -
Tick Searchable for that question. Hover over the column heading for guidance.
-
Save the credential type.
-
Repeat for every credential type whose people should be found.
Notes:
-
Searchable can only be ticked for text fields (text box, text area, IDMS user ID). Files, PDFs, photos and signatures cannot be searched.
-
Choose fields whose values are unique to one person, such as a badge number. Do not make fields with only a few possible answers searchable (yes/no, department, and so on).
-
Existing people on that credential type are indexed in the background straight after you save. Large credential types can take a few minutes. The IDMS log shows when the background indexing starts and finishes.
Step 2: Create the account the calling application will use (needs the SystemManager role)
-
Go to Administration > Operators and add an operator for the application, for example "Badge Station Service".
-
Enter the Certificate Thumbprint of the client certificate the application will present.
-
Assign the role
BadgeLookup.
Give this account only the roles it needs. Use a separate account for each application so their traffic can be told apart in the logs.
Step 3: Give monitoring access (optional, needs the SystemManager role)
-
Go to Administration > Operators and open each person who should see the Performance tab.
-
Assign the role
SystemMonitor. These people also needSystemManager, because the tab is on the Administration > System Connections page. -
If a monitoring dashboard will call the detailed status API, create a separate account for it with
SystemMonitor, so it does not share the status call limit with people using the screen.
Step 4: Test it
Use the PowerShell sample in section 6.3 with a value you know exists. You should get 200 and the person's details.
4. Roles required
|
Role |
Who gets it |
What it allows |
|---|---|---|
|
|
IDMS administrators |
Ticking Searchable on credential types; creating operators and assigning roles; reaching Administration > System Connections; running the index jobs on demand |
|
|
The account used by the calling application |
Calling the lookup API ( |
|
|
Administrators who watch performance, and monitoring dashboards |
Seeing the Performance tab and calling the detailed status API ( |
Both new roles (BadgeLookup and SystemMonitor) are added to IDMS automatically when it starts. You only need to assign them.
5. Calling the lookup API
5.1 The basics
Every call needs a token. The application gets a token once, keeps it, and sends it with each lookup.
|
Step |
Call |
|---|---|
|
1. Get a token |
|
|
2. Look up a value |
|
|
3. Check health (optional) |
|
-
<value>is the scanned value. URL-encode it if it can contain anything other than letters and numbers. -
attributeis the intake field name (itsdataName), for examplebarCode. It is optional but recommended: it makes the lookup faster and avoids ambiguous results. Without it, every searchable field is searched. -
Tokens last 1 day. Request one token, reuse it for all lookups, and renew it every hour. Do not request a new token for every scan.
5.2 Answers you can get
A successful lookup (200 OK):
{
"userId": 1000015058,
"firstName": "Jane",
"middleName": "A",
"lastName": "Doe",
"networkUserId": "jdoe01",
"requestStatus": "APPROVED",
"badgeType": "DCMLL",
"matchedAttribute": "barCode",
"asOf": "2026-10-12T14:03:22Z"
}
asOf is when the details were read from the database (up to 60 seconds earlier).
|
Code |
Meaning |
What the application should do |
|---|---|---|
|
200 |
Exactly one person found |
Use the details |
|
400 |
The value is blank or longer than 256 characters, or |
Do not retry; fix the request |
|
401 |
The token is missing or expired |
Get a new token, then retry once |
|
403 |
The account does not have the |
Do not retry; ask the IDMS administrator |
|
404 |
No one has this value (also returned for values in the wrong format) |
Do not retry; treat as "not found" |
|
409 |
More than one person has this value |
Do not retry; report it to the IDMS administrator |
|
429 |
This account is sending too fast |
Wait the number of seconds in |
|
503 |
IDMS is busy or the database is slow |
Wait the number of seconds in |
|
500 |
Unexpected error |
Retry later; give the |
Error bodies look like { "error": "NotFound" }. 429 and 503 bodies also include retryAfterSeconds.
Every answer includes a Server-Timing header showing how long IDMS took, for example db;dur=3.2, total;dur=5.1 (milliseconds).
5.3 Good practice for the calling application
-
Always wait for
Retry-Afteron 429 and 503. Retrying immediately makes the overload worse. -
Never retry 400, 403, 404 or 409. The answer will not change.
-
If many stations share one application, the application should call IDMS on their behalf and share the results, rather than each station calling separately. This also applies to the status API.
-
Optionally send an
X-Station-Idheader naming the station. IDMS can log it to help trace problems.
6. Sample API calls
Replace <https://idms.example.com/WebApi,> the certificate thumbprint and the values with your own.
6.1 PowerShell: get a token and look up a value
Works in Windows PowerShell 5.1 and PowerShell 7. The client certificate must be in the current user's certificate store.
$baseUrl = "https://idms.example.com/WebApi"
$thumbprint = "<client certificate thumbprint>"
$cert = Get-Item -Path (Join-Path "Cert:\CurrentUser\My" $thumbprint)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# 1. Get a token (once; reuse it and renew it hourly)
$token = Invoke-RestMethod -Method Post -Uri "$baseUrl/Token" -Certificate $cert `
-ContentType "application/x-www-form-urlencoded" `
-Body "grant_type=password&username=apiuser&password=unused"
$headers = @{ Authorization = "Bearer $($token.access_token)" }
# 2. Look up a badge barcode
$value = [uri]::EscapeDataString("1234567890")
try {
$person = Invoke-RestMethod -Method Get -Uri "$baseUrl/api/v2/lookup/$($value)?attribute=barCode" `
-Headers $headers -Certificate $cert
"$($person.firstName) $($person.lastName): $($person.requestStatus), $($person.badgeType)"
}
catch {
$code = [int]$_.Exception.Response.StatusCode
"Lookup failed with HTTP $code"
}
6.2 PowerShell: check the status
# Basic status (role BadgeLookup): ok, degraded or unavailable
Invoke-RestMethod -Uri "$baseUrl/api/v2/status" -Headers $headers -Certificate $cert
# Detailed status (role SystemMonitor)
Invoke-RestMethod -Uri "$baseUrl/api/v2/status/detail" -Headers $headers -Certificate $cert |
ConvertTo-Json -Depth 6
6.3 PowerShell: quick test with status code and timing
Use this in Step 4 of the setup to see exactly what IDMS returns, including errors.
$response = Invoke-WebRequest -Uri "$baseUrl/api/v2/lookup/1234567890?attribute=barCode" `
-Headers $headers -Certificate $cert -UseBasicParsing -SkipHttpErrorCheck
"Status: $($response.StatusCode)"
"Timing: $($response.Headers['Server-Timing'])"
$response.Content
-SkipHttpErrorCheck needs PowerShell 7. In Windows PowerShell 5.1, remove it; error codes then appear as exceptions, as in 6.1.
6.4 curl (Windows)
The curl that comes with Windows can use a certificate from the Windows certificate store:
curl -s -X POST "https://idms.example.com/WebApi/Token" \
--cert "CurrentUser\My\<thumbprint>" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=apiuser&password=unused"
curl -s -i "https://idms.example.com/WebApi/api/v2/lookup/1234567890?attribute=barCode" \
--cert "CurrentUser\My\<thumbprint>" \
-H "Authorization: Bearer <access_token>"
On Linux or macOS, use the certificate file instead, for example --cert-type P12 --cert client.pfx:<pfx password>.
6.5 C# (.NET): reuse one client and one token
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
public sealed class CredentialLookupClient
{
private readonly HttpClient _http;
private string _token;
private DateTime _tokenExpires = DateTime.MinValue;
public CredentialLookupClient(string baseUrl, X509Certificate2 clientCertificate)
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(clientCertificate);
_http = new HttpClient(handler) { BaseAddress = new Uri(baseUrl.TrimEnd('/') + "/") };
}
public async Task<string> LookupAsync(string value, string attribute = "barCode")
{
await EnsureTokenAsync();
var request = new HttpRequestMessage(HttpMethod.Get,
"api/v2/lookup/" + Uri.EscapeDataString(value) + "?attribute=" + Uri.EscapeDataString(attribute));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
HttpResponseMessage response = await _http.SendAsync(request);
if (response.StatusCode == (HttpStatusCode)429 || response.StatusCode == HttpStatusCode.ServiceUnavailable)
{
TimeSpan wait = response.Headers.RetryAfter?.Delta ?? TimeSpan.FromSeconds(5);
await Task.Delay(wait); // wait as told, then let the caller try again
return null;
}
if (response.StatusCode == HttpStatusCode.NotFound)
{
return null; // not found: do not retry
}
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync(); // JSON with the person's details
}
private async Task EnsureTokenAsync()
{
if (_token != null && DateTime.UtcNow < _tokenExpires)
{
return;
}
var body = new FormUrlEncodedContent(new[]
{
new System.Collections.Generic.KeyValuePair<string, string>("grant_type", "password"),
new System.Collections.Generic.KeyValuePair<string, string>("username", "apiuser"),
new System.Collections.Generic.KeyValuePair<string, string>("password", "unused")
});
HttpResponseMessage response = await _http.PostAsync("Token", body);
response.EnsureSuccessStatusCode();
dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
_token = (string)json.access_token;
_tokenExpires = DateTime.UtcNow.AddHours(1); // renew hourly
}
}
Create one CredentialLookupClient when the application starts and use it for every scan.
7. Background jobs (Job Scheduler)
Credential Lookup uses two background tasks. Neither needs setting up.
7.1 Background indexing (runs on its own)
When someone ticks Searchable on a credential type and saves, IDMS indexes that credential type's existing people in the background. It works in small batches with short pauses so it does not slow IDMS down. When someone unticks Searchable, IDMS removes that field's index entries for the credential type. Both are recorded in the IDMS log.
7.2 Nightly check and repair: SearchableIndexReconciliationJobManager
|
Item |
Details |
|---|---|
|
What it does |
Checks the whole search index against the IDMS records. It removes entries for people who were deleted, moved to another credential type, or whose field is no longer searchable, and adds or fixes entries that are missing or out of date. |
|
When it runs |
Every day at 3:30 am (server time). |
|
Where to see it |
Administration > Scheduling, Job Scheduling tab. It is listed by name, with its state and the result of its last run. |
|
Set up needed |
None. Unlike most IDMS jobs, it is switched on automatically. |
|
Several IDMS servers |
Safe. Only one server runs it at a time; the others skip that night's run. |
Pause or resume it: on the Job Scheduling tab, use the pause or play button on the job's row.
Change when it runs: click the cog button on the job's row and change the schedule. The schedule uses Quartz cron format (seconds, minutes, hours, day of month, month, day of week):
|
Schedule |
Cron value |
|---|---|
|
Every day at 3:30 am (default) |
|
|
Every day at 1:00 am |
|
|
Every Sunday at 2:00 am |
|
Choose a quiet time. The job reads every person on credential types with a searchable field, so on large systems it can take a while.
Run it now: a SystemManager account can start it straight away with POST <https://<server>>/WebApi/api/SearchableIndex/StartReconciliation. To index a single credential type again, use POST <https://<server>>/WebApi/api/SearchableIndex/StartBackfill?policyKey=<credential type key>. Both return straight away; the work continues in the background and is logged.
7.3 External systems health check: HealthCheckerJobManager
The External systems card on the Performance tab shows the latest result of the existing IDMS health check job. That job is installed paused. If the card says the check hasn't run, resume HealthCheckerJobManager on the Job Scheduling tab. It does not affect lookups.
8. Monitoring performance
8.1 The Performance tab
Go to Administration > System Connections and open the Performance tab. You need the SystemManager and SystemMonitor roles.
-
The figures refresh every 20 seconds while the tab is open. Use Refresh for an immediate update, or Pause to stop.
-
Each card has an (i) button at its top right. Click it for a plain explanation of the card.
|
Card |
What it tells you |
|---|---|
|
Status banner |
OK (green), Degraded (amber, with the reasons listed) or Unavailable (red). Also shows which server answered and how fresh the figures are. |
|
Badge lookups |
Lookups in the last minute; how many are being worked on now ("Busy N of 64"); how many were turned away |
|
Response time |
Typical and slowest-5% answer times for the last minute and last 5 minutes; average database time |
|
Database |
Whether the IDMS database is reachable, and how long a quick check takes |
|
Server |
Processor use of IDMS and of the whole server; web server connections |
|
External systems |
Summary of the IDMS external-system health check |
|
Trend |
A chart of the last 40 refreshes (about 13 minutes): lookups per minute and slowest-5% response time |
When to act:
|
You see |
What it means |
What to do |
|---|---|---|
|
Degraded: slowest 5% over 500 ms |
Lookups are getting slow |
Check the Database and Server cards. Look for other heavy work on the server or database. |
|
Degraded: lookup slots busy over 75% |
Many lookups at once |
Usually a traffic peak. If it lasts, the calling application may not be waiting for |
|
Degraded: database check over 1 s |
The database is slow |
Check the database server. |
|
Unavailable |
IDMS cannot reach its database |
Check the database server and the IDMS log straight away. |
|
"Turned away" above 0 |
Lookups were refused with 429 or 503 |
Check that the calling application waits for |
If you run several IDMS servers behind a load balancer, each server has its own figures. The banner shows which server answered.
8.2 Status APIs for dashboards
|
API |
Role |
Returns |
|---|---|---|
|
|
|
|
|
|
|
All the figures on the Performance tab, as JSON |
-
The figures are measured every 10 seconds, so calling more often gives the same answer.
-
Each account may call each status API 6 times a minute. More calls get 429. Poll every 20 to 30 seconds.
8.3 The IDMS log
By default the IDMS WebApi log is c:\\temp\\idexchangeWebApi.txt on the IDMS server. Useful lines:
|
Log line |
Meaning |
|---|---|
|
|
Written once a minute while there is lookup traffic: counts per answer, response times and the busiest accounts |
|
|
The nightly check finished, with counts of entries added and removed |
|
Backfill started / finished |
Background indexing after Searchable was ticked |
|
Duplicate warning |
Two people have the same value in a searchable field. Both IDs are listed. |
|
Status changes and database check failures |
Logged once when they happen, and again when they recover |
Readable lookup values are never written to the log.
8.4 Built-in limits
These protect IDMS from overload. They suit most sites and do not need changing.
|
Limit |
Default |
|---|---|
|
Lookups per second per account |
100 (short bursts up to 200) |
|
Lookups worked on at the same time (all accounts) |
64 |
|
Status API calls per minute, per account and API |
6 |
|
Failed (unauthorised) requests per second from one address before it is refused |
20 |
|
"Not found" answers per minute before an account is slowed for 5 minutes as possible guessing |
300, when most of its lookups are "not found" |
|
Longest value accepted |
256 characters |
|
How long answers are remembered |
60 seconds |
If your traffic needs different limits, they can be overridden in Web.config. See the separate note "Badge Lookup: Optional Rate-Limit Settings" before changing them.
9. Troubleshooting
|
Problem |
Likely cause |
Fix |
|---|---|---|
|
Every lookup returns 404 |
Searchable isn't ticked for the field, or |
Check the credential type's Intake Form. Check the field name ( |
|
A person who should be found returns 404 |
Their credential type has no searchable field, or their answer is different from the scanned value |
Check the person's credential type and their answer to the field. Run the reconciliation job if you suspect the index is out of date. |
|
400 |
|
Correct the field name or the value |
|
401 |
The token expired or wasn't sent |
Get a new token; renew it hourly |
|
403 |
The account lacks |
Assign the role in Administration > Operators |
|
409 |
Two people share the value |
Check the IDMS log for the duplicate warning and correct one person's record |
|
Many 429s |
The application is sending faster than its limit, or not waiting for |
Make the application wait as told; reuse one token |
|
503s |
IDMS is very busy or the database is slow |
Check the Performance tab and the database server |
|
The Performance tab is missing |
The operator lacks |
Assign the role, then sign out and back in |
|
External systems says the check hasn't run |
|
Resume it on the Job Scheduling tab (optional) |
|
Web server connections says "not available" |
The IDMS application pool account isn't in the Windows Performance Monitor Users group |
Optional: add it to the group and recycle the application pool |