ORCID Validation in Python — Researcher Identifier Lookup
Every researcher can have an ORCID — a persistent digital identifier that disambiguates authors across journals, institutions, and funding bodies. Here's how ORCIDs are structured, why validation matters, and how to validate and look up any ORCID in your Python application.
In this guide
1. What is an ORCID?
ORCID stands for Open Researcher and Contributor ID. It is a persistent digital identifier that uniquely distinguishes individual researchers — solving the name ambiguity problem that plagues academic publishing. Two researchers named "J. Smith" at the same university are clearly distinguished by their ORCIDs.
ORCIDs are managed by the ORCID organisation, a non-profit launched in 2012. The registry now holds over 18 million identifiers and is integrated into the submission workflows of most major publishers, funders, and institutional systems worldwide.
ORCIDs are used by publishers (Elsevier, Springer Nature, Wiley), funding agencies (NIH, ERC, UKRI), institutional repositories, and preprint servers. Many journal submission systems now require an ORCID at manuscript submission time.
2. ORCID structure
An ORCID iD is a 16-digit number displayed in four groups of four, separated by hyphens. The final character is a check digit calculated using the ISO 7064 MOD 11-2 algorithm, which can be a digit (0-9) or the letter X (representing the value 10).
ORCID anatomy
Check digit calculation
The last character is computed using ISO 7064 MOD 11-2 over the first 15 digits. If the remainder maps to 10, the check digit is represented as X. This detects single-digit errors and all transposition errors.
| Format | Example | Notes |
|---|---|---|
| XXXX-XXXX-XXXX-XXXX | 0000-0002-1825-0097 | Standard display format |
| XXXX-XXXX-XXXX-XXXX | 0000-0001-5109-3700 | Check digit is 0 |
| XXXX-XXXX-XXXX-XXXX | 0000-0002-1694-233X | Check digit is X (value 10) |
0000 in practice.3. Why ORCID validation matters
ORCIDs are critical infrastructure for research identity management. Invalid or malformed ORCIDs cause real problems in production systems:
Grant applications
Funding agencies (NIH, NSF, ERC, UKRI) increasingly require valid ORCIDs on grant applications. A malformed ORCID can delay or invalidate a submission. Automated systems that pre-populate applicant profiles depend on correct identifiers to link prior publications and funding history.
Journal submissions
Most major publishers require ORCIDs during manuscript submission. Editorial systems use the ORCID to auto-fill author details, link to reviewer profiles, and track publication records. An invalid ORCID breaks this chain and can cause authorship attribution errors that persist in the published record.
Institutional repositories
Universities use ORCIDs to link researchers to their institutional profiles, publications, and datasets. CRIS systems (Pure, Symplectic, VIVO) rely on ORCIDs as the primary key for researcher disambiguation. Importing records with invalid ORCIDs creates ghost profiles and breaks reporting.
Data integrity
Research information systems that aggregate data from multiple sources use ORCIDs for deduplication. A single transposed digit can split one researcher into two records or merge two researchers into one — both scenarios are costly to fix.
4. Basic validation vs profile lookup
The IsValid ORCID API offers two modes of validation. Basic validation checks the ORCID format, verifies the ISO 7064 check digit, and returns the formatted identifier with its URI. Profile lookup goes further and retrieves the researcher's public profile from the ORCID registry.
Basic (default)
- Format validation
- ISO 7064 MOD 11-2 check digit verification
- Formatted ORCID (XXXX-XXXX-XXXX-XXXX)
- ORCID URI
With lookup=True
- Everything from basic, plus:
- Whether the profile was found
- Given names and family name
- Current organisation
5. The right solution
The IsValid ORCID API handles format validation, check digit verification, formatting, and optional profile retrieval in a single call.
Full parameter reference and response schema: ORCID Validation API docs →
6. Python code example
from isvalid import create_client iv = create_client(api_key=os.environ["ISVALID_API_KEY"]) # ── Basic validation ──────────────────────────────────────────────────────── result = iv.orcid("0000-0002-1825-0097") print(result["valid"]) # True print(result["formatted"]) # '0000-0002-1825-0097' print(result["uri"]) # 'https://orcid.org/0000-0002-1825-0097' # ── With profile lookup ───────────────────────────────────────────────────── lookup = iv.orcid("0000-0002-1825-0097", lookup=True) print(lookup["profile"]["givenNames"]) # 'Josiah' print(lookup["profile"]["familyName"]) # 'Carberry' print(lookup["profile"]["organization"]) # 'Brown University'
In a researcher onboarding pipeline:
# Validate ORCIDs before importing researcher records def import_researchers(rows: list[dict]) -> list[dict]: results = [] for row in rows: if not row.get("orcid"): results.append({**row, "orcid_status": "missing"}) continue check = iv.orcid(row["orcid"], lookup=True) if not check["valid"]: results.append({**row, "orcid_status": "invalid"}) continue results.append({ **row, "orcid": check["formatted"], "given_names": check.get("profile", {}).get("givenNames"), "family_name": check.get("profile", {}).get("familyName"), "organization": check.get("profile", {}).get("organization"), "orcid_status": "valid", }) return results
0000-0002-1825-0097) rather than a bare digit string. You can construct the URI at display time by prepending https://orcid.org/.7. cURL example
Basic ORCID validation:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/orcid?value=0000-0002-1825-0097"
With profile lookup:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/orcid?value=0000-0002-1825-0097&lookup=true"
ORCID without hyphens:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/orcid?value=0000000218250097"
Invalid ORCID:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/orcid?value=0000-0002-1825-0000"
8. Understanding the response
Basic validation (valid ORCID):
{ "valid": true, "formatted": "0000-0002-1825-0097", "uri": "https://orcid.org/0000-0002-1825-0097" }
With profile lookup:
{ "valid": true, "formatted": "0000-0002-1825-0097", "uri": "https://orcid.org/0000-0002-1825-0097", "profile": { "found": true, "givenNames": "Josiah", "familyName": "Carberry", "organization": "Brown University" } }
Invalid ORCID:
{ "valid": false }
| Field | Type | Description |
|---|---|---|
| valid | boolean | Whether the ORCID has a valid format and check digit |
| formatted | string | The ORCID in display format (XXXX-XXXX-XXXX-XXXX) |
| uri | string | Full ORCID URI (https://orcid.org/...) |
| profile | object | Only present when lookup=True |
| profile.found | boolean | Whether a public profile exists for this ORCID |
| profile.givenNames | string | The researcher's given (first) names |
| profile.familyName | string | The researcher's family (last) name |
| profile.organization | string | The researcher's current organisation affiliation |
9. Edge cases
(a) Check digit X
When the ISO 7064 MOD 11-2 algorithm produces a remainder of 10, the check digit is represented as the uppercase letter X. This is valid and must be accepted by any ORCID validation logic. The API handles this correctly and will normalise lowercase x to uppercase in the formatted output.
# ORCID with check digit X result = iv.orcid("0000-0002-1694-233X") print(result["valid"]) # True print(result["formatted"]) # '0000-0002-1694-233X'
(b) URL vs bare ID
Researchers often share their ORCID as a full URL (https://orcid.org/0000-0002-1825-0097) rather than the bare identifier. If your system collects ORCIDs from user input, strip the URL prefix before passing it to the API.
import re # Strip the ORCID URL prefix before validation def extract_orcid(raw: str) -> str: return re.sub(r"^https?://orcid\.org/", "", raw, flags=re.IGNORECASE).strip() orcid = extract_orcid("https://orcid.org/0000-0002-1825-0097") result = iv.orcid(orcid) print(result["valid"]) # True
(c) Inactive profiles
An ORCID can be structurally valid (correct format and check digit) but belong to an inactive or deactivated profile. When using lookup=True, check the profile.found field to determine whether the profile is publicly accessible. A valid ORCID with found: false may indicate a deactivated account or a profile set to private.
(d) Hyphens and whitespace
The canonical display format uses hyphens between groups, but users may enter ORCIDs without hyphens or with spaces. The API accepts the bare 16-digit string and will return the properly formatted version. Always store the hyphenated format returned in the formatted field.
10. Summary
See also
Validate ORCIDs instantly
Free tier includes 100 API calls per day. No credit card required. Supports basic validation and profile lookup.