Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Retrieve structured metadata from any DOI via HTTP content negotiation
.claude/skills/brycewang-stanford-doi-content-negotiation/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 189% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 119% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 153% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 140% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 226% | 0% |
Any DOI can return structured metadata in multiple formats through HTTP content negotiation — simply set the Accept header when requesting https://doi.org/{doi}. This is the most universal way to get citation metadata, BibTeX entries, JSON-LD, and RDF from any publisher without needing a specific API. Works for all 300M+ registered DOIs. Free, no authentication.
bash# Get JSON citation metadata (Citeproc JSON) curl -LH "Accept: application/vnd.citationstyles.csl+json" \ "https://doi.org/10.1038/nature14539" # Get BibTeX curl -LH "Accept: application/x-bibtex" \ "https://doi.org/10.1038/nature14539" # Get RIS format curl -LH "Accept: application/x-research-info-systems" \ "https://doi.org/10.1038/nature14539" # Get formatted citation (APA style) curl -LH "Accept: text/x-bibliography; style=apa" \ "https://doi.org/10.1038/nature14539" # Get formatted citation (Chicago style) curl -LH "Accept: text/x-bibliography; style=chicago-author-date" \ "https://doi.org/10.1038/nature14539"
| Accept Header | Format | Use Case | |--------------|--------|----------| | application/vnd.citationstyles.csl+json | Citeproc JSON | Programmatic metadata | | application/x-bibtex | BibTeX | LaTeX bibliography | | application/x-research-info-systems | RIS | Reference managers | | text/x-bibliography; style=apa | Formatted text | Direct citation | | application/rdf+xml | RDF/XML | Linked data | | text/turtle | Turtle RDF | Linked data | | application/vnd.schemaorg.ld+json | Schema.org JSON-LD | Web metadata | | application/json | DataCite JSON | DataCite DOIs | | application/vnd.crossref.unixref+xml | Crossref XML | Full Crossref metadata |
Over 9,000 CSL styles available:
bash# APA 7th edition style=apa # Chicago Manual of Style (author-date) style=chicago-author-date # IEEE style=ieee # MLA style=modern-language-association # Harvard style=harvard-cite-them-right # Vancouver (medical) style=vancouver # Nature style=nature
json{ "DOI": "10.1038/nature14539", "type": "article-journal", "title": "Deep learning", "author": [ {"given": "Yann", "family": "LeCun"}, {"given": "Yoshua", "family": "Bengio"}, {"given": "Geoffrey", "family": "Hinton"} ], "container-title": "Nature", "volume": "521", "issue": "7553", "page": "436-444", "issued": {"date-parts": [[2015, 5, 28]]}, "publisher": "Springer Science and Business Media LLC", "ISSN": ["0028-0836", "1476-4687"], "URL": "http://dx.doi.org/10.1038/nature14539", "abstract": "Deep learning allows computational models..." }
pythonimport requests def get_metadata(doi: str) -> dict: """Get structured metadata for a DOI.""" resp = requests.get( f"https://doi.org/{doi}", headers={"Accept": "application/vnd.citationstyles.csl+json"}, allow_redirects=True, ) resp.raise_for_status() return resp.json() def get_bibtex(doi: str) -> str: """Get BibTeX entry for a DOI.""" resp = requests.get( f"https://doi.org/{doi}", headers={"Accept": "application/x-bibtex"}, allow_redirects=True, ) resp.raise_for_status() return resp.text def get_formatted_citation(doi: str, style: str = "apa") -> str: """Get a formatted citation string.""" resp = requests.get( f"https://doi.org/{doi}", headers={ "Accept": f"text/x-bibliography; style={style}", }, allow_redirects=True, ) resp.raise_for_status() return resp.text.strip() def batch_bibtex(dois: list) -> str: """Generate BibTeX file for multiple DOIs.""" entries = [] for doi in dois: try: bib = get_bibtex(doi) entries.append(bib) except requests.HTTPError: entries.append(f"% Failed to resolve: {doi}") return "\n\n".join(entries) # Example: get metadata meta = get_metadata("10.1038/nature14539") authors = ", ".join( f"{a['given']} {a['family']}" for a in meta.get("author", []) ) print(f"{meta['title']}") print(f" Authors: {authors}") print(f" {meta.get('container-title')} ({meta.get('volume')})") # Example: get BibTeX bibtex = get_bibtex("10.1038/nature14539") print(f"\nBibTeX:\n{bibtex}") # Example: formatted APA citation apa = get_formatted_citation("10.1038/nature14539", "apa") print(f"\nAPA: {apa}") # Example: batch export bibliography = batch_bibtex([ "10.1038/nature14539", "10.5555/3295222.3295349", ]) with open("references.bib", "w") as f: f.write(bibliography)
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→pass | 5,443 | 2,899 | -47% | 1 | 1 | 0% | 838 | 2,418 | +189% | 0 | 0 | — |
case-04 | pass→pass | 5,813 | 33,035 | +468% | 1 | 1 | 0% | 917 | 2,323 | +153% | 0 | 0 | — |
case-01 | pass→pass | 34,851 | 34,116 | -2% | 1 | 1 | 0% | 1,009 | 2,423 | +140% | 0 | 0 | — |
case-02 | pass→pass | 3,644 | 2,688 | -26% | 1 | 1 | 0% | 711 | 2,318 | +226% | 0 | 0 | — |
case-03 | pass→pass | 6,358 | 3,074 | -52% | 1 | 1 | 0% | 1,174 | 2,293 | +95% | 0 | 0 | — |
case-06 | pass→pass | 3,842 | 3,321 | -14% | 1 | 1 | 0% | 775 | 2,281 | +194% | 0 | 0 | — |
case-07 | pass→pass | 7,177 | 3,593 | -50% | 1 | 1 | 0% | 1,317 | 2,478 | +88% | 0 | 0 | — |
case-08 | pass→pass | 7,487 | 3,627 | -52% | 1 | 1 | 0% | 1,490 | 2,505 | +68% | 0 | 0 | — |
case-09 | pass→pass | 6,065 | 2,255 | -63% | 1 | 1 | 0% | 1,063 | 2,256 | +112% | 0 | 0 | — |
case-10 | pass→pass | 4,042 | 3,736 | -8% | 1 | 1 | 0% | 744 | 2,330 | +213% | 0 | 0 | — |
case-11 | pass→pass | 3,660 | 2,512 | -31% | 1 | 1 | 0% | 730 | 2,272 | +211% | 0 | 0 | — |
case-12 | pass→pass | 5,455 | 2,551 | -53% | 1 | 1 | 0% | 839 | 2,219 | +164% | 0 | 0 | — |
case-13 | pass→pass | 6,889 | 2,701 | -61% | 1 | 1 | 0% | 1,003 | 2,297 | +129% | 0 | 0 | — |
case-14 | pass→pass | 10,269 | 4,556 | -56% | 1 | 1 | 0% | 1,576 | 2,686 | +70% | 0 | 0 | — |
case-15 | fail→pass | 5,978 | 4,073 | -32% | 1 | 1 | 0% | 1,068 | 2,343 | +119% | 0 | 0 | — |
case-16 | pass→pass | 9,477 | 6,693 | -29% | 1 | 1 | 0% | 1,919 | 3,145 | +64% | 0 | 0 | — |
case-17 | pass→pass | 13,351 | 8,046 | -40% | 1 | 1 | 0% | 2,391 | 3,311 | +38% | 0 | 0 | — |
case-18 | pass→pass | 12,728 | 6,058 | -52% | 1 | 1 | 0% | 2,240 | 3,090 | +38% | 0 | 0 | — |
case-19 | pass→pass | 10,485 | 5,573 | -47% | 1 | 1 | 0% | 1,745 | 2,788 | +60% | 0 | 0 | — |
case-20 | pass→pass | 9,881 | 8,032 | -19% | 1 | 1 | 0% | 2,043 | 3,467 | +70% | 0 | 0 | — |
case-21 | pass→pass | 11,550 | 6,681 | -42% | 1 | 1 | 0% | 2,017 | 3,214 | +59% | 0 | 0 | — |
case-22 | pass→pass | 13,887 | 12,178 | -12% | 1 | 1 | 0% | 2,397 | 3,975 | +66% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.