# Beacon v2 Genomics Extractor (`datamule/beacon-v2-genomics-extractor`) Actor

Point at ANY GA4GH Beacon v2 endpoint (Progenetix, Cancer Cell Lines, ELIXIR/BSC) and pull biosamples, individuals, genomic variants, cohorts, datasets or filtering terms into clean flat rows. Auto-detects skip/limit paging, keeps the full record in \_raw. Pay per record.

- **URL**: https://apify.com/datamule/beacon-v2-genomics-extractor.md
- **Developed by:** [Datamule](https://apify.com/datamule) (community)
- **Categories:** Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Beacon v2 Genomics Extractor

Point at **ANY GA4GH Beacon v2 endpoint** and pull genomics-discovery data into
clean, flat, tabular rows — no per-resource scraper. GA4GH Beacon v2 is the global
standard for **federated genomics discovery**: cancer-genomics resources, national
biobanks, reference-population projects and ELIXIR nodes all expose the **same wire
grammar**, and this one Actor speaks it universally.

### Why one Actor works everywhere

Every conformant Beacon v2 endpoint answers with the same envelope:

```
GET {base}/{endpoint}?[filters=…][&params][&skip=&limit=]
  → { meta:{ apiVersion, beaconId, returnedGranularity, returnedSchemas },
      responseSummary:{ exists, numTotalResults },
      response:{ … one of the containers below … } }
```

The Actor routes on whichever container the beacon returns, so it handles every
Beacon entry type with one code path:

| Endpoint(s) | Container | One row per… |
|---|---|---|
| `biosamples`, `individuals`, `g_variants`, `analyses`, `runs` | `response.resultSets[].results[]` | matched record |
| `cohorts`, `datasets` | `response.collections[]` | collection |
| `filtering_terms` | `response.filteringTerms[]` | queryable ontology term |
| `entry_types`, `configuration` | `response.entryTypes{}` | advertised entry type |
| `info`, `map`, `service-info` | singleton object | the object |

### The pagination-semantics auto-detect (why it's genuinely universal)

Beacon v2 pages record endpoints with `skip` + `limit`, but independent operator
families **disagree on what `skip` counts** — and a runner that hard-codes either
model silently loses or duplicates data on the other:

- **ELIXIR / BSC** (`beacon-python`): `skip` is a **raw record offset** (`skip=1`
  shifts the window by one record).
- **bycon** (Progenetix, Cancer Cell Lines): `skip` is a **page index** (`skip=1`
  is the disjoint next page; effective offset = `skip × limit`).

The Actor reads page 0, then — only if more records exist — sends one `skip=1`
probe and **classifies the mode** from the returned ids. Every row is then deduped
by `(resultSetId, id)`, so an overlap never double-emits and a server that ignores
`skip` terminates cleanly instead of looping. Verified live against all three
families.

### Input

| Field | Type | Notes |
|---|---|---|
| `sources` | array (**required**) | Beacon v2 base URLs, e.g. `https://progenetix.org/beacon`, `https://beacons.bsc.es/beacon/v2.0.0`. Point at the base — don't append an endpoint. |
| `endpoint` | select | `biosamples` (default), `individuals`, `g_variants`, `analyses`, `runs`, `cohorts`, `datasets`, `filtering_terms`, `info`, `configuration`, `entry_types`, `map`. |
| `filters` | array | CURIE ontology IDs (e.g. `NCIT:C7376`). Some beacons (bycon family) **require** a filter for record endpoints — use `filtering_terms` to discover valid IDs. |
| `requestParameters` | object | Extra Beacon query params. For `g_variants`: `{ "referenceName": "9", "start": "21000000", "end": "22000000", "variantType": "DEL" }`. |
| `granularity` | select | `record` (default), `count`, `boolean`, `aggregated`. |
| `maxRecords` | integer | Total row cap across all sources. Default 1000. |
| `bearerToken` | string (secret) | Optional OAuth2 bearer for auth-gated beacons. Never required for public beacons; never logged. |
| `extraHeaders` | object | Optional extra request headers. |

### Output

One flat row per record/collection/term, with `id`, `label`, `name`, `type`,
`count`, full provenance (`_source`, `_beaconId`, `_apiVersion`, `_endpoint`,
`_container`, `_entryType`, `_beaconSoftware`, `_resultSetId`, `_numTotalResults`),
and the complete original record losslessly in `_raw`.

### Honesty

- A top-level Beacon `error` envelope (e.g. HTTP 422 `no valid query`) is surfaced
  as a real error and **skipped-with-warning**, never emitted as a fabricated row.
- A valid-but-empty response is a real 0-result, exit 0.
- A run where **every** source fails exits non-zero (91) so nothing broken ships.

### Pricing

Pay-per-event: **one `record` charge per emitted row.**

### Notes

Beacon v2 exists precisely to share genomics **discovery** (counts, boolean
existence, and record-level metadata over consented cohorts) *without* moving
patient-level genomes. This is a generic protocol client; auth is optional and only
needed for beacons that expose protected datasets.

# Actor input Schema

## `sources` (type: `array`):

One or more GA4GH Beacon v2 base/root URLs. Examples: https://progenetix.org/beacon (Progenetix), https://cancercelllines.org/beacon (Cancer Cell Lines), https://beacons.bsc.es/beacon/v2.0.0 (ELIXIR Spain / BSC). Point at the beacon BASE — do NOT append an endpoint like /biosamples.

## `endpoint` (type: `string`):

Which Beacon v2 endpoint to query. Record endpoints (biosamples, individuals, g\_variants, analyses, runs) emit one row per matched record and are paginated. Collection endpoints (cohorts, datasets) emit one row per collection. filtering\_terms lists a beacon's queryable ontology terms. info / configuration / entry\_types / map are single-object discovery maps of what a beacon exposes.

## `filters` (type: `array`):

Optional Beacon filtering terms — CURIE-style ontology IDs applied to record queries, e.g. NCIT:C7376 (a cancer type), or an ICD-O / UBERON / EFO term. Some beacons (the bycon family: Progenetix, Cancer Cell Lines) REQUIRE at least one filter to return biosample/individual records (an unfiltered query returns HTTP 422 "no valid query"). Use filtering\_terms mode to discover valid IDs for a beacon. Leave empty for beacons that serve records unfiltered (e.g. ELIXIR/BSC).

## `requestParameters` (type: `object`):

Optional extra Beacon query parameters as a JSON object, applied to every request. For g\_variants (genomic variant) queries the range model uses e.g. {"referenceName": "9", "start": "21000000", "end": "22000000", "variantType": "DEL"}. The paging skip/limit and requestedGranularity are managed for you.

## `granularity` (type: `string`):

Beacon requestedGranularity. "record" (default) returns full records; "count" / "boolean" return only aggregate discovery answers (numTotalResults / exists) with no patient-level data — many beacons only permit these for protected datasets. "aggregated" returns summary counts.

## `maxRecords` (type: `integer`):

Maximum total number of rows to emit across all sources. skip/limit paging is followed until this cap is reached, so a huge beacon never runs forever. Each returned row is one billable event. Default 1000.

## `bearerToken` (type: `string`):

Optional OAuth2 bearer token for auth-gated beacons that expose protected datasets. Sent as Authorization: Bearer \*\*\*. NOT required for public beacons (Progenetix, Cancer Cell Lines, ELIXIR/BSC) — leave empty. Never logged.

## `extraHeaders` (type: `object`):

Optional extra HTTP headers to send with every request, as a JSON object, e.g. an API-key header a specific beacon node requires. Leave empty for public beacons.

## Actor input object example

```json
{
  "sources": [
    "https://beacons.bsc.es/beacon/v2.0.0"
  ],
  "endpoint": "biosamples",
  "granularity": "record",
  "maxRecords": 1000
}
```

# Actor output Schema

## `results` (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 = {
    "sources": [
        "https://beacons.bsc.es/beacon/v2.0.0"
    ],
    "maxRecords": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("datamule/beacon-v2-genomics-extractor").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 = {
    "sources": ["https://beacons.bsc.es/beacon/v2.0.0"],
    "maxRecords": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("datamule/beacon-v2-genomics-extractor").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 '{
  "sources": [
    "https://beacons.bsc.es/beacon/v2.0.0"
  ],
  "maxRecords": 1000
}' |
apify call datamule/beacon-v2-genomics-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=datamule/beacon-v2-genomics-extractor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/JarwzkgiZkANDH6Vh/builds/kt6LrHWs6RwQBdB3d/openapi.json
