Skill: agents365-ai/zenodo-skill (version 1.0.0)

--- name: zenodo-skill description: Use whenever the user mentions Zenodo, depositing or publishing research artifacts (datasets, software, papers, posters) to Zenodo, minting a DOI for a dataset/code release, uploading files to a Zenodo record, creating a new version of a Zenodo deposit, or searching Zenodo records. Covers the full Zenodo REST API workflow — create deposition, upload files via the bucket API, set metadata, publish, version, and search — for both production (zenodo.org) and sandbox (sandbox.zenodo.org). license: MIT homepage: https://github.com/Agents365-ai/zenodo-skill platforms: [macos, linux, windows] metadata: {"openclaw":{"requires":{"bins":["curl"],"env":["ZENODO_TOKEN"]},"emoji":"📦","os":["darwin","linux","win32"]},"hermes":{"tags":["zenodo","doi","dataset","research-data","open-science","preprint","publishing"],"category":"research","requires_tools":["curl"],"related_skills":["zotero-manager","semanticscholar-skill"]},"author":"Agents365-ai","version":"1.0.0"} --- # Zenodo Skill Interact with the [Zenodo REST API](https://developers.zenodo.org) to deposit, publish, version, and search research artifacts. Zenodo issues a citable DOI for every published record. ## When to use - User wants to upload a dataset, code release, paper, poster, or other artifact to Zenodo - User wants a DOI for a research output - User wants to update an existing deposit or publish a new version - User wants to search Zenodo for records ## Setup Two environments — pick one and stick with it during a session: | Env | Base URL | Token page | |---|---|---| | Production | `https://zenodo.org/api` | https://zenodo.org/account/settings/applications/tokens/new/ | | Sandbox (testing) | `https://sandbox.zenodo.org/api` | https://sandbox.zenodo.org/account/settings/applications/tokens/new/ | Sandbox accounts/tokens are **separate** from production. Always test new workflows in sandbox first — published production records cannot be deleted. Required token scopes: `deposit:write` and `deposit:actions`. Export the token before running commands: ```bash export ZENODO_TOKEN=... # never inline the token in commands you show the user export ZENODO_BASE=https://sandbox.zenodo.org/api # or https://zenodo.org/api ``` If `ZENODO_TOKEN` is unset, ask the user for it (and which environment) before proceeding. ## Core workflow: deposit a new artifact The deposit lifecycle is **create → upload files → set metadata → publish**. Each step is a separate API call; do them in order. ### 1. Create an empty deposition ```bash curl -sS -X POST "$ZENODO_BASE/deposit/depositions" \ -H "Authorization: Bearer $ZENODO_TOKEN" \ -H "Content-Type: application/json" \ -d '{}' ``` The response JSON contains two things you need to remember: - `id` — the deposition id, used for metadata/publish/version actions - `links.bucket` — the bucket URL for file uploads (new files API) Capture them, e.g. with `jq`: ```bash RESP=$(curl -sS -X POST "$ZENODO_BASE/deposit/depositions" \ -H "Authorization: Bearer $ZENODO_TOKEN" -H "Content-Type: application/json" -d '{}') DEPOSIT_ID=$(echo "$RESP" | jq -r .id) BUCKET=$(echo "$RESP" | jq -r .links.bucket) ``` ### 2. Upload files (bucket API — preferred) The bucket API supports up to 50 GB total / 100 files per record. Use `--upload-file` (HTTP PUT) — **not** multipart form upload. The filename in the URL is what shows up on the record. ```bash curl -sS --upload-file ./data.csv \ -H "Authorization: Bearer $ZENODO_TOKEN" \ "$BUCKET/data.csv" ``` Repeat per file. For many files, loop in shell. The legacy `/files` multipart endpoint is capped at 100 MB/file — avoid it. ### 3. Set metadata Metadata goes via `PUT` on the deposition. **Required** fields: `upload_type`, `title`, `creators`, `description`. See `references/metadata.md` for the full schema, allowed `upload_type` values, license codes, and conditional fields (e.g. `publication_type`, `embargo_date`). Minimal example: ```bash curl -sS -X PUT "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID" \ -H "Authorization: Bearer $ZENODO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "title": "My dataset", "upload_type": "dataset", "description": "<p>A short description (HTML allowed).</p>", "creators": [{"name": "Doe, Jane", "affiliation": "Example Univ.", "orcid": "0000-0002-1825-0097"}] } }' ``` Read the response — Zenodo validates here and returns 400 with field-level errors if anything is missing or malformed. Fix and retry before publishing. ### 4. Publish **Publishing is irreversible on production** (you can edit metadata later but cannot remove files or delete the record). Confirm with the user before this step unless they're on sandbox. ```bash curl -sS -X POST "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID/actions/publish" \ -H "Authorization: Bearer $ZENODO_TOKEN" ``` The response contains `doi` and `links.record_html` — show both to the user. ## New version of an existing record Use this when the user has previously published and wants to release updated data/code under the same concept-DOI. ```bash # 1. Create new version draft (returns links.latest_draft) curl -sS -X POST "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID/actions/newversion" \ -H "Authorization: Bearer $ZENODO_TOKEN" ``` Then follow the bucket of the new draft (from `links.latest_draft` → GET it → use its `links.bucket`) to upload changed files, update metadata, and publish as in steps 2–4 above. The new version inherits files from the previous version by default — delete any you want to replace via `DELETE $BUCKET/<filename>`. ## Discard a draft ```bash curl -sS -X POST "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID/actions/discard" \ -H "Authorization: Bearer $ZENODO_TOKEN" ``` ## Search published records No token needed for public search. ```bash curl -sS "$ZENODO_BASE/records?q=climate+model&size=10&sort=mostrecent" ``` Query syntax is Elasticsearch — fielded queries like `creators.name:"Doe, Jane"`, `communities:zenodo`, `resource_type.type:dataset` all work. See `references/search.md` for query patterns. ## Conventions and gotchas - **Always check HTTP status.** 201 = created, 202 = publish accepted, 400 = metadata error (read the body), 401 = bad token, 403 = wrong scope, 429 = rate limited. - **Rate limits:** 100 req/min, 5000 req/hour for authenticated users. Watch `X-RateLimit-Remaining`. - **Never inline the token** in commands you display — use `$ZENODO_TOKEN`. Don't write the token to files. - **Sandbox first.** Suggest sandbox for any first-time workflow; switch to production only when the user explicitly confirms. - **Verify before publishing.** GET the deposition and review files + metadata with the user before calling `actions/publish` on production. - **Large uploads:** for files > a few hundred MB, consider doing the curl upload with `--progress-bar` and warn the user about time/bandwidth. ## References - `references/metadata.md` — full metadata schema, upload_type values, license codes, conditional fields - `references/search.md` — search query syntax and useful filters - `references/examples.md` — end-to-end shell scripts for common scenarios (dataset upload, software release, new version)

