Complete API Reference
This page is the exhaustive index: every REST endpoint and every Python client method available for programmatic access to the platform, in one place. For prose walkthroughs and payload examples, see the Public API Guide, Authentication & API Tokens, and Python Client Guide — this page links out to them rather than repeating their examples.
Scope
This reference covers everything a contributor or an external program can legitimately call: reading the dataset, managing an account and personal access tokens, submitting/updating experiment data, and querying your own submissions.
Deliberately excluded:
- Admin & moderation (
/admin/**,/moderation/**,/cas/**, admin-only/metadata/**writes, admin-only/feedback/**) — require theADMINorMODERATORrole and aren't part of the contributor-facing API. - Machine learning (
/ml/**, dimensionality reduction, model training/prediction/explainability) — a separate authenticated subsystem with no Python client support today; out of scope for this reference.
Base URLs & installation
| Public read API base | https://api.electrospinning-data.org/public/dataset |
| Full API root (auth, submissions, everything else) | https://api.electrospinning-data.org |
| Python package | pip install electrospinning-data-client |
Authentication tiers
| Tier | How | Applies to |
|---|---|---|
| None | — | Reading/downloading the dataset, reference metadata, contributors list, image content, feedback, anonymous web-form submission |
| Session or PAT | Authorization: Bearer <jwt-or-esd_pat_token> | Account profile, submitting/updating data, querying your own records, personal dataset-version snapshots |
| Session only | A browser-login JWT specifically — a PAT is rejected | Creating/listing/revoking/regenerating personal access tokens (a PAT can never be used to manage other PATs) |
See Authentication & API Tokens for how to log in and create a token.
REST API
Dataset (read)
No authentication required.
| Method | Path | Description |
|---|---|---|
GET | /public/dataset (or /latest) | Paginated, filterable JSON of the latest dataset. Params: skip, limit, filter. |
GET | /public/dataset/{version} | Same, for a specific version snapshot, identified by version identifier or DOI. |
GET | /public/dataset/versions | List all dataset version snapshots (versionIdentifier, recordCount, createdAt, doi, license). |
GET | /public/dataset/export | Export latest dataset. Params: format (xlsx|json|zip), version (identifier or DOI), filter. |
GET | /public/dataset/{version}/export | Export a specific version by identifier. Params: format, filter. DOIs contain /, so export by DOI via /public/dataset/export?version={doi} instead. |
Filter syntax and worked examples: Public API Guide.
Downloads & cache
No authentication required. A thin, non-filterable alternative to /public/dataset/export used by the website's download buttons.
| Method | Path | Description |
|---|---|---|
GET | /cache/download/excel | Latest dataset as .xlsx. |
GET | /cache/download/json | Latest dataset as .json. Param: logDownload (bool, default false). |
GET | /cache/download/images | Latest image archive as .zip. |
GET | /cache/download/count | Total download count (long). |
GET | /cache/download/versions | Version list, richer than /public/dataset/versions (adds id, description). |
GET | /cache/download/excel/{id} | A specific version's .xlsx, by numeric version id. |
GET | /cache/download/images/{id} | A specific version's image .zip, by numeric version id. |
Reference / metadata
No authentication required for GET; creating, updating, or deleting reference data requires the ADMIN role (not covered here).
| Method | Path | Description |
|---|---|---|
GET | /metadata/polymers | All known polymers. |
GET | /metadata/polymers/search?cas={cas} | Look up a polymer by CAS number. |
GET | /metadata/solvents | All known solvents. |
GET | /metadata/solvents/search?cas={cas} | Look up a solvent by CAS number. |
GET | /metadata/morphologies | All fiber morphology labels (grouped by category). |
GET | /metadata/units | All measurement units. |
GET | /metadata/instabilities | All process instability labels. |
Use these to validate polymerName/solventName/unit strings before calling /data/submit — an unresolvable name is always rejected (see Record statuses & incomplete submissions).
Contributors
No authentication required.
| Method | Path | Description |
|---|---|---|
GET | /contributors/list | Public list of contributors (JSON). |
Images
No authentication required for standalone image operations; attaching/listing images on a specific experiment record requires a session or PAT.
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /images/upload | None | Upload an image (multipart file, optional imageType/imageDefinition), not yet linked to a record. |
GET | /images/{imageId}/content | None | Fetch the raw image bytes (image/png). |
DELETE | /images/{imageId} | None | Delete an image. |
POST | /experiments/{experimentId}/images | Session or PAT | Attach an uploaded image to an experiment record. |
GET | /experiments/{experimentId}/images | Session or PAT | List images attached to an experiment record. |
Feedback & analytics
No authentication required.
| Method | Path | Description |
|---|---|---|
POST | /feedback/submit | Submit contact-form feedback. Body: {name, category, subject, message, imageBase64}. |
POST | /analytics/view | Log a dataset page view (fire-and-forget, used by the website). |
GET | /analytics/stats | Aggregate {views, downloads} counters. |
Account & authentication
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /auth/register | None | Create an account. Body: {email, password, name, orcid}. Sends a verification email. |
POST | /auth/login | None | Body: {email, password, rememberMe}. Returns {token, refreshToken, email, role, expiresIn}. |
POST | /auth/refresh | None | Body: {refreshToken}. Returns a new LoginResponse. |
GET | /auth/verify-email?token= | None | Confirm a registration email. |
POST | /auth/resend-verification | None | Body: {email}. |
POST | /auth/forgot-password | None | Body: {email}. |
POST | /auth/reset-password | None | Body: {token, newPassword}. |
POST | /auth/admin/create | None* | Bootstrap the first admin only — returns 403 once any admin account exists. |
GET | /auth/me | Session or PAT | {email, role, enabled} for the caller. |
GET | /auth/profile | Session or PAT | Full profile: {email, emailVerified, role, createdAt, name, orcid}. |
PUT | /auth/profile | Session or PAT | Update {name, orcid}. |
POST | /auth/change-password | Session or PAT | Body: {currentPassword, newPassword}. |
DELETE | /auth/profile | Session or PAT | Permanently delete the caller's account. |
# Register, then log in
curl -X POST https://api.electrospinning-data.org/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"jane@example.com","password":"S3curePass!","name":"Jane Doe"}'
curl -X POST https://api.electrospinning-data.org/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"jane@example.com","password":"S3curePass!"}'
# -> {"token": "...", "refreshToken": "...", "email": "jane@example.com", "role": "USER", "expiresIn": 900000}
Personal access tokens
Session only (a PAT cannot manage other PATs). Full walkthrough: Authentication & API Tokens.
| Method | Path | Description |
|---|---|---|
GET | /auth/tokens | List your tokens (metadata only, never the secret). |
POST | /auth/tokens | Create a token. Body: {name, expiresInDays} (expiresInDays ∈ {30, 90, 365} or omitted for no expiry). Response includes the plaintext token once. |
DELETE | /auth/tokens/{id} | Revoke a token immediately. |
POST | /auth/tokens/{id}/regenerate | Rotate a token's secret, keeping its name/expiry. Response includes the new plaintext token once. |
Submitting & updating data
Session or PAT. Only PAT-authenticated calls are allowed to omit mandatory experiment fields (saved as NEEDS_UPDATE); session and anonymous calls keep strict validation. Full walkthrough and payload shape: Authentication & API Tokens.
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /data/submit | None, but PAT unlocks incomplete submissions | Submit a new experiment. Body: SubmitDataDTO (userMetadata, researchMetadata, experimentData[], imageOnly). Returns {message, submissionId, records: [{recordId, status, missingFields}]}. |
PUT | /data/update/{recordId} | Owner (session or PAT) | Update one experiment record. Same body shape (one experimentData[] item). Returns {recordId, status, missingFields, message}. |
PUT | /data/update-submission/{submissionId} | Owner (session or PAT) | Update every record in a submission at once. Returns {message, submissionId, records: [...]}. |
POST | /data/parse-excel | Session or PAT | Multipart file upload — parses an Excel sheet into ExperimentDataDTO[] you can embed in a /data/submit payload. |
Querying your own data
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /data/statuses | None | The four valid status strings: ["PENDING","APPROVED","REJECTED","NEEDS_UPDATE"]. |
GET | /data/my-records | Owner (session or PAT) | Flat list of your own records. Optional ?status= filter; omit for every status combined. |
GET | /data/my-records/ids | Owner (session or PAT) | Same filtering, record ids only. |
GET | /data/my-submissions | Owner (session or PAT) | Your records grouped by submission, each with an aggregate status (PENDING/APPROVED/REJECTED/NEEDS_UPDATE/MIXED/EMPTY). |
GET | /data/pending | Owner (session or PAT) | Legacy equivalent of /data/my-records?status=PENDING. |
GET | /data/experiment/{recordId} | Owner (session or PAT) | A single record, reconstructed as a full SubmitDataDTO. |
GET | /data/submission/{submissionId} | Owner (session or PAT) | A single submission (all its records), as SubmitDataDTO. |
Full explanation of NEEDS_UPDATE and the status lifecycle: Record statuses & incomplete submissions.
Personal dataset-version snapshots
Session or PAT. Lets a contributor save a named, filtered snapshot of the dataset for reproducibility (distinct from the platform's master version releases).
| Method | Path | Description |
|---|---|---|
POST | /versions | Create a snapshot. Body: {name, filterConfig, ...}. |
GET | /versions | List your own snapshots. |
GET | /versions/{id} | Get one snapshot. |
DELETE | /versions/{id} | Delete a snapshot. |
Python client
Installation
pip install electrospinning-data-client
Module-level convenience functions
| Function | Returns | Description |
|---|---|---|
load_latest_dataset(filters=None) | pandas.DataFrame | One-shot download of the latest dataset. |
load_versioned_dataset(version, filters=None) | pandas.DataFrame | One-shot download of a specific version. |
Client (alias: ElectrospinningDataClient)
Client(
base_url="https://api.electrospinning-data.org/public/dataset",
transport=None, timeout=60, verify=True,
token=None, api_token=None, api_base_url=None,
)
token (a personal access token; api_token is kept as an alias for existing code) is only required for the write/query-your-own-data methods below; every read/download method works without it. ElectrospinningDataClient is a plain alias for Client — same class, isinstance()-compatible, nothing to migrate.
Every method has both a short name and a longer, equivalent one — pick whichever reads better:
| Short | Full name | Returns | Requires token | Description |
|---|---|---|---|---|
download(version=None, filters=None) | download_latest / download_version | DataFrame | No | Latest (or a specific version's) dataset, flattened. |
search(filters=None, version="latest") | download_latest(filters=...) | DataFrame | No | Filtered dataset query; same call as download(filters=...). |
submit(record) | submit_experiment(payload) | dict | Yes | Submit a new experiment. Missing mandatory fields don't raise — see status/missingFields per record. |
update(id, record) | update_experiment(experiment_id, payload) | dict | Yes | Update a record you own; completes a NEEDS_UPDATE record. |
status(submission_id) | get_submission_status(submission_id) | dict | Yes | Current state of a submission you own. |
records(status=None) | list_my_records(status=None) | List[dict] | Yes | Your own records, optionally filtered to one status. |
record_ids(status=None) | list_my_record_ids(status=None) | List[int] | Yes | Same filtering, ids only. |
versions() | get_versions() | List[VersionInfo] | No | All dataset version snapshots. |
| — | export_file(output_path, export_format='xlsx', version='latest', filters=None) | None | No | Download straight to a local file (xlsx/json/zip). |
| — | load_records(skip=0, limit=100, version='latest', filters=None) | dict | No | Raw paginated records (no DataFrame conversion). |
| — | close() | None | No | Release the underlying HTTP session. |
FilterBuilder
Fluent filter construction, usable anywhere a filters= argument is accepted.
| Method | Description |
|---|---|
.polymer(value) | Filter by polymer name (case-insensitive contains). |
.solvent(value) | Filter by solvent name. |
.morphology(value) | Filter by morphology label. |
.voltage(min_val=None, max_val=None) | Voltage range (kV). |
.flow_rate(min_val=None, max_val=None) | Flow rate range (mL/h). |
.concentration(min_val=None, max_val=None) | Concentration range (wt%). |
.custom(key, value) | Any other raw filter key/value. |
.build() | Returns the filter dict. |
from electrospinning_data_client import FilterBuilder, load_latest_dataset
filters = FilterBuilder().polymer("PAN").voltage(min_val=20, max_val=30).build()
df = load_latest_dataset(filters=filters)
Exceptions
All inherit from ElectrospinningError.
| Exception | Raised when |
|---|---|
AuthenticationError | A method requiring api_token is called without one configured. |
APIError | The server returns a 4xx/5xx (has .status_code and .response_body). |
TransportError | A network-level failure (timeout, DNS, connection refused). |
ValidationError | Invalid local filter parameters. |
ParsingError | The API response couldn't be parsed into the expected shape. |
Models
| Model | Fields |
|---|---|
ExperimentRecord | record_id, research_metadata, polymer_components, solvent_components, solution_property, needle_property, collector_property, process_parameter, ambient_parameter, fiber_property, mechanical_property, functional_property, raw_data |
VersionInfo | version_identifier, record_count, created_at |
Python method → REST endpoint map
| Python method | REST endpoint(s) |
|---|---|
download / download_latest / download_version | GET /public/dataset[/{version}] |
search (same as download with filters) | GET /public/dataset[/{version}] |
versions / get_versions | GET /public/dataset/versions |
export_file | GET /public/dataset/export or /{version}/export |
load_records | GET /public/dataset or /{version} (raw, unflattened) |
submit / submit_experiment | POST /data/submit |
update / update_experiment | PUT /data/update/{id} |
status / get_submission_status | GET /data/submission/{id} |
records / list_my_records | GET /data/my-records |
record_ids / list_my_record_ids | GET /data/my-records/ids |
There is currently no Python client wrapper for account/token management (/auth/**) or personal dataset-version snapshots (/versions/**) — call those directly over REST with requests (or any HTTP client), using the same bearer-token pattern as the write methods above.
See also
- Public API Guide — filter syntax and read-endpoint walkthrough
- Authentication & API Tokens — creating/using tokens, submission payload examples, record statuses
- Python Client Guide — narrative walkthrough of the Python package