Guide · Node.js · SDK · Publishing

Academic Publishing Validation

Four academic identifiers, one submission workflow. Here's how to validate a DOI, ORCID researcher ID, ISBN, and ISSN when building academic publishing platforms, citation managers, or repository submission systems.

1. The academic identifier validation problem

Academic publishing platforms need to validate multiple identifier types at once. A journal submission system must confirm the author's ORCID is valid, the DOI format is correct (and optionally resolve metadata), referenced ISBNs are structurally sound, and the journal's ISSN is registered.

Invalid identifiers cause broken links, failed CrossRef DOI registrations, metadata errors in indexing databases like PubMed and Scopus, and rejected submissions. A single malformed ORCID can block an author from being credited in a deposit.

The solution: validate all relevant identifiers in parallel at submission time, enriching the metadata and catching errors before they propagate into the scholarly record.

ℹ️CrossRef DOI registration requires valid prefixes (registered with CrossRef) and correctly formatted suffixes. Pre-validating DOI format before registration saves rejection round-trips with CrossRef's metadata API.

2. The four identifiers

ValidatorWhat it validatesWhen to useAPI endpoint
DOIFormat (10.prefix/suffix) + optional CrossRef metadataArticle/dataset DOI validationGET /v0/doi
ORCID16-digit format (MOD-11-2) + optional profile lookupAuthor identity verificationGET /v0/orcid
ISBNISBN-10/ISBN-13 check digit + normalizationBook references, citation validationGET /v0/isbn
ISSNMOD-11 check digit for serial publicationsJournal ISSN validationGET /v0/issn

3. Step 1: Validate the DOI

A Digital Object Identifier (DOI) follows the format 10.prefix/suffix. The endpoint validates:

  • Format validation — confirms the 10. prefix and non-empty suffix
  • Registrant identification — the numeric prefix identifies the CrossRef registrant
  • Metadata lookup — optionally resolves title, authors, publisher, and publication date via CrossRef

Example response

{
  "valid": true,
  "doi": "10.1038/nature12373",
  "prefix": "10.1038",
  "suffix": "nature12373",
  "registrantCode": "1038",
  "registrant": "Nature Publishing Group",
  "url": "https://doi.org/10.1038/nature12373",
  "metadata": {
    "found": true,
    "title": "Gravitational waves from binary pulsars",
    "authors": ["J. H. Taylor"],
    "publisher": "Springer Science and Business Media LLC",
    "type": "journal-article",
    "issued": [[1994, 1]]
  }
}

What to check in your code

1

valid === true — the DOI follows the 10.prefix/suffix format

2

metadata.found — CrossRef has a record; use title/authors to pre-fill the citation form

3

url — the canonical DOI resolver URL to store for linking


4. Step 2: Validate the ORCID

An ORCID (Open Researcher and Contributor ID) is a 16-digit identifier in four groups of four digits (XXXX-XXXX-XXXX-XXXX), with the last character being a MOD-11-2 check digit (0–9 or X). The endpoint validates:

  • Format and checksum — 16-digit ORCID with MOD-11-2 check
  • Public profile lookup — optionally retrieves the researcher's name and institution

Example response

{
  "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"
  }
}

What to check in your code

1

valid === true — the ORCID passes format and MOD-11-2 checksum validation

2

uri — store the canonical ORCID URI for linking and interoperability

3

profile.found — profile not found may mean private ORCID; do not reject the author


5. Step 3: Validate the ISBN

ISBN (International Standard Book Number) exists in two formats: ISBN-10 (legacy) and ISBN-13 (current standard). The endpoint accepts both and normalizes to ISBN-13:

Example response

{
  "valid": true,
  "format": "ISBN-13",
  "isbn10": "3161484100",
  "isbn13": "9783161484100"
}

What to check in your code

1

valid === true — the check digit is valid for the detected format

2

isbn13 — always store the ISBN-13 form as the canonical identifier


6. Step 4: Validate the ISSN

ISSN (International Standard Serial Number) identifies serial publications (journals, magazines, newspapers). It's 8 digits in two groups of four (XXXX-XXXX) with a MOD-11 check digit (0–9 or X).

Example response

{
  "valid": true,
  "issn": "0378-5955",
  "normalized": "03785955"
}

7. Putting it all together — parallel validation

The following example validates all applicable identifiers in parallel at article submission time. Pass only the identifiers that are present — the function adapts.

import { createClient } from '@isvalid-dev/sdk';

const iv = createClient({ apiKey: process.env.ISVALID_API_KEY });