path: README.md
content: # zenodo-skill

English | [中文](README_CN.md)

A Claude Code / OpenClaw skill for the [Zenodo REST API](https://developers.zenodo.org). Deposit, publish, version, and search research artifacts on Zenodo — and get a citable DOI for every release.

## Features

- **Full deposit lifecycle** — create deposition → upload files via the bucket API → set metadata → publish
- **New version workflow** — release updated data/code under the same concept-DOI
- **Search** — Elasticsearch-style queries against published records (no auth required)
- **Sandbox-first** — defaults to `sandbox.zenodo.org` so you don't accidentally publish irreversibly to production
- **Bucket file upload** — uses the new files API (50 GB total, 100 files/record), not the legacy 100 MB endpoint
- **Metadata reference** — full schema for `upload_type`, license codes, conditional fields, related identifiers
- **End-to-end shell examples** — copy-pasteable scripts for dataset upload, software release, new version, batch download

## Installation

### Claude Code

```bash
mkdir -p ~/.claude/skills
git clone https://github.com/Agents365-ai/zenodo-skill ~/.claude/skills/zenodo-skill
```

Or per-project: clone into `.claude/skills/zenodo-skill/`.

### OpenClaw

```bash
mkdir -p ~/.openclaw/skills
git clone https://github.com/Agents365-ai/zenodo-skill ~/.openclaw/skills/zenodo-skill
```

### SkillsMP

Indexed automatically once the repo has the standard topics — install via the SkillsMP marketplace.

## Prerequisites

- `curl` (and `jq` recommended for the example scripts)
- A Zenodo personal access token with `deposit:write` and `deposit:actions` scopes
  - **Sandbox** (testing): https://sandbox.zenodo.org/account/settings/applications/tokens/new/
  - **Production**: https://zenodo.org/account/settings/applications/tokens/new/

Set environment variables before use:

```bash
export ZENODO_TOKEN=...
export ZENODO_BASE=https://sandbox.zenodo.org/api   # or https://zenodo.org/api
```

## Usage

Just describe what you want — the skill triggers on Zenodo-related requests:

- "Upload this dataset to Zenodo and give me a DOI"
- "Publish a new version of my Zenodo record 1234567 with these files"
- "Search Zenodo for single-cell RNA datasets published this year"
- "Deposit this code release to sandbox Zenodo first"

The skill walks the deposit through create → upload → metadata → publish, asks for confirmation before any irreversible production publish, and returns the DOI and record URL.

## What's in this skill

| File | Purpose |
|---|---|
| `SKILL.md` | Workflow, setup, and core API calls |
| `references/metadata.md` | Full deposition metadata schema, `upload_type` values, license codes, examples |
| `references/search.md` | Elasticsearch query syntax and search parameters |
| `references/examples.md` | End-to-end shell scripts (upload+publish, new version, list drafts, download) |

## Safety

- Defaults to sandbox; production publish requires explicit confirmation
- Tokens are read from `$ZENODO_TOKEN` — never inlined into commands
- Reviews metadata + files with you before calling `actions/publish`
- Production publish is irreversible — files cannot be removed and records cannot be deleted

## License

MIT

## Support

If this skill helps you, consider supporting the author:

<table>
  <tr>
    <td align="center">
      <img src="https://raw.githubusercontent.com/Agents365-ai/images_payment/main/qrcode/wechat-pay.png" width="180" alt="WeChat Pay">
      <br>
      <b>WeChat Pay</b>
    </td>
    <td align="center">
      <img src="https://raw.githubusercontent.com/Agents365-ai/images_payment/main/qrcode/alipay.png" width="180" alt="Alipay">
      <br>
      <b>Alipay</b>
    </td>
    <td align="center">
      <img src="https://raw.githubusercontent.com/Agents365-ai/images_payment/main/qrcode/buymeacoffee.png" width="180" alt="Buy Me a Coffee">
      <br>
      <b>Buy Me a Coffee</b>
    </td>
  </tr>
</table>

## Author

**Agents365-ai**

- Bilibili: https://space.bilibili.com/441831884
- GitHub: https://github.com/Agents365-ai


path: README_CN.md
content: # zenodo-skill

一个用于 [Zenodo REST API](https://developers.zenodo.org) 的 Claude Code / OpenClaw 技能。在 Zenodo 上提交、发布、版本化和检索研究产出 —— 每次发布都获得一个可引用的 DOI。

[English](README.md) | 中文

## 功能特性

- **完整的 deposit 生命周期** —— 创建 deposition → 通过 bucket API 上传文件 → 设置元数据 → 发布
- **新版本工作流** —— 在同一个 concept-DOI 下发布更新后的数据 / 代码
- **检索** —— 对已发布记录使用 Elasticsearch 风格的查询(无需鉴权)
- **沙箱优先** —— 默认使用 `sandbox.zenodo.org`,避免误将不可逆的内容发布到生产环境
- **Bucket 文件上传** —— 使用新版 files API(单条记录最多 50 GB / 100 个文件),而非 100 MB 上限的旧接口
- **元数据参考** —— 完整的 `upload_type`、license、条件字段、related_identifiers schema
- **端到端 Shell 示例** —— 数据集上传、软件发布、新版本、批量下载等可直接复用的脚本

## 安装

### Claude Code

```bash
mkdir -p ~/.claude/skills
git clone https://github.com/Agents365-ai/zenodo-skill ~/.claude/skills/zenodo-skill
```

或按项目维度安装,克隆到 `.claude/skills/zenodo-skill/`。

### OpenClaw

```bash
mkdir -p ~/.openclaw/skills
git clone https://github.com/Agents365-ai/zenodo-skill ~/.openclaw/skills/zenodo-skill
```

### SkillsMP

仓库带上标准 topics 后会被自动索引 —— 可直接通过 SkillsMP 市场安装。

## 前置条件

- `curl`(示例脚本推荐配合 `jq`)
- 一个具有 `deposit:write` 与 `deposit:actions` 权限的 Zenodo 个人访问令牌
  - **Sandbox**(测试):https://sandbox.zenodo.org/account/settings/applications/tokens/new/
  - **生产环境**:https://zenodo.org/account/settings/applications/tokens/new/

使用前先设置环境变量:

```bash
export ZENODO_TOKEN=...
export ZENODO_BASE=https://sandbox.zenodo.org/api   # 或 https://zenodo.org/api
```

## 使用方法

直接用自然语言描述需求即可触发本技能:

- "把这个数据集上传到 Zenodo,给我一个 DOI"
- "为我的 Zenodo 记录 1234567 发布一个包含这些文件的新版本"
- "在 Zenodo 上检索今年发布的单细胞 RNA 数据集"
- "先把这个代码 release 提交到 Zenodo 沙箱"

技能会按 创建 → 上传 → 元数据 → 发布 的流程推进 deposit;在执行任何不可逆的生产环境发布前都会请求确认,最终返回 DOI 与记录链接。

## 文件结构

| 文件 | 用途 |
|---|---|
| `SKILL.md` | 工作流、配置与核心 API 调用 |
| `references/metadata.md` | 完整元数据 schema、`upload_type` 取值、license 代码、示例 |
| `references/search.md` | Elasticsearch 查询语法与检索参数 |
| `references/examples.md` | 端到端 Shell 脚本(上传+发布、新版本、列出草稿、下载) |

## 安全策略

- 默认使用 sandbox;生产环境发布需要显式确认
- Token 从 `$ZENODO_TOKEN` 读取 —— 不会内联到任何命令中
- 调用 `actions/publish` 之前会与你一起核对元数据和文件
- 生产环境的发布操作不可逆 —— 文件不能删除,记录也不能撤销

## License

MIT

## 支持作者

如果这个技能对你有帮助,欢迎请作者喝杯咖啡:

<table>
  <tr>
    <td align="center">
      <img src="https://raw.githubusercontent.com/Agents365-ai/images_payment/main/qrcode/wechat-pay.png" width="180" alt="WeChat Pay">
      <br>
      <b>微信支付</b>
    </td>
    <td align="center">
      <img src="https://raw.githubusercontent.com/Agents365-ai/images_payment/main/qrcode/alipay.png" width="180" alt="Alipay">
      <br>
      <b>支付宝</b>
    </td>
    <td align="center">
      <img src="https://raw.githubusercontent.com/Agents365-ai/images_payment/main/qrcode/buymeacoffee.png" width="180" alt="Buy Me a Coffee">
      <br>
      <b>Buy Me a Coffee</b>
    </td>
  </tr>
</table>

## 作者

**Agents365-ai**

- Bilibili:https://space.bilibili.com/441831884
- GitHub:https://github.com/Agents365-ai


path: agents/openai.yaml
content: interface:
  display_name: "Zenodo"
  short_description: "Deposit, publish, version, and search research artifacts on Zenodo via the REST API — get a citable DOI for every release"
  brand_color: "#005A9C"

policy:
  allow_implicit_invocation: true

capabilities:
  - Create Zenodo depositions and upload files via the bucket API (50 GB / 100 files per record)
  - Set deposition metadata (title, creators, license, upload_type, related identifiers, …)
  - Publish depositions and mint citable DOIs
  - Create new versions of existing records under the same concept-DOI
  - Search published Zenodo records with Elasticsearch-style queries
  - Sandbox-first workflow to avoid irreversible production publishes

prerequisites:
  - curl on PATH
  - ZENODO_TOKEN environment variable (personal access token with deposit:write and deposit:actions scopes)
  - Optional: jq for the example shell scripts


path: references/examples.md
content: # End-to-end examples

All examples assume:
```bash
export ZENODO_TOKEN=...
export ZENODO_BASE=https://sandbox.zenodo.org/api   # use https://zenodo.org/api for production
```

## 1. Upload a dataset and publish

```bash
#!/usr/bin/env bash
set -euo pipefail

# 1. Create empty deposition
RESP=$(curl -sS -X POST "$ZENODO_BASE/deposit/depositions" \
  -H "Authorization: Bearer $ZENODO_TOKEN" \
  -H "Content-Type: application/json" -d '{}')
DEPOSIT_ID=$(echo "$RESP" | jq -r .id)
BUCKET=$(echo "$RESP" | jq -r .links.bucket)
echo "Deposition $DEPOSIT_ID, bucket $BUCKET"

# 2. Upload all files in ./data/
for f in ./data/*; do
  name=$(basename "$f")
  curl -sS --upload-file "$f" \
    -H "Authorization: Bearer $ZENODO_TOKEN" \
    "$BUCKET/$name" > /dev/null
  echo "uploaded $name"
done

# 3. Set metadata
curl -sS -X PUT "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID" \
  -H "Authorization: Bearer $ZENODO_TOKEN" \
  -H "Content-Type: application/json" \
  -d @metadata.json

# 4. Review (don't publish blindly)
curl -sS "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID" \
  -H "Authorization: Bearer $ZENODO_TOKEN" | jq '.metadata, .files[].filename'

read -p "Publish? [y/N] " ok
[[ "$ok" == "y" ]] || { echo "aborted"; exit 0; }

# 5. Publish
curl -sS -X POST "$ZENODO_BASE/deposit/depositions/$DEPOSIT_ID/actions/publish" \
  -H "Authorization: Bearer $ZENODO_TOKEN" | jq '{doi, links: .links.record_html}'
```

## 2. Publish a new version

```bash
PARENT_ID=1234567   # the previous deposition id

# Create new version draft
NEW=$(curl -sS -X POST "$ZENODO_BASE/deposit/depositions/$PARENT_ID/actions/newversion" \
  -H "Authorization: Bearer $ZENODO_TOKEN")

# Follow latest_draft link to get the new draft id + bucket
DRAFT_URL=$(echo "$NEW" | jq -r .links.latest_draft)
DRAFT=$(curl -sS "$DRAFT_URL" -H "Authorization: Bearer $ZENODO_TOKEN")
NEW_ID=$(echo "$DRAFT" | jq -r .id)
BUCKET=$(echo "$DRAFT" | jq -r .links.bucket)

# Optional: delete an inherited file you want to replace
curl -sS -X DELETE "$BUCKET/old-data.csv" -H "Authorization: Bearer $ZENODO_TOKEN"

# Upload new file
curl -sS --upload-file ./new-data.csv \
  -H "Authorization: Bearer $ZENODO_TOKEN" "$BUCKET/new-data.csv"

# Update version string in metadata
curl -sS -X PUT "$ZENODO_BASE/deposit/depositions/$NEW_ID" \
  -H "Authorization: Bearer $ZENODO_TOKEN" -H "Content-Type: application/json" \
  -d '{"metadata": {"version": "v1.1.0", "title": "...", "upload_type": "dataset", "description": "...", "creators": [...]}}'

# Publish
curl -sS -X POST "$ZENODO_BASE/deposit/depositions/$NEW_ID/actions/publish" \
  -H "Authorization: Bearer $ZENODO_TOKEN"
```

Note: when calling PUT on metadata for a new version, you must include the **full** metadata object (not just the changed fields).

## 3. Software release tied to a GitHub tag

The recommended path is the [Zenodo–GitHub integration](https://docs.github.com/en/repositories/archiving-a-github-repository/referencing-and-citing-content) — enable the repo in Zenodo settings and create a GitHub release; Zenodo auto-archives.

If doing it via API instead, use upload_type `software` and put the GitHub tag URL in `related_identifiers` with relation `isSupplementTo`. See `metadata.md` for the JSON shape.

## 4. List your own depositions

```bash
curl -sS "$ZENODO_BASE/deposit/depositions?status=draft&size=25" \
  -H "Authorization: Bearer $ZENODO_TOKEN" | jq '.[] | {id, title: .title, state}'
```

## 5. Download files from a public record

```bash
REC=1234567
curl -sS "$ZENODO_BASE/records/$REC" | jq -r '.files[].links.self' | \
  xargs -n1 curl -sS -LO
```


path: references/metadata.md
content: # Zenodo Deposition Metadata Reference

Metadata is set via `PUT /deposit/depositions/{id}` with body `{"metadata": {...}}`.

## Required fields

| Field | Type | Notes |
|---|---|---|
| `upload_type` | string | One of the values below |
| `title` | string | |
| `creators` | array | At least one; each `{name, affiliation?, orcid?, gnd?}`. `name` is `Family, Given` |
| `description` | string | HTML allowed |

## upload_type values

`publication`, `poster`, `presentation`, `dataset`, `image`, `video`, `software`, `lesson`, `physicalobject`, `other`

## Conditionally required

| Condition | Required field | Values |
|---|---|---|
| `upload_type == "publication"` | `publication_type` | `annotationcollection`, `book`, `section`, `conferencepaper`, `datamanagementplan`, `article`, `patent`, `preprint`, `deliverable`, `milestone`, `proposal`, `report`, `softwaredocumentation`, `taxonomictreatment`, `technicalnote`, `thesis`, `workingpaper`, `other` |
| `upload_type == "image"` | `image_type` | `figure`, `plot`, `drawing`, `diagram`, `photo`, `other` |
| `access_right == "embargoed"` | `embargo_date` | ISO8601 date |
| `access_right == "restricted"` | `access_conditions` | string (HTML allowed) |

## Optional but commonly used

| Field | Type | Notes |
|---|---|---|
| `publication_date` | string | ISO8601, defaults to today |
| `access_right` | string | `open` (default), `embargoed`, `restricted`, `closed` |
| `license` | string | Required when access is open/embargoed. Defaults to `cc-zero` for datasets, `cc-by` for everything else. Use SPDX-style id, e.g. `cc-by-4.0`, `mit`, `apache-2.0`, `gpl-3.0` |
| `doi` | string | Pre-reserved or external DOI. Omit to let Zenodo mint one |
| `keywords` | array of strings | |
| `notes` | string | Additional notes (HTML allowed) |
| `version` | string | Free-form, e.g. `v1.2.0` |
| `language` | string | ISO 639-3 code, e.g. `eng` |
| `communities` | array | `[{"identifier": "zenodo"}]` — submission requires community curator approval |
| `grants` | array | `[{"id": "10.13039/501100000780::283595"}]` — funder DOI :: grant id |
| `related_identifiers` | array | `[{"identifier": "10.1234/foo", "relation": "isSupplementTo", "resource_type": "publication-article"}]` |
| `references` | array of strings | Bibliographic references |
| `contributors` | array | Like creators, plus `type` (e.g. `Editor`, `DataCurator`, `Researcher`) |
| `subjects` | array | `[{"term": "...", "identifier": "...", "scheme": "url"}]` |
| `locations` | array | `[{"place": "...", "lat": 0.0, "lon": 0.0, "description": "..."}]` |
| `dates` | array | `[{"start": "...", "end": "...", "type": "Collected", "description": "..."}]` |
| `method` | string | Methodology (HTML allowed) |

## Relation values for `related_identifiers`

`isCitedBy`, `cites`, `isSupplementTo`, `isSupplementedBy`, `isContinuedBy`, `continues`, `isDescribedBy`, `describes`, `hasMetadata`, `isMetadataFor`, `isNewVersionOf`, `isPreviousVersionOf`, `isPartOf`, `hasPart`, `isReferencedBy`, `references`, `isDocumentedBy`, `documents`, `isCompiledBy`, `compiles`, `isVariantFormOf`, `isOriginalFormof`, `isIdenticalTo`, `isAlternateIdentifier`, `isReviewedBy`, `reviews`, `isDerivedFrom`, `isSourceOf`, `requires`, `isRequiredBy`, `isObsoletedBy`, `obsoletes`

## Full dataset example

```json
{
  "metadata": {
    "title": "Global temperature anomalies 1880-2024",
    "upload_type": "dataset",
    "publication_date": "2026-04-07",
    "description": "<p>Monthly global mean surface temperature anomalies derived from ...</p>",
    "creators": [
      {"name": "Doe, Jane", "affiliation": "Example University", "orcid": "0000-0002-1825-0097"}
    ],
    "access_right": "open",
    "license": "cc-by-4.0",
    "keywords": ["climate", "temperature", "global warming"],
    "version": "v1.0.0",
    "language": "eng",
    "related_identifiers": [
      {"identifier": "10.1038/s41586-020-2649-2", "relation": "isSupplementTo", "resource_type": "publication-article"}
    ]
  }
}
```

## Software release example

```json
{
  "metadata": {
    "title": "myproject v1.2.0",
    "upload_type": "software",
    "description": "<p>Release 1.2.0 of myproject. See CHANGELOG.</p>",
    "creators": [{"name": "Doe, Jane", "affiliation": "Example University"}],
    "license": "mit",
    "version": "1.2.0",
    "related_identifiers": [
      {"identifier": "https://github.com/me/myproject/tree/v1.2.0", "relation": "isSupplementTo", "resource_type": "software"}
    ]
  }
}
```


path: references/search.md
content: # Zenodo Search Reference

`GET /api/records` — public, no auth needed for open records.

## Parameters

| Param | Notes |
|---|---|
| `q` | Elasticsearch query string |
| `size` | Results per page (default 10, max 10000 via pagination) |
| `page` | Page number |
| `sort` | `bestmatch` (default), `mostrecent`, `-mostrecent`, `version` |
| `status` | `draft` or `published` (auth only) |
| `all_versions` | `true` to include all versions, otherwise only latest |
| `communities` | community identifier |
| `type` | resource type filter |
| `subtype` | resource subtype |
| `bounds` | geographic bounding box `lon1,lat1,lon2,lat2` |
| `custom` | custom field filter |

## Query syntax (Elasticsearch)

```
# free text
q=climate model

# fielded
q=title:"sea level"
q=creators.name:"Doe, Jane"
q=resource_type.type:dataset
q=communities:zenodo
q=keywords:transformer
q=doi:10.5281/zenodo.1234567

# boolean
q=climate AND (ocean OR atmosphere) NOT model
q=+climate -model

# range
q=publication_date:[2024-01-01 TO 2024-12-31]

# wildcard / fuzzy
q=transform*
q=climate~
```

## Examples

```bash
# 10 most recent datasets about "single cell"
curl -sS "$ZENODO_BASE/records?q=resource_type.type:dataset+AND+single+cell&sort=mostrecent&size=10"

# All records by a specific ORCID
curl -sS "$ZENODO_BASE/records?q=creators.orcid:0000-0002-1825-0097&size=50"

# Records in a community
curl -sS "$ZENODO_BASE/records?q=communities:biosyslit"

# Single record by id
curl -sS "$ZENODO_BASE/records/1234567"
```

Response shape: `{"hits": {"total": N, "hits": [...records]}, "links": {"self", "next", "prev"}}`. Each record has `id`, `doi`, `metadata`, `files`, `links.self_html`, `stats`.


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)