# Citation Link and Metadata Auditor (`flintglade/citation-link-metadata-auditor`) Actor

Audit DOI, PMID, and public HTTPS citations for resolvability, canonical identifiers, redirects, metadata mismatches, and source-reported correction or retraction signals.

- **URL**: https://apify.com/flintglade/citation-link-metadata-auditor.md
- **Developed by:** [Flintglade](https://apify.com/flintglade) (community)
- **Categories:** AI, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 citation audits

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Citation Link and Metadata Auditor

Audit explicit DOI, PMID, and public HTTPS citations for resolvability, canonical identifiers, redirect behavior, metadata consistency, content type, and source-reported correction or retraction signals.

### What this does not do

- No paper-content retrieval.
- No citation-quality or truth score.
- No automatic manuscript changes or link repair.
- No medical interpretation.
- No crawling references from a page.
- No guarantee that provider metadata is complete.

### Sources and authorization

The Actor uses public Crossref REST metadata, NCBI E-utilities metadata, and a bounded request to a user-supplied public HTTPS URL. URL checks start with `HEAD` and use `GET Range: bytes=0-65535` only when HEAD is unsupported. Every redirect hop is revalidated against the SSRF policy. The Actor does not retain article or page bodies.

### Input

Each of 1-1,000 entries contains exactly one `doi`, `pmid`, or `url`, and may include `expectedTitle` and `expectedYear`. Checks can be limited to identifiers, HTTP, metadata, or corrections. Concurrency is 1-16 and each response is capped at 2 MB.

```json
{"citations":[{"doi":"10.1038/s41586-021-03819-2"}],"checks":["identifiers","metadata","corrections"],"followRedirects":true,"concurrency":1}
````

### Output

One result row is written per citation, followed by one uncharged run summary. Result rows include canonical identifiers, redirect chain, HTTP evidence, bounded metadata, deterministic expected-field comparison, source coverage, source-reported warnings, evidence locators, and a recommended human action. KVS includes source-contract and artifact manifests.

```json
{"status":"ok","data":{"substatus":"healthy","canonicalIdentifiers":{"doi":"10.1038/s41586-021-03819-2"},"sourceWarnings":[],"recommendedHumanAction":"No citation-specific action indicated by the selected checks."},"charge":{"event":"citation-audit","chargeable":true}}
```

### Pricing

The primary event is `citation-audit` at **$0.01 per terminal citation audit**. Healthy, redirected, metadata-mismatch, definitive not-found, source-warning, and useful partial results are chargeable. Invalid input, blocked URLs, transient DNS/TLS failures, provider outages, and exhausted rate limits are not charged. The maximum event cost is the number of admitted terminal audits multiplied by $0.01; Apify platform usage is separate.

### State

The Actor is stateless. It creates no baseline and commits no monitor state. Duplicate inputs are independently represented so billing and result cardinality remain explicit.

### Negative and partial results

A verified 404/410 is a useful terminal result, not a run failure. A source warning is always labeled as provider-reported and never restated as a Flintglade determination. When one selected source succeeds and another fails transiently, the row is `partial` only if it still provides useful evidence.

### Resources

Minimum 256 MB, default 512 MB, maximum 1024 MB, and a 300-second hosted timeout. Requests follow a five-hop redirect cap, 2 MB response cap, and maximum concurrency of 16.

### Data handling, privacy, and deletion

Input and results are stored in the run's Apify storages under the caller's account retention settings. Optional Crossref `mailto` is treated as secret and is never echoed. URLs with credentials are rejected and query values are not used as display identifiers. Delete the run, dataset, and key-value store in Apify to delete stored output.

### Rights and attribution

Crossref metadata is attributed to Crossref; PubMed metadata is attributed to NCBI. Explicit URL evidence is limited to technical metadata authorized by the user-supplied locator. Provider names and marks are not used to imply endorsement.

### Limitations

Provider metadata can lag publishers or omit relations. A reachable URL can still contain incorrect content. Title similarity is reported separately from exact normalized equality and never auto-corrects a citation. Source outages and hostile destinations can make an audit partial or unchargeable.

Support: support@flintglade.com

# Actor input Schema

## `inputSchemaVersion` (type: `integer`):

Versioned runtime input contract.

## `citations` (type: `array`):

Each entry must contain exactly one DOI, PMID, or URL.

## `checks` (type: `array`):

Selected identifier, HTTP, metadata, and source-reported correction checks.

## `followRedirects` (type: `boolean`):

Follow at most five SSRF-revalidated HTTPS redirects.

## `includeExpectedComparison` (type: `boolean`):

Compare supplied expected title and year using deterministic rules.

## `mailto` (type: `string`):

Optional public contact sent only to Crossref; never echoed beyond redacted input handling.

## `maxResponseBytes` (type: `integer`):

Hard maximum for each provider response; response bodies are not retained.

## `concurrency` (type: `integer`):

Maximum simultaneously active citation audits.

## Actor input object example

```json
{
  "inputSchemaVersion": 1,
  "citations": [
    {
      "doi": "10.1038/s41586-021-03819-2"
    }
  ],
  "checks": [
    "identifiers",
    "metadata",
    "corrections"
  ],
  "followRedirects": true,
  "includeExpectedComparison": true,
  "maxResponseBytes": 2000000,
  "concurrency": 8
}
```

# Actor output Schema

## `defaultDataset` (type: `string`):

No description

## `sourceContracts` (type: `string`):

No description

## `artifactManifest` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "citations": [
        {
            "doi": "10.1038/s41586-021-03819-2"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("flintglade/citation-link-metadata-auditor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "citations": [{ "doi": "10.1038/s41586-021-03819-2" }] }

# Run the Actor and wait for it to finish
run = client.actor("flintglade/citation-link-metadata-auditor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "citations": [
    {
      "doi": "10.1038/s41586-021-03819-2"
    }
  ]
}' |
apify call flintglade/citation-link-metadata-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=flintglade/citation-link-metadata-auditor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Citation Link and Metadata Auditor",
        "description": "Audit DOI, PMID, and public HTTPS citations for resolvability, canonical identifiers, redirects, metadata mismatches, and source-reported correction or retraction signals.",
        "version": "0.1",
        "x-build-id": "4jvvspUgmqtpyClWN"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/flintglade~citation-link-metadata-auditor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-flintglade-citation-link-metadata-auditor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/flintglade~citation-link-metadata-auditor/runs": {
            "post": {
                "operationId": "runs-sync-flintglade-citation-link-metadata-auditor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/flintglade~citation-link-metadata-auditor/run-sync": {
            "post": {
                "operationId": "run-sync-flintglade-citation-link-metadata-auditor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "citations"
                ],
                "properties": {
                    "inputSchemaVersion": {
                        "title": "Input schema version",
                        "minimum": 1,
                        "maximum": 1,
                        "type": "integer",
                        "description": "Versioned runtime input contract.",
                        "default": 1
                    },
                    "citations": {
                        "title": "Citations",
                        "minItems": 1,
                        "maxItems": 1000,
                        "type": "array",
                        "description": "Each entry must contain exactly one DOI, PMID, or URL.",
                        "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "properties": {
                                "doi": {
                                    "title": "DOI",
                                    "description": "DOI in bare, doi:, or doi.org form.",
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2000
                                },
                                "pmid": {
                                    "title": "PMID",
                                    "description": "Positive numeric PubMed identifier.",
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 30
                                },
                                "url": {
                                    "title": "Public HTTPS URL",
                                    "description": "Explicit public HTTPS citation URL with no credentials or fragment.",
                                    "type": "string",
                                    "maxLength": 2048
                                },
                                "expectedTitle": {
                                    "title": "Expected title",
                                    "description": "Optional title to compare without automatic correction.",
                                    "type": "string",
                                    "maxLength": 2000
                                },
                                "expectedYear": {
                                    "title": "Expected year",
                                    "description": "Optional publication year to compare exactly.",
                                    "type": "integer",
                                    "minimum": 1600,
                                    "maximum": 3000
                                }
                            }
                        }
                    },
                    "checks": {
                        "title": "Checks",
                        "minItems": 1,
                        "maxItems": 4,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Selected identifier, HTTP, metadata, and source-reported correction checks.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "identifiers",
                                "http",
                                "metadata",
                                "corrections"
                            ],
                            "enumTitles": [
                                "Identifiers",
                                "HTTP",
                                "Metadata",
                                "Corrections"
                            ]
                        },
                        "default": [
                            "identifiers",
                            "metadata",
                            "corrections"
                        ]
                    },
                    "followRedirects": {
                        "title": "Follow redirects",
                        "type": "boolean",
                        "description": "Follow at most five SSRF-revalidated HTTPS redirects.",
                        "default": true
                    },
                    "includeExpectedComparison": {
                        "title": "Compare expected fields",
                        "type": "boolean",
                        "description": "Compare supplied expected title and year using deterministic rules.",
                        "default": true
                    },
                    "mailto": {
                        "title": "Crossref contact email",
                        "type": "string",
                        "description": "Optional public contact sent only to Crossref; never echoed beyond redacted input handling."
                    },
                    "maxResponseBytes": {
                        "title": "Maximum response bytes",
                        "minimum": 1024,
                        "maximum": 2000000,
                        "type": "integer",
                        "description": "Hard maximum for each provider response; response bodies are not retained.",
                        "default": 2000000
                    },
                    "concurrency": {
                        "title": "Concurrency",
                        "minimum": 1,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Maximum simultaneously active citation audits.",
                        "default": 8
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