async function validateAcademicSubmission({
  doi,    // article DOI (optional — may not exist yet for new submissions)
  orcid,  // author ORCID
  isbn,   // for book chapters or book references
  issn,   // journal ISSN
}) {
  const calls = {};

  if (doi) calls.doi = iv.doi(doi, { lookupMetadata: true });
  if (orcid) calls.orcid = iv.orcid(orcid, { lookupProfile: true });
  if (isbn) calls.isbn = iv.isbn(isbn);
  if (issn) calls.issn = iv.issn(issn);

  const keys = Object.keys(calls);
  const results = await Promise.all(Object.values(calls));
  const validated = Object.fromEntries(keys.map((k, i) => [k, results[i]]));

  return {
    doi: validated.doi ? {
      valid: validated.doi.valid,
      url: validated.doi.url ?? null,
      title: validated.doi.metadata?.title ?? null,
      authors: validated.doi.metadata?.authors ?? null,
    } : null,
    orcid: validated.orcid ? {
      valid: validated.orcid.valid,
      uri: validated.orcid.uri ?? null,
      name: validated.orcid.profile
        ? `${validated.orcid.profile.givenNames} ${validated.orcid.profile.familyName}`
        : null,
    } : null,
    isbn: validated.isbn ? {
      valid: validated.isbn.valid,
      isbn13: validated.isbn.isbn13 ?? null,
    } : null,
    issn: validated.issn ? {
      valid: validated.issn.valid,
      issn: validated.issn.issn ?? null,
    } : null,
  };
}

// ── Example: journal article submission ────────────────────────────────────
const result = await validateAcademicSubmission({
  doi: '10.1038/nature12373',
  orcid: '0000-0002-1825-0097',
  issn: '0028-0836', // Nature journal ISSN
});

console.log('DOI  :', result.doi?.valid ? `✓ ${result.doi.url}` : '✗ invalid');
console.log('ORCID:', result.orcid?.valid ? `✓ ${result.orcid.name ?? '(private profile)'}` : '✗ invalid');
console.log('ISSN :', result.issn?.valid ? `✓ ${result.issn.issn}` : '✗ invalid');

// Use DOI metadata to pre-fill citation fields
if (result.doi?.title) {
  console.log('Title (from CrossRef):', result.doi.title);
}
Use DOI metadata lookup (lookupMetadata: true) to pre-fill article title and authors from CrossRef — reducing manual entry errors in the submission form.

8. cURL examples

Validate a DOI with metadata lookup:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/doi?value=10.1038/nature12373&lookup=true"

Validate an ORCID with profile lookup:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/orcid?value=0000-0002-1825-0097&lookup=true"

Validate an ISBN:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/isbn?value=9783161484100"

Validate an ISSN:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.isvalid.dev/v0/issn?value=0028-0836"

9. Handling edge cases

DOI valid but metadata not found

CrossRef doesn't index all DOIs. Preprints (arXiv, bioRxiv) and datasets often have valid DOIs with no CrossRef record. metadata.found: false is not an error.

if (doiResult.valid && !doiResult.metadata?.found) {
  // DOI format is valid but no CrossRef record
  // Store the DOI but don't try to pre-fill citation metadata
  console.log('DOI valid — no CrossRef metadata (may be preprint or dataset)');
}

ORCID profile not public — still valid

Researchers can make their ORCID profiles private. profile.found: false does not mean the ORCID is invalid — the format and checksum passed. Accept the ORCID.

if (orcidResult.valid && !orcidResult.profile?.found) {
  // ORCID is valid but profile is private
  // Accept the ORCID — do not reject the author
  author.orcid = orcidResult.uri;
  author.name = submittedName; // Use user-supplied name
}

ISSN check character X

The ISSN check digit can be X (representing 10 in MOD-11). A user form might strip the X or convert to lowercase. Normalize before validating.

function normalizeISSN(raw) {
  // Uppercase, add hyphen if missing
  const clean = raw.toUpperCase().replace(/[^0-9X]/g, '');
  if (clean.length === 8) return `${clean.slice(0,4)}-${clean.slice(4)}`;
  return raw;
}
const result = await iv.issn(normalizeISSN('03785955x')); // → '0378-595X'

10. Summary checklist

Use DOI metadata lookup to pre-fill citation fields — reduces manual entry errors
Store the canonical ORCID URI (https://orcid.org/...) for interoperability
Always normalize ISBN to ISBN-13 — use the isbn13 field as the canonical form
Validate ISSN before CrossRef journal registration — invalid ISSNs cause failures
Do not reject DOIs without CrossRef metadata — preprints often have no CrossRef record
Do not reject authors with private ORCID profiles — format validity is sufficient

See also

Validate academic identifiers at submission

Free tier includes 100 API calls per day. DOI, ORCID, ISBN, and ISSN validation all included. No credit card required.