Amass logo
Build AssistantDocumentationAPI ReferenceApp gallery
Sign inSign up

Search documentation

Search the documentation by keyword

Getting Started
  • Overview
  • Quickstart
  • Authentication
  • Roadmap
  • Pricing
For AI Agents
  • LLM Quick Reference
Amass Cores
  • BiomedCore
  • DrugCore
  • GeneCore
  • PatentCore
  • RegulatoryCore
  • TrialCore
Examples
  • Starter Agent
  • API Workflows
  • Amass SKILL.md

    BiomedCore

    BiomedCore provides access to 43M+ biomedical citations sourced from PubMed and PubMed Central, enriched with citation counts, journal quality indicators, and structured metadata. It also covers conference abstracts from society meetings, returned alongside journal articles and identified by Conference in publicationTypes. Updated daily.


    Endpoints

    Search — GET /v1/cores/biomedcore/records

    Search across biomedical literature by text, with optional filters.

    Shell
    curl "https://api.amass.tech/api/v1/cores/biomedcore/records?query=CAR-T+therapy&limit=5" \
      -H "Authorization: Bearer amass_YOUR_KEY"

    Parameters:

    NameRequiredDefaultDescription
    queryyes—Search text (titles, abstracts, fulltext, metadata)
    limitno20Results to return (1–300)
    includeno—Optional fields to return. Repeat for multiple: fulltext, authorsMetadata, meshIds, substanceIds, referencesTrialCore, references, citedBy
    minPublicationDateno—ISO date, e.g. 2023-01-01
    maxPublicationDateno—ISO date, e.g. 2026-01-01
    minLastUpdateDateno—ISO date. Earliest date Amass last wrote the record. Records with no such date are excluded
    maxLastUpdateDateno—ISO date. Latest date Amass last wrote the record
    minCreateDateno—ISO date. When Amass ingested the record, not when it was published. Records with no create date are excluded
    minCitationCountno—Integer (0–100,000)
    minJournalQualityJufono—0, 1, 2, or 3 (see Journal Quality Tiers)
    isRetractedno—true or false
    authorOrcidsno—Match ANY of these ORCIDs. Accepts bare (0000-0003-1234-5678) or URL form (https://orcid.org/0000-0003-1234-5678); a value that is not an ORCID is a 400, not an empty result. Repeat the param for multiple values. See Author & institution filters.
    authorNamesno—Match ANY of these author names. Free-text token match (no prefix expansion). A two-part name must be carried by a single author, in either order; the citation form (Liu DR) additionally matches the record's own LastName Initials value. Repeat the param for multiple values.
    institutionRorsno—Match ANY of these ROR identifiers. Accepts bare (03vek6s52) or URL form (https://ror.org/03vek6s52); a value that is not a ROR ID is a 400, not an empty result. Repeat the param for multiple values.
    institutionNamesno—Match ANY of these institution names. Free-text token match against both the normalized institution name and the affiliation line printed on the paper. Repeat the param for multiple values.

    Covering a long window

    Search returns a ranked top-K, so a wide lastUpdateDate window can truncate silently. Request long spans in slices — minLastUpdateDate=2026-08-01&maxLastUpdateDate=2026-08-07, then the next week — and union the results. For complete coverage with no truncation, use /changes.

    Example with filters — highly cited papers in top journals from 2022 onward:

    Shell
    curl "https://api.amass.tech/api/v1/cores/biomedcore/records\
    ?query=immunotherapy\
    &minPublicationDate=2022-01-01\
    &minCitationCount=30\
    &minJournalQualityJufo=2" \
      -H "Authorization: Bearer amass_YOUR_KEY"

    Author & institution filters

    The four filters authorOrcids, authorNames, institutionRors, and institutionNames follow the same encoding and combine with the same rules.

    • Within one filter — OR. Repeat the param to match any of the listed values: ?authorOrcids=0000-0001-...&authorOrcids=0000-0002-... returns papers authored by either ORCID.
    • Across filters — AND. Mixing different filters narrows the result: ?authorNames=Hassabis&institutionNames=DeepMind returns papers that have a Hassabis author and a DeepMind affiliation (not necessarily the same author/affiliation pair).
    • ORCIDs and RORs accept bare or URL form. 0000-0002-2401-5691 and https://orcid.org/0000-0002-2401-5691 match the same author; 03vek6s52 and https://ror.org/03vek6s52 match the same institution. These two params take identifiers only: a value that is not one — a name, say — returns 400 VALIDATION_ERROR rather than an empty page. Names belong in authorNames and institutionNames.
    • Institution names match the affiliation line too. Not every record carries a normalized institution name — that comes from an enrichment pass that does not reach every paper, and it is sparser the further back you go. institutionNames therefore also matches the raw affiliation text as printed on the paper, so smaller organisations, companies, and older records stay reachable. Matching is still token-based, so Moffitt finds Moffitt Cancer Center.
    • Author names match in several forms. Liu DR, David R Liu, Liu and Liu, David are all accepted. Any two-part name — the citation form included — is matched against a single author on the paper, in either order and ignoring any middle name or initial between the two parts. So David Liu finds a paper by David R. Liu, and Liu DR finds one by David R. Liu, but neither matches a paper whose authors are David Chen and Amy Liu. The citation form is additionally matched against the record's own LastName Initials value. A surname alone is the widest match and the one to fall back to, with query for context when the surname is common.
    Shell
    # Papers by one of two ORCIDs at a specific institution (ROR), since 2022
    curl "https://api.amass.tech/api/v1/cores/biomedcore/records\
    ?query=protein+structure+prediction\
    &authorOrcids=0000-0002-2401-5691\
    &authorOrcids=0000-0001-9282-0298\
    &institutionRors=00971b260\
    &minPublicationDate=2022-01-01\
    &include=authorsMetadata\
    &limit=20" \
      -H "Authorization: Bearer amass_YOUR_KEY"

    Response:

    JSON
    { "data": [ { "amassId": "AMBC_...", "title": "...", "..." }, ... ] }

    Get by ID — GET /v1/cores/biomedcore/records/{amassId}

    Fetch a single record by its Amass ID.

    Shell
    curl "https://api.amass.tech/api/v1/cores/biomedcore/records/AMBC_abc123\
    ?include=authorsMetadata" \
      -H "Authorization: Bearer amass_YOUR_KEY"

    Response:

    JSON
    { "data": { "amassId": "AMBC_...", "title": "...", "..." } }

    Returns 404 if not found.


    Lookup — POST /v1/cores/biomedcore/records/lookup

    Convert PMIDs or DOIs to Amass IDs in batch. Each item must contain exactly one identifier — either pmid or doi, not both.

    DOI matching is case-insensitive, as the DOI specification requires: 10.1523/JNEUROSCI.3402-08.2008 and 10.1523/jneurosci.3402-08.2008 resolve to the same record. The doi a record returns is the publisher's deposited spelling, which is not always lowercase.

    Shell
    curl -X POST "https://api.amass.tech/api/v1/cores/biomedcore/records/lookup" \
      -H "Authorization: Bearer amass_YOUR_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "items": [
          { "pmid": "38123456" },
          { "doi": "10.1038/s41586-024-00001-x" }
        ]
      }'

    Response:

    JSON
    {
      "data": [
        {
          "input": { "pmid": "38123456" },
          "amassIds": ["AMBC_abc123"]
        },
        {
          "input": { "doi": "10.1038/s41586-024-00001-x" },
          "error": { "code": "NOT_FOUND", "message": "No matching record found" }
        }
      ]
    }

    Individual items can fail without failing the whole request. Always check each item for an error field.

    Changes — GET /v1/cores/biomedcore/changes

    A resumable feed of publications that were created, updated, or deleted, for keeping a local copy in sync without re-reading the corpus. Read updateType to tell them apart.

    Shell
    curl "https://api.amass.tech/api/v1/cores/biomedcore/changes\
    ?since=2026-01-01\
    &limit=500" \
      -H "Authorization: Bearer amass_YOUR_KEY"

    Parameters:

    NameRequiredDefaultDescription
    sinceyes—ISO date — start of the change window, inclusive
    limitno100Items per page (1–1000)
    cursorno—Opaque cursor from a previous response's nextCursor
    amassIdno—Repeat to follow only these records (max 100). Omit for the whole corpus — see Watching a specific set of publications

    Response:

    JSON
    {
      "data": [
        {
          "amassId": "AMBC_abc123",
          "updateType": "updated",
          "updateDate": "2026-01-14",
          "createDate": "2024-03-02"
        },
        {
          "amassId": "AMBC_def456",
          "updateType": "deleted",
          "updateDate": "2026-01-15",
          "createDate": null
        }
      ],
      "nextCursor": "eyJ2IjoxLCJ..."
    }

    Response fields:

    FieldTypeDescription
    amassIdstringThe record that changed
    updateTypestringcreated, updated, or deleted
    updateDatestringThe change that caused this delivery. For a deletion, the date the removal was observed
    createDatestring | nullWhen the record entered Amass. Always null on a deletion
    nextCursorstring | nullPass back as cursor. null means caught up through the last fully-ingested day

    The feed returns identifiers and change metadata, not publication content — fetch the records you care about with Get by ID once you know which ones moved.

    Paging. Pass the nextCursor from each response back as cursor on the next request. Keep going until nextCursor is null — that is the only signal you are caught up. A page can hold fewer than limit items and still have a cursor: limit bounds the rows the feed scans, not the items it returns, so both a day boundary and a record that changed more than once on one day leave a page short.

    Delivery is at-least-once. The same amassId can appear more than once across pages, so apply the feed as an upsert rather than a counter.

    created describes the delivery, not the record. It means this is the first time the feed has handed you that publication. One that entered Amass inside your window and then changed again — fulltext arriving, a citation count refreshing — arrives once, as updated. To tell genuinely new publications from long-standing ones, compare createDate against your window rather than branching on updateType.

    The most recent day is withheld. A day is only served once ingestion for it has finished, so an in-progress run cannot hand you a half-written day and leave the rest stranded behind your cursor. In practice a change becomes visible about a day after it lands.

    Resume from a day or two before your last since, not from "now". The feed serves everything from since up to the last fully-ingested day, so nextCursor: null means you have that — not that you are caught up to the current date. Advancing your next since to today therefore steps over the withheld day and never comes back for it. Store the since you asked for and re-ask from slightly before it: delivery is at-least-once and you upsert by amassId, so the overlap costs a page and nothing else.

    There is deliberately no until and no throughDate on this endpoint. Both existed in earlier drafts and both read as a second, competing resume token next to the cursor. If your integration needs an explicit end bound or a server-published watermark, tell us — they are held back pending that demand, not removed on principle.

    Watching a specific set of publications

    If you track a fixed set of papers rather than a mirror of the corpus — the references behind a living review, say — pass amassId, repeated, up to 100 per request:

    Shell
    curl "https://api.amass.tech/api/v1/cores/biomedcore/changes\
    ?since=2026-01-01\
    &amassId=AMBC_abc123\
    &amassId=AMBC_def456" \
      -H "Authorization: Bearer amass_YOUR_KEY"

    Everything else is unchanged — same envelope, same updateType, same cursor, same price — and deletions still arrive, so a withdrawn citation in your set still reaches you. On this Core scoping is also the practical answer to the volume warning above: a watchlist is unaffected by a corpus-wide citation refresh unless one of your records moved.

    Repeat the parameter once per paper. A comma-joined list — amassId=AMBC_abc123,AMBC_def456 — is read as one identifier and rejected.

    Two consequences worth knowing:

    • A scoped page can never hold more than 100 distinct records, so limit above 100 does nothing.
    • A cursor is bound to the amassId set it was issued for. Change the set while paging and the cursor is rejected with a 400 — see Changing the watchlist.

    Records whose Amass ID is malformed, belongs to another Core, or is sent as an empty value are rejected outright rather than skipped. A silently dropped id would leave you believing a paper is being watched when it is not.

    Watching more than 100 publications

    Split the watchlist into chunks of 100 and sweep each chunk independently.

    Chunk the same way on every run. Each chunk carries its own cursor, and a cursor is bound to the exact set of ids that issued it, so re-partitioning between runs invalidates every cursor at once. Sort by amassId and slice, or derive the chunk from a stable property of the record. Do not chunk by iteration order over a set or hash map.

    Chunking stably also makes adding a paper a change to one chunk rather than to all of them.

    Changing the watchlist

    A cursor is bound to the amassId set that issued it, so changing that set mid-sweep gets you a 400 on the next request.

    This matters less than it first appears, because cursors are sweep-local. What you persist between runs is your own since, not the cursor; the next sweep starts from since with no cursor at all. A reference list edited between sweeps therefore costs nothing.

    That leaves editing mid-sweep, which you can avoid entirely by paging to nextCursor: null before applying changes — a scoped sweep usually takes one or two requests. If you do have to edit mid-sweep, the recovery depends on which direction it went:

    • Removed a paper. Nothing is missing. Restart from the since you last stored. Re-asking an overlapping window is safe and cheap, because delivery is at-least-once and you upsert by amassId anyway.
    • Added a paper. The new paper needs the full window regardless, so resuming would not have helped it. Either restart the sweep, or run the added ids as their own request from whichever date you want their history to begin.

    A retraction watch is the natural use: retracted papers stay indexed and arrive as updated with isRetracted: true, so scoping the feed to the papers you cite tells you when your evidence base decays.

    Deletions

    Deletions arrive on this feed as updateType: "deleted", under the same cursor as every other change.

    They are deliberately not a separate feed. A second feed would mean a second cursor over the same records, and two cursors can disagree: a record deleted on one day and re-created on a later one is applied in the wrong order by a consumer that is further along one feed than the other — and nothing would ever re-deliver it. One feed, one cursor, events in date order.

    A retraction is not a deletion. Retracted papers stay indexed — they arrive as updateType: "updated" with isRetracted set to true.

    The feed reports current state, not a complete event log. A record removed more than once reports only its most recent removal.


    Record Schema

    Default fields (always returned)

    FieldTypeDescription
    amassIdstringUnique Amass identifier (AMBC_...)
    pmidstring | nullPubMed ID
    pmcidstring | nullPubMed Central ID
    doistring | nullDigital Object Identifier, as the publisher deposited it. Lookups match case-insensitively
    urlstring | nullLink to the source of this record. The target may change over time; use the identifier fields to build links to specific external systems
    titlestring | nullArticle title
    abstractstring | nullArticle abstract
    authorsstring[]Author names (e.g. ["Smith J", "Doe A"])
    journalstring | nullJournal name
    issnstring | nullJournal ISSN
    volumeIssuestring | nullVolume and issue
    publicationDatestring | nullISO date: the electronic publication date when the source record has one, otherwise the journal issue date
    lastUpdateDatestring | nullISO date Amass last wrote the record
    createDatestring | nullISO date the record entered Amass. Null for records ingested before Amass tracked this
    publicationTypesstring[]NLM MeSH publication types, e.g. ["Journal Article", "Review"]. Records sourced from a conference abstract also carry the Amass-assigned value Conference, appended last (see Conference abstracts)
    languagestring | nullLanguage code (e.g. eng)
    citationCountnumber | nullCitation count
    journalQualityJufonumber | nullJuFo journal quality level (0–3, see below)
    meshTermsstring[]MeSH terms
    keywordsstring[]Author keywords
    substancesstring[]Chemical substances
    hasFulltextboolean | nullWhether full text is available
    isRetractedboolean | nullWhether article is retracted

    Optional fields

    Request these with the include parameter. Repeat for multiple: ?include=fulltext&include=authorsMetadata

    FieldInclude valueTypeDescription
    fulltextfulltextstring | nullFull article text. Large — only request when needed.
    authorsMetadataauthorsMetadataobject[]Structured author details (see below)
    meshIdsmeshIdsstring[]MeSH descriptor identifiers
    substanceIdssubstanceIdsstring[]Chemical substance identifiers
    referencesTrialCorereferencesTrialCorestring[]Cross-core link → TrialCore. Amass IDs of TrialCore records (clinical trials) referenced by this publication
    referencesreferencesstring[]Intra-core link within BiomedCore. Amass IDs of other BiomedCore records (publications) referenced by this publication
    citedBycitedBystring[]Intra-core link within BiomedCore. Amass IDs of other BiomedCore records (publications) that cite this publication

    Reference field semantics

    ╔══════════════════ BiomedCore (publications) ══════════════════╗
    ║                                                                ║
    ║   AMBC_aaa ─cites─┐                       ┌─► AMBC_p001        ║
    ║                   │                       ├─► AMBC_p002        ║
    ║                   │                       ├─► AMBC_p003        ║
    ║                   │   ┌──────────┐        │                    ║
    ║                   ├──►│  AMBC_X  │────────┤        ⋮           ║
    ║                   │   └──────────┘        │                    ║
    ║                   │                       ├─► AMBC_p050        ║
    ║                   │                       ├─► AMBC_p051        ║
    ║   AMBC_bbb ─cites─┘                       └─► AMBC_p052        ║
    ║                                                                ║
    ║   AMBC_X.citedBy    = [AMBC_aaa, AMBC_bbb]           ← 2 IDs   ║
    ║   AMBC_X.references = [AMBC_p001, …, AMBC_p052]      ← 52 IDs  ║
    ║                                                                ║
    ║         ── intra-core: arrows stay within BiomedCore ──        ║
    ║                                                                ║
    ╚════════════════════════════════════════════════════════════════╝
                                    │
                                    │   AMBC_X.referencesTrialCore = [AMTC_xxx]
                                    │   ── cross-core link to TrialCore ──
                                    ▼
    ╔══════════════════ TrialCore (clinical trials) ════════════════╗
    ║                                                                ║
    ║                           AMTC_xxx                             ║
    ║                                                                ║
    ╚════════════════════════════════════════════════════════════════╝
    • Intra-core arrows stay inside BiomedCore — target IDs start with AMBC_. Both fan-in (citedBy) and fan-out (references) live in the same Core.
    • Cross-core arrow leaves BiomedCore for TrialCore — target IDs start with AMTC_. Only referencesTrialCore crosses the Core boundary.

    authorsMetadata shape

    JSON
    {
      "name": "Smith J",
      "nameRaw": "John Smith",
      "orcid": "0000-0001-2345-6789",
      "position": 0,
      "affiliations": [
        {
          "name": "Harvard Medical School",
          "nameRaw": "Harvard Medical School, Boston, MA, USA",
          "ror": "03vek6s52",
          "countryCode": "US"
        }
      ]
    }

    Conference abstracts

    BiomedCore includes abstracts presented at conferences alongside journal articles. They are searched and returned the same way, and are identified by the value Conference in publicationTypes:

    JSON
    {
      "title": "Pembrolizumab plus chemotherapy in advanced NSCLC",
      "journal": "Journal of Clinical Oncology",
      "publicationTypes": ["Conference"]
    }

    Conference is not a MeSH publication type. It is assigned by Amass, and it is deliberately outside NLM's vocabulary so the two cannot be confused. It is always appended last, and NLM's values are never removed or reordered.

    Some conference abstracts are also indexed in PubMed under their own PMID. Those are returned as a single record rather than two: the article's PubMed metadata (PMID, MeSH terms, NLM publication types) is kept, and Conference is appended to it. So a record carrying both Journal Article and Conference is one publication known through both routes, not a duplicate.

    On those records Conference is appended only when PubMed's own metadata agrees — an NLM conference type such as Congress, or a supplement Amass has attributed to a named conference — and never to an item a conference proceeding cannot be, such as an Editorial. Where PubMed describes the record as an ordinary article and nothing corroborates the conference, it is returned exactly as PubMed describes it. A record with a PMID and no Conference is therefore not proof that the work was never presented at one.

    journalQualityJufo on a conference abstract is the rating of the journal that published the supplement it appeared in — ESMO's abstracts are in Annals of Oncology, ASCO's in the Journal of Clinical Oncology — so minJournalQualityJufo applies to them as it does to an article. Use publicationTypes to tell the two apart.


    Journal Quality Tiers

    Journal quality is based on Publication Forum (JuFo), an openly published classification of publication channels.

    LevelMeaning
    3Highest quality — represents the highest level in the discipline with extremely consistent impact
    2Domain leading — limited number of journals, conferences, and publishers of the highest level
    1Peer reviewed — peer-reviewed channels specialised in scientific research with an expert editorial board
    0Low quality — evaluated but does not meet all Level 1 criteria
    nullNot evaluated — publication channel has not been evaluated

    See Also

    • TrialCore — Clinical trial records
    • DrugCore — Drug and molecule records
    • RegulatoryCore — FDA & EMA drug authorizations
    • GeneCore — Gene records
    • API Workflows — See BiomedCore in action: literature reviews, scientific maturity assessment, investigator discovery
    • Overview — Errors and rate limits
    • Quickstart — Getting started with examples