Dataverse Integration
No research platform gets to start from zero. Datasets already live in Dataverse installations, carry DOIs, and are cited by papers that will never be updated. A system that asks researchers to abandon that would not be adopted. Bio-DID-Seq bridges instead. A dataset keeps its Dataverse record and its DOI, and gains a DID, sealed storage on IPFS, and a place in the knowledge graph alongside them.
The bridge is two things.
- A Dataverse proxy. The API forwards dataset operations to a Dataverse installation using your Dataverse API token, so the platform never holds a credential for your repository.
- A DID to DOI link. A
did:biorecord can carry a DOI. The DID document then points athttps://doi.org/<doi>through a service entry, and the public metadata document carries the DOI, so discovery works from either identifier.
There is no background synchronisation between the two systems. Every Dataverse change is a call you make.
Two credentials, two headers
Every Dataverse route takes your Ekayana session token in Authorization and your Dataverse API token in x-dataverse-token. The token is used for the one request and not stored. x-dataverse-server selects the installation. demo is https://demo.dataverse.org and the default. harvard is https://dataverse.harvard.edu.
API reference
List your collections
curl https://api.ekayana.io/api/dataverse/collections \
-H "Authorization: Bearer $TOKEN" \
-H "x-dataverse-token: $DATAVERSE_TOKEN" -H "x-dataverse-server: harvard"{ "count": 1, "dataverses": [{ "id": 1234, "alias": "research-lab", "name": "Research Lab",
"description": "...", "affiliation": "..." }] }Create a dataset
curl -X POST https://api.ekayana.io/api/dataverse/dataset \
-H "Authorization: Bearer $TOKEN" \
-H "x-dataverse-token: $DATAVERSE_TOKEN" -H "x-dataverse-server: harvard" \
-H "Content-Type: application/json" \
-d '{
"title": "CRISPR-Cas9 Gene Editing Dataset",
"description": "Comprehensive dataset from CRISPR experiments",
"authors": ["Jane Smith"],
"keywords": ["CRISPR", "gene editing", "genomics"],
"subjects": ["Medicine, Health and Life Sciences"],
"dataverse_alias": "research-lab"
}'{ "id": "12345", "persistent_id": "doi:10.7910/DVN/EXAMPLE" }title, of 1 to 500 characters, and description are required. When dataverse_alias is omitted the dataset is created in the first collection your token can see. When subjects is empty, "Medicine, Health and Life Sciences" is used. The dataset contact is your account's username and email, because Dataverse requires a contact. The dataset is created as a draft.
Upload a file
The dataset's persistent identifier is part of the path, URL encoded, and the multipart body carries the file plus an optional description.
curl -X POST "https://api.ekayana.io/api/dataverse/dataset/file/doi%3A10.7910%2FDVN%2FEXAMPLE" \
-H "Authorization: Bearer $TOKEN" \
-H "x-dataverse-token: $DATAVERSE_TOKEN" -H "x-dataverse-server: harvard" \
-F "file=@reads.fastq.gz" \
-F "description=Raw sequencing reads"{ "file_id": "987654", "message": "file uploaded" }The file goes to Dataverse only. To keep a sealed copy on IPFS as well, upload it through POST /api/upload too. The two copies are independent.
Update metadata
PUT /api/dataverse/dataset/metadata takes persistent_id and any of title, description, authors, keywords, subjects. Fields you omit are read from the current draft first, so a partial update does not blank the rest.
Publish
curl -X POST https://api.ekayana.io/api/dataverse/dataset/publish \
-H "Authorization: Bearer $TOKEN" \
-H "x-dataverse-token: $DATAVERSE_TOKEN" -H "x-dataverse-server: harvard" \
-H "Content-Type: application/json" \
-d '{ "persistent_id": "doi:10.7910/DVN/EXAMPLE" }'{ "persistent_id": "doi:10.7910/DVN/EXAMPLE", "message": "dataset published" }Publishing registers the DOI on the Dataverse side, as a major version.
Read
| Operation | Endpoint |
|---|---|
| Dataset record | GET /api/dataverse/dataset/{persistent_id} |
| Its files | GET /api/dataverse/dataset/{persistent_id}/files |
| Its versions | GET /api/dataverse/dataset/{persistent_id}/versions |
| Its citation | GET /api/dataverse/dataset/{persistent_id}/citation |
| Search | GET /api/dataverse/search?q=&type=&per_page=&start=&subtree= |
| Download a file | GET /api/dataverse/file/{file_id} |
Reads of published datasets work without a Dataverse token. Drafts and restricted files need one.
Link a DID to the DOI
The link lives on the DID record, and the account that owns the DID sets it.
curl -X POST "https://api.ekayana.io/api/did/did:bio:devnet:7Qm3.../dataverse" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "dataverse_doi": "doi:10.7910/DVN/EXAMPLE" }'{ "message": "DID linked to Dataverse dataset", "did": "did:bio:devnet:7Qm3...", "dataverse_doi": "10.7910/DVN/EXAMPLE" }The DOI is normalised, with doi: and https://doi.org/ prefixes stripped, and must look like 10.xxxx/yyyy. Two things happen.
- The record stores the DOI and the public metadata document is rewritten with a
doifield and repinned. - The DID document gains a service entry when the wallet next runs a
syncworkflow. The entry is#dataverse, of typeDataverseRepository, with the endpointhttps://doi.org/10.7910/DVN/EXAMPLE. Until then the record showspending_sync: true.
Nothing is written to Dataverse by this call. If you want the DID to appear in the Dataverse record, add it to the dataset's metadata yourself, for example as a related identifier.
Recommended practice
Link every DID to its DOI, so discovery works from either direction. The link is one call. Keep a sealed copy on IPFS even for data that lives in Dataverse. It is the copy whose availability does not depend on one institution's uptime, and it is the one a pass can grant access to. Register papers with their DOI so the knowledge graph can fill in what it knows. Put an IPNS name in front of any dataset you expect to revise, so citations to old versions and readers of new ones both stay right.