openapi: 3.0.3 info: title: ELabELN REST API version: "2.0.0" description: | The ELabELN REST API gives you programmatic access to experiments, resources, templates, file attachments, scheduling and team administration in an ELabELN electronic lab notebook. Every endpoint the API exposes is documented below, including all endpoints used by the ELabELN integration for Zapier. ## Base URL ``` https://{your-elabeln-host}/api/v2 ``` Every path below is relative to this. Replace `{your-elabeln-host}` with your own instance's hostname — each customer is provisioned on their own host, so there is no single shared base URL. ## Authentication Every request requires an API key, sent in the `Authorization` header: ``` Authorization: 4-1a2b3c4d5e6f... ``` The key is sent **raw** — there is no `Bearer` prefix and no `Token` prefix. `Authorization: Bearer ` fails with `401`. Create a key in the ELabELN web interface under **User panel -> API keys**, as either read only (`GET`) or read/write (`GET`, `POST`, `PATCH`, `DELETE`). A key is bound to the user who created it, and to the team that user was in at the time. `GET /users/me` returns the authenticated user — use it to confirm a key works. This is the call the ELabELN integration for Zapier uses to test a connection. servers: - url: https://{your-elabeln-host}/api/v2 description: Your ELabELN instance variables: your-elabeln-host: default: your-lab.elabeln.com description: The hostname of your ELabELN instance # COMPONENTS components: parameters: SearchQ: name: q in: query schema: type: string description: | Search for a term in title, body or elabid. examples: first: summary: Search for all results with the word "test". value: test SearchExtended: name: extended in: query schema: type: string description: | Extended search (advanced query). examples: first: summary: Search for all results with a rating of 2. value: "rating:2" SearchRelated: name: related in: query schema: type: integer description: | Look only for entries linked to this entry id. examples: first: summary: Look for entries linked to entry with id 42. value: 42 SearchRelatedOrigin: name: related_origin in: query schema: type: string enum: ['experiments', 'items'] description: | When using the "related" query parameter, select the type of the related ID (experiments or items) examples: items: summary: The related entry is a resource. value: items experiments: summary: The related entry is an experiment. value: experiments Category: name: cat in: query schema: type: string description: | Add a filter on the Category. Supports comma separated list of numbers, including "null". examples: first: summary: Only display results with category ID 2 value: "2" second: summary: Display results with category ID 3 or 4 or not set (null) value: "3,4,null" Status: name: status in: query schema: type: string description: | Add a filter on the Status. Supports comma separated list of numbers, including "null". examples: first: summary: Only display results with status ID 2 value: "2" second: summary: Display results with status ID 3 or 4 or not set (null) value: "3,4,null" Tags: name: tags[] in: query schema: type: array items: type: string description: | An array of tags for filtering results containing all of these tags. Limit: name: limit in: query schema: type: integer default: 15 description: | Limit the number of results. examples: first: summary: Limit number of results to 5. value: 5 Offset: name: offset in: query schema: type: integer default: 0 description: | Skip a number of results. Use with limit to work the pagination. examples: first: summary: Skip 3 first results. value: 3 Owner: name: owner in: query schema: type: string description: | Filter results by author (user id) examples: first: summary: Only display results from user with id 2 value: "2" second: summary: Only display results from user with id 2 or 3 value: "2,3" Scope: name: scope in: query schema: type: integer enum: [1, 2, 3] description: | Set the scope for the results. 1: self, 2: team, 3: everything. It defaults to the user value stored in preferences. Order: name: order in: query schema: type: string enum: ["cat", "comment", "customid", "date", "id", "lastchange", "rating", "status", "title", "user"] description: | Change the ordering of the results. examples: first: summary: Order by category value: cat second: summary: Order by custom ID value: customid Sort: name: sort in: query schema: type: string enum: ["asc", "desc"] description: | Change the sorting of results: ascending or descending. State: name: state in: query schema: type: string default: "1" examples: first: summary: Display only archived entries value: "2" second: summary: Display archived and deleted entries value: "2,3" description: | Filter results based on their state: 1 (Normal), 2 (Archived), 3 (Deleted). Supports comma separated values. # end query parameters for entity requestBodies: PatchEntity: description: Parameters for patching an entity required: true content: application/json: schema: anyOf: - $ref: "#/components/schemas/PatchAction" - $ref: "#/components/schemas/entity_editable" PatchItem: description: Parameters for patching an item required: true content: application/json: schema: anyOf: - $ref: "#/components/schemas/PatchAction" - $ref: "#/components/schemas/EntityAndItemEditable" securitySchemes: token: in: header type: apiKey name: Authorization description: The Authorization header value must contain an API Key. schemas: Error: type: object required: [code, message, description] properties: code: type: string message: type: string description: type: string PatchAction: type: object properties: action: type: string enum: - bloxberg - exclusiveeditmode - forcelock - forceunlock - lock - pin - sign - timestamp - updatemetadatafield - update passphrase: type: string description: > The passphrase corresponding to your signature key. Required when action is "sign". example: hunter2 meaning: type: integer enum: [10, 20, 30, 40, 50] description: | Meaning of the signature (required when action is "sign"): - 10: Approval - 20: Authorship - 30: Responsibility - 40: Review - 50: Safety example: 40 required: [action] EntityAndItemEditable: allOf: - $ref: "#/components/schemas/entity_editable" - $ref: "#/components/schemas/item_editable" # API KEY apikey: type: object properties: id: type: integer name: type: string created_at: type: string last_used_at: type: string hash: type: string can_write: type: integer team: type: integer team_name: type: string # CHANGELOG changelog: type: object properties: created_at: type: string description: Timestamp when the change was recorded. example: "2026-02-11 20:36:47" target: type: string description: Field/attribute that was changed. example: "timestamped_at" content: type: string description: New value stored for the target field (may be a scalar or JSON-encoded string depending on target). example: "2026-02-11 20:36:47" fullname: type: string description: Full name of the user who made the change. example: "Chewie" userid: type: integer description: Userid of the user who made the change. example: 3 # COMPOUND compound: type: object properties: id: type: integer example: 14 created_at: type: string format: date-time example: "2025-05-17T15:39:15Z" created_by: type: integer example: 1 modified_at: type: string format: date-time example: "2025-05-17T15:39:15Z" modified_by: type: integer example: 1 userid: type: integer example: 1 team: type: integer example: 1 state: type: integer example: 1 name: type: string example: "2,4-Dichloroanisole" molecular_formula: type: string example: "C7H6Cl2O" cas_number: type: string example: "553-82-2" ec_number: type: string nullable: true chebi_id: type: string nullable: true chembl_id: type: string nullable: true dea_number: type: string nullable: true drugbank_id: type: string nullable: true dsstox_id: type: string nullable: true hmdb_id: type: string nullable: true inchi: type: string example: "InChI=1S/C7H6Cl2O/c1-10-7-3-2-5(8)4-6(7)9/h2-4H,1H3" inchi_key: type: string example: "CICQUFBZCADHHX-UHFFFAOYSA-N" iupac_name: type: string example: "2,4-dichloro-1-methoxybenzene" kegg_id: type: string nullable: true metabolomics_wb_id: type: string nullable: true molecular_weight: # it's a string, see #5733 type: string example: "177.02" nci_code: type: string nullable: true nikkaji_number: type: string nullable: true pharmgkb_id: type: string nullable: true pharos_ligand_id: type: string nullable: true pubchem_cid: type: integer example: 11119 rxcui: type: string nullable: true smiles: type: string example: "COC1=C(C=C(C=C1)Cl)Cl" unii: type: string nullable: true wikidata: type: string nullable: true wikipedia: type: string nullable: true is_corrosive: type: integer enum: [0, 1] is_explosive: type: integer enum: [0, 1] is_flammable: type: integer enum: [0, 1] is_gas_under_pressure: type: integer enum: [0, 1] is_hazardous2env: type: integer enum: [0, 1] is_hazardous2health: type: integer enum: [0, 1] is_serious_health_hazard: type: integer enum: [0, 1] is_oxidising: type: integer enum: [0, 1] is_toxic: type: integer enum: [0, 1] is_radioactive: type: integer enum: [0, 1] is_antibiotic: type: integer enum: [0, 1] is_antibiotic_precursor: type: integer enum: [0, 1] is_drug: type: integer enum: [0, 1] is_drug_precursor: type: integer enum: [0, 1] is_explosive_precursor: type: integer enum: [0, 1] is_cmr: type: integer enum: [0, 1] is_nano: type: integer enum: [0, 1] is_controlled: type: integer enum: [0, 1] is_ed2health: type: integer enum: [0, 1] is_ed2env: type: integer enum: [0, 1] is_pbt: type: integer enum: [0, 1] is_pmt: type: integer enum: [0, 1] is_vpvb: type: integer enum: [0, 1] is_vpvm: type: integer enum: [0, 1] fp2_base64: type: string description: Base64-encoded fingerprint userid_human: type: string example: "Toto Le sysadmin" team_name: type: string example: "Alpha" has_fingerprint: type: integer enum: [0, 1] CompoundDuplicateRequest: type: object required: - action properties: action: type: string enum: - duplicate cid: type: integer description: PubChem Compound ID (CID). Use it to find a compound via this unique identifier. Not compatible with `cas` parameter. example: 2519 cas: type: string description: CAS number. Use it to find a compound via this unique identifier. Not compatible with `cid` parameter. example: "58-08-2" CompoundCreateRequest: type: object properties: action: type: string description: | Note: the default value for `action` attribute is `create`, and as such it can be omitted. enum: - create default: create name: type: string inchi: type: string inchi_key: type: string smiles: type: string molecular_formula: type: string cas_number: type: string iupac_name: type: string pubchem_cid: type: integer is_corrosive: type: integer enum: [0, 1] is_serious_health_hazard: type: integer enum: [0, 1] is_explosive: type: integer enum: [0, 1] is_flammable: type: integer enum: [0, 1] is_gas_under_pressure: type: integer enum: [0, 1] is_hazardous2env: type: integer enum: [0, 1] is_hazardous2health: type: integer enum: [0, 1] is_oxidising: type: integer enum: [0, 1] is_toxic: type: integer enum: [0, 1] # COMMENT comment: type: object properties: id: type: integer created_at: type: string item_id: type: integer comment: type: string userid: type: integer modified_at: type: string fullname: type: string firstname: type: string lastname: type: string orcid: type: string # CONFIG config: type: object properties: admins_create_users: type: string example: '1' default: '1' admins_create_users_remote_dir: type: string example: '0' default: '0' admin_panel_custom_msg: type: string example: 'Welcome to the Admin Panel. Please follow internal procedures.' default: '' admin_validate: type: string example: '0' default: '0' allow_permission_full: type: string example: '1' default: '1' allow_permission_organization: type: string example: '1' default: '1' allow_permission_team: type: string example: '1' default: '1' allow_permission_user: type: string example: '1' default: '1' allow_permission_useronly: type: string example: '1' default: '1' announcement: description: This text will be shown on every page, including login page. type: string example: 'Scheduled maintenance on Saturday 02:00–03:00 UTC.' anon_users: type: string example: '1' default: '1' autologout_time: type: string example: '0' default: '0' blox_anon: type: string example: '0' default: '0' blox_enabled: type: string example: '1' default: '1' chat_url: type: string example: 'https://chat.example.org' cookie_validity_time: type: integer example: 43200 default: 43200 dspace_host: description: URL for dspace host example: "https://dspace.example.org" default: "https://demo.dspace.org/" type: string format: uri dspace_user: description: Username for dspace integration example: "dspace+user@example.org" default: "dspacedemo+admin@gmail.com" type: string dspace_password: description: Password for the corresponding dspace user example: baguette1789 default: "" type: string email_domain: type: string example: 'null' extauth_email: type: string example: '' default: '' extauth_firstname: type: string example: '' default: '' extauth_lastname: type: string example: '' default: '' extauth_remote_user: type: string example: '' default: '' extauth_teams: type: string example: '' default: '' lang: type: string example: 'en_GB' default: 'en_GB' ldap_base_dn: type: string example: 'dc=example,dc=org' default: 'dc=example,dc=org' ldap_search_attr: type: string example: 'mail' default: 'mail' ldap_email: type: string example: 'mail' default: 'mail' ldap_firstname: type: string example: 'givenname' default: 'givenname' ldap_host: type: string example: 'ldpa' default: 'ldap' ldap_lastname: type: string example: 'cn' default: 'cn' ldap_password: type: string example: 'admin' default: 'admin' ldap_port: type: string example: '389' default: '389' ldap_sync_teams: type: string example: '0' default: '0' ldap_team: type: string example: 'on' default: 'on' ldap_team_create: type: string example: '1' default: '0' ldap_toggle: type: string example: '0' default: '0' ldap_use_tls: type: string example: '0' default: '0' ldap_username: type: string example: 'cn=admin,dc=example,dc=org' default: 'cn=admin,dc=example,dc=org' local_login: type: string example: null default: '1' local_register: type: string example: '1' default: '1' login_announcement: description: This text will only be shown on the login page. type: string example: null login_tries: type: string example: '10' default: '10' logout_url: type: string example: '' default: '' mail_from: type: string example: 'otconfigured@example.com' default: 'notconfigured@example.com' max_revisions: type: string example: '10' default: '10' min_days_revisions: type: string example: '23' default: '23' min_delta_revisions: description: Minimum number of characters changed required to trigger a revision save. type: string example: '100' default: '100' onboarding_email_active: enum: ['0', '1'] type: string example: '1' default: '1' onboarding_email_admins_body: type: string example: '

Test email body for admins.

' default: '

Test email body for admins.

' onboarding_email_admins_subject: type: string example : 'subject for admins' default: 'subject for admins' onboarding_email_body: type: string example: '

Test email body for users.

' default: '

Test email body for users.

' onboarding_email_different_for_admins: enum: ['0', '1'] type: string example: '1' default: '1' onboarding_email_subject: type: string example: 'test email subject' default: 'test email subject' privacy_policy: type: string example: '' proxy: type: string example: '' default: '' remote_dir_config: type: string example: '' default: '' remote_dir_service: type: string example: 'eairef' default: 'eairef' s3_bucket_name: type: string example: '' default: '' s3_endpoint: type: string example: '' default: '' s3_path_prefix: type: string example: '' default: '' s3_region: type: string example: '' default: 'fr-par-42' s3_verify_cert: type: string example: '1' default: '1' saml_allowrepeatattributename: type: string example: '0' default: '0' saml_authnrequestssigned: type: string example: '0' default: '0' saml_baseurl: type: string example: '' saml_debug: type: string example: '0' default: '0' saml_entityid: type: string example: '' saml_logoutrequestsigned: type: string example: '0' default: '0' saml_logoutresponsesigned: type: string example: '0' default: '0' saml_lowercaseurlencoding: type: string example: '0' default: '0' saml_nameidencrypted: type: string example: '0' default: '0' saml_nameidformat: type: string example: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress' default: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress' saml_privatekey: type: string example: '' saml_relaxdestinationvalidation: type: string example: '0' default: '0' saml_signmetadata: type: string example: '0' default: '0' saml_strict: type: string example: '1' default: '1' saml_sync_teams: type: string example: '0' default: '0' saml_team_create: type: string example: '1' default: '1' saml_team_default: type: string example: '-1' default: '-1' saml_toggle: type: string example: '0' default: '0' saml_user_default: type: string example: '1' default: '1' saml_wantassertionsencrypted: type: string example: '0' default: '0' saml_wantassertionssigned: type: string example: '0' default: '0' saml_wantmessagessigned: type: string example: '0' default: '0' saml_wantnameid: type: string example: '1' default: '1' saml_wantnameidencrypted: type: string example: '0' default: '0' saml_wantxmlvalidation: type: string example: '1' default: '1' saml_x509: type: string example: '' saml_x509_new: type: string example: '' schema: type: string example: '196' default: '196' smtp_address: type: string example: 'mail.smtp2go.com' default: 'mail.smtp2go.com' smtp_encryption: type: string example: 'ssl' default: 'ssl' smtp_password: type: string example: '' default: '' smtp_port: type: string example: '587' default: '587' smtp_username: type: string example: '' default: '' support_url: type: string example: 'https://support.example.org' ts_authority: type: string example: 'dfn' default: 'dfn' ts_cert: type: string example: '' ts_hash: type: string example: 'sha256' default: 'sha256' ts_limit: type: string example: '0' default: '0' ts_login: type: string example: '' ts_password: type: string example: '' default: '' ts_url: type: string example: '' uploads_storage: type: string example: '1' default: '1' users_validity_is_externally_managed: type: string example: '0' default: '0' # CONTAINER container: type: object description: A container represents the storage of an entity in a specific storage unit properties: id: type: integer description: The container link ID example: 1 qty_stored: type: string description: Quantity stored in this container example: 10.5 qty_unit: type: string description: Unit of the quantity stored example: "mL" enum: ["bar", "•", "m", "μL", "mL", "L", "μg", "mg", "g", "kg"] storage_id: type: integer description: ID of the storage unit example: 5 item_id: type: integer description: ID of the entity (experiment or resource) example: 42 created_at: type: string description: When the container entry was created example: "2024-05-28T02:42:19Z" modified_at: type: string description: When the container entry was last modified example: "2024-05-28T02:42:31Z" storage_name: type: string description: Name of the storage unit example: "Freezer A" full_path: type: string description: Full hierarchical path of the storage unit example: "Building A > Room 101 > Freezer A" # ENTITY COMPONENT: EXTENDS ENTITY_EDITABLE entity: description: The complete representation of an entity allOf: - $ref: '#/components/schemas/entity_editable' - type: object properties: access_key: type: string nullable: true body_html: type: string nullable: true category_color: type: string nullable: true category_title: type: string nullable: true changelog: type: array items: $ref: '#/components/schemas/changelog' comments: type: array items: $ref: '#/components/schemas/comment' compounds_links: type: array items: $ref: '#/components/schemas/compound' created_at: type: string created_from_id: type: integer description: Id of the template used to create this entry. nullable: true created_from_type: type: integer description: | Type of the entity used to create this entry: template or concrete type if duplicate nullable: true created_from_type_human: type: string description: Human readable version of created_from_type integer. nullable: true elabid: type: string exclusive_edit_mode: $ref: '#/components/schemas/exclusive_edit_mode' experiments_links: type: array items: $ref: '#/components/schemas/link' firstname: type: string fullname: type: string hide_main_text: type: integer enum: [ 0, 1 ] description: Hide the main text of an entry. When applied to templates, this setting also applies to derived entries. id: type: integer items_links: type: array items: $ref: '#/components/schemas/link' lastchangeby: type: integer nullable: true lastname: type: string locked: type: integer lockedby: type: integer nullable: true locked_at: type: string nullable: true modified_at: type: string next_step: type: string nullable: true orcid: type: string nullable: true page: type: string recent_comment: type: string nullable: true related_experiments_links: type: array items: $ref: '#/components/schemas/link' related_items_links: type: array items: $ref: '#/components/schemas/link' sharelink: type: string status_color: type: string nullable: true status_title: type: string nullable: true steps: type: array items: $ref: '#/components/schemas/step' tags: type: string nullable: true tags_id: type: string nullable: true team: type: integer timestamped: type: integer timestampedby: type: integer nullable: true timestamped_at: type: string nullable: true type: type: string uploads: type: array items: $ref: '#/components/schemas/upload' # ENTITY EDITABLE entity_editable: type: object description: For columns that can be modified by POST or PATCH properties: body: type: string nullable: true description: The main text content (HTML or Markdown) example: "

Section title

Main text of resource

" canread_base: type: number nullable: true description: | Base permission for read access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 20 enum: [10, 20, 30, 40, 50] canread: type: string nullable: true description: JSON permissions for reading the entry example: '{"teams": [4], "users": [42,32], "teamgroups": [1,5]}' default: '{"teams": [], "users": [], "teamgroups": []}' canwrite_base: type: number nullable: true description: | Base permission for write access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 10 enum: [10, 20, 30, 40, 50] canwrite: type: string nullable: true description: JSON permissions for writing the entry example: '{"teams": [4], "users": [42,32], "teamgroups": [1,5]}' default: '{"teams": [], "users": [], "teamgroups": []}' category: type: integer nullable: true description: The experiment category ID example: 3 date: type: string content_type: type: integer nullable: true description: | Set the content type for main text: - 1: HTML (default) - 2: Markdown If unset, it will use the user's preference value. example: 1 enum: [ 1, 2 ] custom_id: type: integer description: Cannot be negative. Can be reset with "0", null or empty string. nullable: true metadata: $ref: '#/components/schemas/metadata' rating: type: integer nullable: true description: Rating value from 0 to 5 default: 0 state: type: integer status: type: integer nullable: true description: Cannot be negative nor empty string. Can be reset with "0" and null. example: 1 title: type: string nullable: true description: The title of the entry default: Untitled example: "Test replicating the results of Naomi" template: type: integer description: | The template id to use, or 0 to use the common team template, or -1 to have an empty body. default: -1 userid: type: integer description: | User ID of the entity owner. When transferring ownership, the `team` field should also be provided (optional). team: type: integer description: | Optional team context for ownership transfer. If omitted, the requester’s team is used by default. If provided, the API validates that the target user is a member of the specified team. # ENTITY DUPLICATE entity_duplicate: type: object description: Parameters for duplicating an entry properties: action: type: string description: | The "duplicate" action creates a new entity based from the given entity id. default: 'duplicate' copyFiles: type: boolean default: false description: | If "true", the action will import the files of the original entity. linkToOriginal: type: boolean default: true description: | If "true", the action will create a link to the original entity. # EVENT event: type: object properties: id: type: integer example: 13 team: type: integer example: 1 team_name: type: string example: 'Alpha' title: type: string description: Optional comment added to the event example: '[pET-32a(+)] Afternoon experiment. (Titi Koelpin)' title_only: type: string description: Title of the event. nullable: true example: 'Afternoon experiment' book_cancel_minutes: type: integer nullable: true description: Minutes before start when cancellation is allowed book_is_cancellable: type: integer description: Whether the booking can be cancelled (1 = yes, 0 = no) example: 1 canbook: type: integer description: Whether the event is bookable (1 = yes, 0 = no) example: 1 created_at: type: string format: date-time example: '2026-03-02 16:14:14' modified_at: type: string format: date-time example: '2026-03-02 16:29:27' start: type: string format: date-time example: '2026-03-04 17:30:00' end: type: string format: date-time example: '2026-03-04 20:00:00' event_duration_minutes: type: integer example: 150 userid: type: integer example: 2 fullname: type: string description: Full name of the user who created the event. example: 'Titi Koelpin' experiment: type: integer nullable: true example: 20 experiment_title: type: string description: The experiment that has been bound to the event. nullable: true example: 'Effect of temperature on enzyme activity' items_id: type: integer description: ID of the Resource being booked example: 124 item_title: type: string example: 'pET-32a(+)' items_category: type: integer nullable: true items_category_title: type: string nullable: true item_link: type: integer nullable: true example: 132 item_link_title: type: string description: The item that has been bound to the event. nullable: true example: 'HEK293T' color: type: string nullable: true experiment: allOf: - $ref: '#/components/schemas/entity' # ENTITY TEMPLATE entity_template_editable: allOf: - $ref: '#/components/schemas/entity_editable' - type: object properties: canread_is_immutable: type: integer description: Set to 1 to prevent further changes to the permissions setting for read access default: 0 canwrite_is_immutable: type: integer description: Set to 1 to prevent further changes to the permissions setting for write access default: 0 entity_template: description: For experiments templates and items types (resources templates) allOf: - $ref: '#/components/schemas/entity_template_editable' - $ref: '#/components/schemas/entity' exclusive_edit_mode: type: object properties: locked_by: type: integer description: Userid of the user having exclusive edition rights locked_by_human: type: string description: Full name of the user having exclusive edition rights locked_at: type: string description: Time when the exclusive edit mode was created is_stale: type: integer description: Is 1 when the exclusive edit lock is longer than ExclusiveEditMode::EXPIRATION_MINUTES extra_fields_keys: type: object properties: extra_fields_key: type: string frequency: type: integer # EXPORT export: type: object properties: id: type: integer example: 120 created_at: type: string example: "2024-05-28 02:42:19" requester_userid: type: integer example: 2 state: type: integer example: 1 long_name: type: string example: "7dd6ef1e6093ab8861e425aeb1950e70e2a0bea9672bfff45f20a0cf26e49222c634c2fabf408bd6e9f3c447338edf3c4f11475c0472e00ab7ba5ea41319ec49" filesize: type: integer example: 268438 modified_at: type: string example: "2024-05-28 02:42:31" real_name: type: string example: "export-2024-05-28_02-42-30.json" team: type: integer example: 1 changelog: type: integer example: 0 pdfa: type: integer example: 0 json: type: integer example: 0 hash: type: string example: "90651dd009d40b4d0fabc65395e9f3eba9b913a71b13bad94904c0cede7d8c24" hash_algo: type: string example: "sha256" experiments: type: integer example: 1 items: type: integer example: 0 experiments_templates: type: integer example: 0 items_types: type: integer example: 0 format: type: string example: "pdf" idp_cert: type: object description: X.509 certificate associated with a SAML IdP properties: id: type: integer example: 42 x509: type: string description: > Base64 encoded DER representation of the X.509 certificate (as stored in the database). example: MIIGRzCCBC+gAwIBAgIUMeJZCXrKxA9Mc9Yam8Ni6OrvwQQwDQYJKoZIhvcNAQELBQAw... sha256: type: string description: Hex encoded SHA 256 fingerprint of the certificate. pattern: '^[0-9a-f]{64}$' example: d789916e2e44323c91119bf4676e9d8bba3609d4ee50d8cb6367591dd4276c7e purpose: type: integer description: > Usage of the certificate. 0 for signing, 1 for encryption. example: 0 not_before: type: string description: Validity starting date for certificate example: '2019-04-15 18:18:00.000000' not_after: type: string description: Validity end date for certificate example: '2038-01-19 03:47:07.000000' created_at: type: string description: Timestamp when the certificate was created. example: '2025-11-16 21:00:23.000000' modified_at: type: string description: Timestamp when the certificate was last modified. example: '2025-11-16 21:00:23.000000' required: - id - x509 - sha256 - purpose - created_at - modified_at idp_endpoint: type: object description: SAML2 endpoint properties: id: type: integer example: 42 is_slo: type: integer description: > Will be 1 if the endpoint is for SLO (otherwise it means it's SSO) example: 0 enum: [ 0, 1 ] binding: type: integer description: | The type of binding: POST or redirect(see SamlBinding enum) enum: [ 0, 1 ] example: 0 location: type: string description: > Actual URL example: https://idp.uni-example.de/idp/profile/SAML2/POST/SLO binding_urn: type: string description: URN corresponding to the `binding` field example: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST' created_at: type: string description: Timestamp when the endpoint was created. example: '2025-11-16 21:00:23.000000' modified_at: type: string description: Timestamp when the endpoint was last modified. example: '2025-11-16 21:00:23.000000' idp: type: object properties: id: type: integer name: type: string entityid: type: string enabled: type: integer email_attr: type: string fname_attr: type: string lname_attr: type: string team_attr: type: string nullable: true orgid_attr: type: string nullable: true orcid_attr: type: string nullable: true source: type: integer nullable: true certs: type: array description: Certificates associated with this IdP. items: $ref: '#/components/schemas/idp_cert' endpoints: type: array description: Endpoints associated with this IdP. items: $ref: '#/components/schemas/idp_endpoint' idp_source: type: object properties: id: type: integer url: type: string auto_refresh: type: integer last_fetched_at: type: string format: date-time nullable: true idps_count: type: integer idps_count_enabled: type: integer item_editable: type: object properties: is_bookable: type: integer canbook_base: type: number description: | Base permission for booking access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 20 enum: [10, 20, 30, 40, 50] canbook: type: string book_max_minutes: type: integer book_max_slots: type: integer book_can_overlap: type: integer book_users_can_in_past: type: integer book_is_cancellable: type: integer book_cancel_minutes: type: integer booking_window_days: type: integer description: How many days in advance users can book an item. 0 means no limit. booking_hourly_rate_notax: type: number description: The hourly rate of booked resource, without taxes. minimum: 0 booking_hourly_rate_tax: type: number description: The hourly rate of booked resource, with taxes. minimum: 0 booking_hourly_rate_currency: type: integer description: | The currency of the hourly rate: - 0: CAD - 1: CHF - 2: CNY - 3: DKK - 4: EUR - 5: GBP - 6: JPY - 7: USD - 8: SEK - 9: NOK example: 0 enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] item: allOf: - $ref: '#/components/schemas/entity' - $ref: '#/components/schemas/item_editable' link: type: object properties: entityid: type: integer title: type: string is_bookable: type: integer link_state: type: integer category_id: type: integer nullable: true category_color: type: string nullable: true category_title: type: string nullable: true status_id: type: integer nullable: true status_color: type: string nullable: true status_title: type: string nullable: true custom_id: type: integer nullable: true page: type: string type: type: string # METADATA COMPONENT metadata: type: object nullable: true description: The metadata is a JSON type attribute that is mainly used to hold the custom fields, but it can hold anything you want properties: elabftw: type: object nullable: true properties: extra_fields_groups: type: array nullable: true description: This array stores the custom fields groups default: [] items: type: object properties: id: type: integer name: type: string extra_fields: type: object nullable: true description: See https://doc.elabftw.net/docs/usage/metadata#extra-fields-objects additionalProperties: type: object nullable: true properties: type: nullable: true type: string enum: ['allow_multi_values', 'blank_value_on_duplicate', 'checkbox', 'date', 'datetime-local', 'description', 'email', 'experiments', 'group_id', 'items', 'number', 'options', 'position', 'radio', 'required', 'select', 'text', 'time', 'unit', 'url', 'users'] value: nullable: true type: string group_id: type: integer nullable: true description: type: string nullable: true notification: type: object properties: id: type: integer category: type: integer is_ack: type: integer created_at: type: string userid: type: integer send_email: type: integer email_sent_at: type: string body: type: string revision: type: object properties: id: type: integer item_id: type: integer body: type: string body_html: type: string content_type: type: integer created_at: type: string userid: type: integer # experiments_status, experiments_categories, resources_categories and items_status are statuslike statuslike: type: object properties: id: type: integer title: type: string color: type: string is_default: type: integer step: type: object properties: id: type: integer item_id: type: integer body: type: string ordering: type: integer finished: type: integer finished_time: type: string deadline: type: string deadline_notif: type: integer is_immutable: description: Only editable via templates. Immutability persists on derived experiments or resources. enum: [ 0, 1 ] type: integer # STORAGE UNIT storage_unit: type: object properties: id: type: integer description: The storage unit ID example: 1 name: type: string description: Name of the storage unit example: "Freezer A" parent_id: type: integer nullable: true description: ID of the parent storage unit (null for root level) example: null full_path: type: string description: Full hierarchical path from root to this unit example: "Building A > Room 101 > Freezer A" level_depth: type: integer description: Depth level in the hierarchy (0 for root) example: 2 tag: type: object properties: id: type: integer item_count: type: integer is_favorite: type: integer tag: type: string team: type: integer team: type: object properties: id: type: integer name: type: string user_create_tag: type: integer force_exp_tpl: type: integer default: 0 description: Binary toggle to force usage of templates. force_res_tpl: type: integer default: 0 description: Binary toggle to force usage of templates. created_at: type: string orgid: type: string visible: type: integer announcement: description: Text shown on top of every page for all users of this team. type: string nullable: true onboarding_email_active: description: Do we send onboarding emails to new users? enum: [0, 1] type: integer onboarding_email_body: type: string nullable: true onboarding_email_subject: type: string nullable: true teamgroup: type: object properties: id: type: integer name: type: string users: type: array items: type: object properties: userid: type: integer fullname: type: string todoitem: type: object properties: id: type: integer body: type: string creation_time: type: string ordering: type: integer userid: type: integer unfinished_step: type: object properties: id: type: integer title: type: string steps: type: array items: type: string unfinished_steps: type: object properties: experiments: type: array items: $ref: '#/components/schemas/unfinished_step' items: type: array items: $ref: '#/components/schemas/unfinished_step' upload: type: object properties: id: type: integer real_name: type: string long_name: type: string comment: type: string item_id: type: integer userid: type: integer type: type: string created_at: type: string hash: type: string hash_algorithm: type: string storage: type: integer filesize: type: integer state: type: integer immutable: type: integer fullname: type: string # users seen as a user, with limited columns users: description: Response for when requester is a regular user. type: object properties: userid: type: integer firstname: type: string lastname: type: string initials: type: string email: type: string fullname: type: string orcid: type: string nullable: true sig_pubkey: type: string description: Public signature key (minisign format) nullable: true # users seen as an admin users_full: description: Response for when requester has Admin privilege. allOf: - $ref: '#/components/schemas/users' - type: object properties: created_at: type: string description: Account creation timestamp. validated: type: integer valid_until: type: string nullable: true last_login: type: string nullable: true description: Last time a full authentication happened. orgid: type: string nullable: true description: Internal organization id used to match user with something other than email. auth_service: type: integer nullable: true description: What mechanism was used to login, see AuthType Enum. is_sysadmin: type: integer default: 0 default_read: type: string example: '{"teams": [4], "users": [42,32], "teamgroups": [1,5]}' default: '{"teams": [], "users": [], "teamgroups": []}' default_read_base: type: number nullable: true description: | Base permission for default read access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 20 enum: [10, 20, 30, 40, 50] default_read_base_human: type: string description: Default read base permission as human readable value default_write: type: string example: '{"teams": [4], "users": [42,32], "teamgroups": [1,5]}' default: '{"teams": [], "users": [], "teamgroups": []}' default_write_base: type: number nullable: true description: | Base permission for default write access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 20 enum: [10, 20, 30, 40, 50] default_write_base_human: type: string description: Default write base permission as human readable value teams: type: array items: type: object properties: id: type: integer name: type: string is_admin: type: integer is_owner: type: integer is_archived: type: integer # RESPONSES responses: BadRequest: description: Bad request (syntax error, invalid request or missing field) content: application/json: schema: $ref: '#/components/schemas/Error' example: code: '400' message: | Error decoding json payload: Syntax error description: "" Unauthorized: description: Unauthorized (Authentication required) content: application/json: schema: $ref: '#/components/schemas/Error' example: code: '401' message: Authentication required description: No corresponding API key found! Forbidden: description: Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/Error' example: code: '403' message: Forbidden description: Insufficient permissions NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' example: code: '404' message: Nothing to show with this id description: "" Unprocessable: description: | Unprocessable content: your request is valid but the server cannot process it. content: application/json: schema: $ref: '#/components/schemas/Error' example: code: '422' message: You must have at least one base permission active description: "" InternalServerError: description: The server was unable to complete your request. Please try again later. content: application/json: schema: $ref: '#/components/schemas/Error' example: code: '500' message: Unexpected error description: Hopefully something useful x-parameterGroups: searchParams: &searchParams - $ref: "#/components/parameters/SearchQ" - $ref: "#/components/parameters/SearchExtended" - $ref: '#/components/parameters/SearchRelated' - $ref: '#/components/parameters/SearchRelatedOrigin' - $ref: '#/components/parameters/Category' - $ref: '#/components/parameters/Status' - $ref: '#/components/parameters/Tags' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Offset' - $ref: '#/components/parameters/Owner' - $ref: '#/components/parameters/Scope' - $ref: '#/components/parameters/Order' - $ref: '#/components/parameters/Sort' - $ref: '#/components/parameters/State' security: - token: - token tags: - name: Info description: Version and usage information about the ELabELN instance. - name: Users description: "Read and manage users. `GET /users/me` returns the user that owns the API key and is the standard way to verify a key." - name: Api keys description: Create and revoke API keys. - name: Experiments description: "Create, read, update and delete experiments. `POST` creates an empty experiment and returns its id in the `Location` header; follow it with a `PATCH` to populate it." - name: Items description: "Create, read, update and delete resources (samples, reagents, equipment). `POST` requires a `category_id` and returns the new id in the `Location` header; follow it with a `PATCH` to populate it." - name: Steps description: Procedure steps on an experiment or resource, and marking them finished. - name: Comments description: Comments on an experiment or resource. - name: Tags description: Tags applied to an individual experiment or resource. - name: Uploads description: File attachments on an experiment or resource, uploaded as multipart form data. - name: Links to items description: "Links from an entry to a resource. The target id goes in the URL, with `{\"action\": \"create\"}` in the body." - name: Links to experiments description: Links from an entry to an experiment. - name: Links to compounds description: Links from an entry to a chemical compound. - name: Experiments templates description: Reusable experiment templates. Creating an experiment from a template copies its body, extra fields and steps. - name: Items types (Resources Templates) description: "Resource categories, also called items types. The id of an items type is what `POST /items` needs as `category_id`." - name: Experiments categories description: Per-team experiment categories. - name: Resources categories description: Per-team resource categories. - name: Experiments status description: Per-team experiment statuses. - name: Resources status description: Per-team resource statuses. - name: Team tags description: The tag vocabulary available to a team. - name: Favorite tags description: "A user's favourite tags." - name: Teams description: Team records and team membership. - name: Teamgroups description: Groups of users within a team, used for permissions. - name: Events description: Scheduler bookings for bookable resources. - name: Todolist description: "The authenticated user's to-do list." - name: Unfinished steps description: "Steps not yet marked finished, across the user's entries." - name: Containers description: Storage locations holding a given entry. - name: Storage units description: "The storage hierarchy itself, for example freezer to shelf to box. Units nest through `parent_id`." - name: Compounds description: Chemical compounds and their properties. - name: Custom Fields Keys description: The set of custom field keys in use, useful for building field pickers. - name: Revisions description: "Revision history of an entry's body." - name: Exports description: "Export entries as PDF, CSV, JSON or ELN archive. `eln` is the portable, re-importable format." - name: Import description: Import entries from a file. - name: Reports description: Instance-wide reporting data. - name: Notifications description: "A user's notifications." - name: User Uploads description: All uploads belonging to a user. - name: Config description: Instance configuration. Sysadmin only. - name: Idps description: SAML identity providers for single sign-on. Sysadmin only. - name: Idps Sources description: Identity provider metadata sources. Sysadmin only. - name: DSpace description: Integration with a DSpace repository. paths: # CONTAINERS /{entity_type}/{id}/containers: summary: Manage containers for an entity in the inventory. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates', 'items_types'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Containers'] summary: Read all containers for this entity. description: Get a list of all storage locations (containers) where this entity is stored. operationId: read-containers responses: '200': description: A list of containers. content: application/json: schema: type: array items: $ref: '#/components/schemas/container' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/containers/{subid}: summary: Actions on a specific container. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates', 'items_types'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the container required: true schema: type: integer post: tags: ['Containers'] summary: Create a container for this entity. description: Store this entity in a storage unit with a specified quantity. operationId: post-container requestBody: description: Parameters for creating a container. content: application/json: schema: type: object required: ['storage_id', 'qty_stored'] properties: qty_stored: type: number description: Quantity stored. example: 10.5 qty_unit: type: string description: Unit of the quantity. Defaults to "unit" if not provided. example: "mL" # see Units enum enum: ['bar', '•', 'm', 'μL', 'mL', 'L', 'μg', 'mg', 'g', 'kg'] responses: '201': description: The container has been created. headers: location: description: An URL to the container that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' get: tags: ['Containers'] summary: Read a container. description: Get details of a specific container entry. operationId: read-container responses: '200': description: A container. content: application/json: schema: $ref: '#/components/schemas/container' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Containers'] summary: Modify a container. description: | Update the quantity stored, the unit, or the storage location of a container. Setting `storage_id` moves the container to a different storage unit while preserving its `id` and `created_at`. operationId: patch-container requestBody: description: Parameters for modifying a container. content: application/json: schema: type: object properties: qty_stored: type: number description: New quantity stored. example: 15.0 qty_unit: type: string description: New unit of the quantity. example: "g" storage_id: type: integer description: | New storage unit id. Moves the container to that storage unit. Requires write access on the parent entity and (when `inventory_require_edit_rights=1`) the `can_manage_inventory_locations` permission. example: 12 responses: '200': description: The updated container. content: application/json: schema: $ref: '#/components/schemas/container' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Containers'] summary: Delete a container. description: Remove an entity from a storage unit. operationId: delete-container responses: '204': description: The container was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # STORAGE UNITS /storage_units: summary: List containers or storage unit hierarchy. get: tags: ['Storage units'] summary: Read all containers, or the storage unit hierarchy when `?hierarchy=true`. description: | Without parameters, returns the full list of containers (assignments of experiments or resources to storage locations) that you have access to. With `?hierarchy=true`, returns a flat list of all storage units (freezers, boxes, positions, etc.) with their hierarchy metadata (`id`, `name`, `parent_id`, `full_path`, `level_depth`, `children_count`). This allows clients to discover, traverse, or display the storage unit tree. operationId: read-storage-units parameters: - name: hierarchy in: query required: false schema: type: boolean description: | When true, returns a flat list of all storage units in the hierarchy (id, name, parent_id, full_path, level_depth, children_count) instead of the default container assignment list. responses: '200': description: | Without `hierarchy`: a list of containers attached to experiments or resources. With `hierarchy=true`: a flat list of storage units with hierarchy metadata. content: application/json: schema: oneOf: - description: Default mode — container assignments. type: array items: type: object properties: entity_id: type: integer example: 211 entity_title: type: string example: Some title entity_custom_id: nullable: true type: integer example: null page: type: string example: experiments container2item_id: type: integer example: 1 qty_stored: type: string description: Quantity stored, formatted as a string (often decimal). example: "1.00" qty_unit: type: string description: Quantity unit (may contain special characters). example: "•" created_at: type: string description: Timestamp in `YYYY-MM-DD HH:MM:SS` format. example: "2026-01-23 16:10:41" modified_at: type: string description: Timestamp in `YYYY-MM-DD HH:MM:SS` format. example: "2026-01-23 16:10:41" firstname: type: string example: Ada lastname: type: string example: Lovelace fullname: type: string example: Ada Lovelace team_name: type: string example: BIOMEKA team_id: type: integer example: 1 storage_id: type: integer example: 12 storage_name: type: string example: 4th floor full_path: type: string description: Full storage path, formatted with separators. example: "Hospital > 4th floor" cas_number: type: string nullable: true example: null pubchem_cid: type: integer nullable: true example: null is_corrosive: type: integer nullable: true enum: [0, 1] example: null is_serious_health_hazard: type: integer nullable: true enum: [0, 1] example: null is_explosive: type: integer nullable: true enum: [0, 1] example: null is_flammable: type: integer nullable: true enum: [0, 1] example: null is_gas_under_pressure: type: integer nullable: true enum: [0, 1] example: null is_hazardous2env: type: integer nullable: true enum: [0, 1] example: null is_hazardous2health: type: integer nullable: true enum: [0, 1] example: null is_oxidising: type: integer nullable: true enum: [0, 1] example: null is_toxic: type: integer nullable: true enum: [0, 1] example: null is_radioactive: type: integer nullable: true enum: [0, 1] example: null is_antibiotic: type: integer nullable: true enum: [0, 1] example: null is_antibiotic_precursor: type: integer nullable: true enum: [0, 1] example: null is_drug: type: integer nullable: true enum: [0, 1] example: null is_drug_precursor: type: integer nullable: true enum: [0, 1] example: null is_explosive_precursor: type: integer nullable: true enum: [0, 1] example: null is_cmr: type: integer nullable: true enum: [0, 1] example: null is_nano: type: integer nullable: true enum: [0, 1] example: null is_controlled: type: integer nullable: true enum: [0, 1] example: null is_ed2health: type: integer nullable: true enum: [0, 1] example: null is_ed2env: type: integer nullable: true enum: [0, 1] example: null is_pbt: type: integer nullable: true enum: [0, 1] example: null is_pmt: type: integer nullable: true enum: [0, 1] example: null is_vpvb: type: integer nullable: true enum: [0, 1] example: null is_vpvm: type: integer nullable: true enum: [0, 1] example: null - description: Hierarchy mode (`?hierarchy=true`) — flat list of storage units. type: array items: type: object properties: id: type: integer example: 5 name: type: string example: Freezer A parent_id: type: integer nullable: true description: ID of parent storage unit, or null for root units. example: null full_path: type: string description: Full path from root to this unit, separated by " > ". example: "Hospital > 4th floor > Freezer A" level_depth: type: integer description: Depth in hierarchy (0 for root units). example: 2 children_count: type: integer description: Number of direct children of this storage unit. example: 3 '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Storage units'] summary: Create a new storage unit. description: Create a new storage unit. Requires permission to manage inventory locations. operationId: post-storage-unit requestBody: required: true description: Parameters for creating a storage unit. content: application/json: schema: type: object required: ['name'] properties: name: type: string description: Name of the storage unit. example: "Freezer A" parent_id: type: integer nullable: true description: ID of the parent storage unit. Set to null for a top-level unit. example: null responses: '201': description: The storage unit has been created. headers: location: description: An URL to the storage unit that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' /storage_units/{id}: summary: Actions on a specific storage unit. parameters: - name: id in: path description: ID of the storage unit. required: true schema: type: integer get: tags: ['Storage units'] summary: Read a storage unit. description: Get details of a specific storage unit including its full hierarchical path. operationId: read-storage-unit responses: '200': description: A storage unit. content: application/json: schema: $ref: '#/components/schemas/storage_unit' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Storage units'] summary: Modify a storage unit. description: | Update the name and/or the parent of a storage unit. Setting `parent_id` reparents the unit (and everything under it) in place. Pass `parent_id: null` to move the unit to the root. Requires permission to manage inventory locations. operationId: patch-storage-unit requestBody: description: Parameters for modifying a storage unit. content: application/json: schema: type: object minProperties: 1 properties: name: type: string description: New name for the storage unit. example: "Freezer B" parent_id: type: integer nullable: true description: | New parent storage unit id, or `null` to move to the root. Cannot be the unit itself or any of its descendants. example: 5 responses: '200': description: The updated storage unit. content: application/json: schema: $ref: '#/components/schemas/storage_unit' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Storage units'] summary: Delete a storage unit. description: | Delete a storage unit. Requires permission to manage inventory locations. Cannot delete a storage unit that has children or containers. operationId: delete-storage-unit responses: '204': description: The storage unit was deleted. '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': $ref: '#/components/responses/Unprocessable' # API KEYS /apikeys: summary: Manage API keys description: Handle operations on API keys. get: tags: ['Api keys'] summary: Read API keys description: Get list of API keys for currently logged in user. operationId: get-apikeys responses: '200': description: List API keys for user content: application/json: schema: type: array items: $ref: '#/components/schemas/apikey' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' post: tags: ['Api keys'] summary: Create an API key description: | Create an API key. The cleartext key is sent back in the location header. operationId: post-apikeys requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: A name for the API key. default: An API key canwrite: type: integer description: Set to 1 to allow the key to do write actions. default: 0 responses: '201': description: The key has been created. headers: location: description: A fake URL that contains the API key in cleartext schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': $ref: '#/components/responses/Unprocessable' /apikeys/{id}: summary: Actions on an api key parameters: - name: id in: path description: ID of the API key required: true schema: type: integer delete: tags: ['Api keys'] summary: Delete an API key. description: Delete an API key operationId: delete-apikey responses: '204': description: The key was deleted '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' # COMPOUNDS /compounds: summary: The instance level compounds database get: tags: ['Compounds'] summary: Read compounds description: Get the list of all compounds operationId: get-compounds responses: '200': description: List compounds content: application/json: schema: type: array items: $ref: '#/components/schemas/compound' '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Compounds'] summary: Create or import a compound description: | - If `action=duplicate`, import (or match) a compound from PubChem using `cid` or `cas`. If both parameters are present, only the `cid` is used. - Otherwise, create a compound directly from the provided fields. - If a compound with the same unique identifier already exists (e.g `cas_number`, `pubchem_cid`), the API will return the existing compound instead of creating a new one. operationId: post-compounds requestBody: required: true content: application/json: schema: oneOf: - $ref: '#/components/schemas/CompoundDuplicateRequest' - $ref: '#/components/schemas/CompoundCreateRequest' responses: '200': description: OK headers: location: description: OK schema: type: string '201': description: Created compound or existing compound returned (match on unique identifier) headers: location: description: URL to the created or matched compound schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': $ref: '#/components/responses/Unprocessable' /compounds/{id}: parameters: - name: id in: path description: ID of the compound required: true schema: type: integer get: tags: ['Compounds'] summary: Get a single compound description: Retrieve one compound by its ID operationId: get-compound responses: '200': description: A single compound content: application/json: schema: $ref: '#/components/schemas/compound' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Compounds'] summary: Soft-delete a compound description: The compound gets marked as deleted. operationId: delete-compound responses: '204': description: The compound was soft-deleted '401': $ref: '#/components/responses/Unauthorized' # CONFIG /config: summary: The general instance configuration settings get: tags: ['Config'] summary: Read the config operationId: get-config responses: '200': description: The config settings content: application/json: schema: $ref: '#/components/schemas/config' '401': $ref: '#/components/responses/Unauthorized' patch: tags: ['Config'] summary: Modify the config operationId: patch-config requestBody: description: The config values to change. content: application/json: schema: $ref: '#/components/schemas/config' responses: '200': description: The config was modified. content: application/json: schema: $ref: '#/components/schemas/config' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '422': $ref: '#/components/responses/Unprocessable' delete: tags: ['Config'] summary: Reset the config to default values operationId: delete-config responses: '204': description: The config was reset. '401': $ref: '#/components/responses/Unauthorized' # EXPERIMENTS /experiments: summary: Actions on experiments post: tags: ['Experiments'] summary: Create an experiment operationId: post-experiment requestBody: description: Parameters for creating an experiment content: application/json: schema: $ref: '#/components/schemas/entity_editable' responses: '201': description: The experiment has been created. headers: location: description: An URL to the experiment that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' get: tags: ['Experiments'] summary: Read all experiments that are accessible operationId: read-experiments parameters: *searchParams responses: '200': description: A list of experiments content: application/json: schema: type: array items: $ref: '#/components/schemas/experiment' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /experiments/{id}: summary: Actions on a specific experiment parameters: - name: id in: path description: ID of the experiment required: true schema: type: integer post: tags: ['Experiments'] summary: Duplicate an experiment with its ID operationId: post-experiment-by-id parameters: - name: id in: path required: true description: The unique identifier of the experiment to duplicate. schema: type: integer requestBody: description: Parameters for duplicating an experiment content: application/json: schema: $ref: '#/components/schemas/entity_duplicate' responses: '201': description: The experiment has been duplicated. headers: location: description: An URL to the experiment that was duplicated. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' get: tags: ['Experiments'] summary: Read an experiment operationId: get-experiment parameters: - name: format in: query schema: type: string enum: ['csv', 'eln', 'elnhtml', 'json', 'qrpdf', 'qrpng', 'pdf', 'pdfa', 'zip', 'zipa'] default: json description: | Get the entity in a different format like csv, pdf, eln or zip. "pdfa" means archive pdf (PDF/A), same with "zipa". examples: first: summary: Generate a pdf value: pdf second: summary: Generate a csv value: csv - name: json in: query schema: type: boolean default: false description: | Include a full JSON export in the ZIP archive. Only applicable if format is zip(a). examples: includeJson: summary: Include JSON in ZIP value: true excludeJson: summary: Exclude JSON in ZIP value: false - name: withTitle in: query schema: type: boolean default: true description: | Include the title in the QR code. Only applicable if format is qrpng. examples: includeTitle: summary: Include title in QR code value: true excludeTitle: summary: Exclude title in QR code value: false - name: size in: query schema: type: integer default: 250 description: | Specify the size of the QR code in pixels. Only applicable if format is qrpng. examples: mediumSize: summary: Small QR code value: 50 - name: changelog in: query schema: type: boolean default: false description: | Toggles if the changelog should be included in PDF exports (pdf, pdfa, zip, zipa). Changelog is by default included if the export provides PDF/A, otherwise not. examples: first: summary: Generate PDF exports that always includes the changelog value: true second: summary: Generate PDF exports that do not include the changelog. value: false responses: '200': description: An experiment content: application/json: schema: $ref: '#/components/schemas/entity' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Experiments'] summary: Modify an experiment operationId: patch-experiment requestBody: $ref: '#/components/requestBodies/PatchEntity' responses: '200': description: The patched experiment content: application/json: schema: $ref: '#/components/schemas/experiment' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' delete: tags: ['Experiments'] summary: Delete an experiment. description: The experiment gets soft-deleted. operationId: delete-experiment responses: '204': description: The experiment was deleted '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # INFO /info: summary: Information about the instance get: tags: ['Info'] summary: Get information about the instance. description: Get information about the instance. operationId: get-info parameters: - in: query name: hist required: false description: | Get usage information about the instance. If `hist` is present, returns cumulative histogram data for experiments, items (resources), and users. schema: type: boolean allowEmptyValue: true example: true - in: query name: columns required: false description: Number of columns (buckets) to display in histogram outputs. schema: type: integer minimum: 1 example: 120 responses: '200': description: Information about the instance content: application/json: schema: oneOf: - type: object properties: elabftw_version: type: string description: Current eLabFTW version example: 4.8.0 elabftw_version_int: type: integer description: Current eLabFTW version as an integer example: 50102 ts_balance: type: integer description: Number of timestamp tokens left example: 461 all_users_count: type: integer description: Total count of all users example: 389 active_users_count: type: integer description: Total count of active users example: 311 items_count: type: integer description: Total count of items example: 666 teams_count: type: integer description: Total count of teams example: 18 experiments_count: type: integer description: Total count of experiments example: 10189 experiments_timestamped_count: type: integer description: Total count of experiments with timestamps example: 1601 uploads_filesize_sum: type: integer description: Sum of stored filesize in MySQL for all uploads of the instance. example: 25681672 format: int64 uploads_filesize_sum_formatted: type: string description: Sum of stored filesize in MySQL for all uploads of the instance, formatted example: "24.49 MiB" - type: object description: Histogram data (when `hist` is present). properties: experiments: type: array items: type: object properties: bucket_start: type: string format: date example: "2020-01-01" total: type: integer example: 120 items: type: array items: type: object properties: bucket_start: type: string format: date example: "2020-01-01" total: type: integer example: 55 users: type: array items: type: object properties: bucket_start: type: string format: date example: "2020-01-01" total: type: integer example: 10 '401': $ref: '#/components/responses/Unauthorized' # ITEMS /items: summary: Actions on items post: tags: ['Items'] summary: Create an item operationId: post-item requestBody: description: Parameters for creating an item content: application/json: schema: $ref: '#/components/schemas/entity_editable' responses: '201': description: The item has been created. headers: location: description: An URL to the item that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' get: tags: ['Items'] summary: Read all items that are accessible operationId: read-items parameters: *searchParams responses: '200': description: A list of items content: application/json: schema: type: array items: $ref: '#/components/schemas/item' '401': $ref: '#/components/responses/Unauthorized' /items/{id}: summary: Actions on a specific item parameters: - name: id in: path description: ID of the item required: true schema: type: integer post: tags: ['Items'] summary: Duplicate an item with its ID operationId: post-item-by-id parameters: - name: id in: path required: true description: The unique identifier of the item to duplicate. schema: type: integer requestBody: description: Parameters for duplicating an item content: application/json: schema: $ref: '#/components/schemas/entity_duplicate' responses: '201': description: The item has been duplicated. headers: location: description: An URL to the item that was duplicated. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' get: tags: ['Items'] summary: Read an item operationId: get-item parameters: # Start copy paste from experiments/id - name: format in: query schema: type: string enum: ['csv', 'eln', 'elnhtml', 'json', 'qrpdf', 'qrpng', 'pdf', 'pdfa', 'zip', 'zipa'] default: json description: | Get the entity in a different format like csv, pdf, eln or zip. "pdfa" means archive pdf (PDF/A), same with "zipa". examples: first: summary: Generate a pdf value: pdf second: summary: Generate a csv value: csv - name: json in: query schema: type: boolean default: false description: | Include a full JSON export in the ZIP archive. Only applicable if format is zip(a). examples: includeJson: summary: Include JSON in ZIP value: true excludeJson: summary: Exclude JSON in ZIP value: false - name: withTitle in: query schema: type: boolean default: true description: | Include the title in the QR code. Only applicable if format is qrpng. examples: includeTitle: summary: Include title in QR code value: true excludeTitle: summary: Exclude title in QR code value: false - name: size in: query schema: type: integer default: 250 description: | Specify the size of the QR code in pixels. Only applicable if format is qrpng. examples: mediumSize: summary: Small QR code value: 50 - name: changelog in: query schema: type: boolean default: false description: | Toggles if the changelog should be included in PDF exports (pdf, pdfa, zip, zipa). Changelog is by default included if the export provides PDF/A, otherwise not. examples: first: summary: Generate PDF exports that always includes the changelog value: true second: summary: Generate PDF exports that do not include the changelog. value: false # End copy paste from experiments/id responses: '200': description: An item content: application/json: schema: $ref: '#/components/schemas/entity' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Items'] summary: Modify an item operationId: patch-item requestBody: $ref: '#/components/requestBodies/PatchItem' responses: '200': description: The patched item content: application/json: schema: $ref: '#/components/schemas/item' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '422': $ref: '#/components/responses/Unprocessable' delete: tags: ['Items'] summary: Delete an item. description: The item gets soft-deleted. operationId: delete-item responses: '204': description: The key was deleted '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IMPORT /import: summary: Import a file get: tags: ['Import'] summary: Get information about this endpoint operationId: read-import responses: '200': description: Information content: application/json: schema: type: object properties: allowed_extensions: description: allowlist of file extensions accepted for import type: array items: type: string example: [".eln", ".csv"] max_filesize: description: maximum size of an uploaded file in bytes type: integer example: 2147483648 max_upload_size: description: value of MAX_UPLOAD_SIZE env parameter type: string example: 3G max_upload_time: description: value of MAX_UPLOAD_TIME env parameter type: integer example: 900000 '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Import'] summary: Send a file to import operationId: post-import requestBody: content: multipart/form-data: schema: type: object required: ['file', 'entity_type'] properties: file: type: string format: binary description: The file to upload. entity_type: type: string example: "experiments" enum: ["experiments", "items", "experiments_templates", "items_types"] description: The target entity type category: type: integer example: 6 description: The default category ID if no category is defined for a given entry canread_base: type: number nullable: true description: | Base permission for read access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 30 enum: [10, 20, 30, 40, 50] canwrite_base: type: number nullable: true description: | Base permission for write access: - 10: Owner only - 20: Owner + Admins - 30: Team members - 40: Everyone with an account - 50: Everyone including anonymous users example: 20 enum: [10, 20, 30, 40, 50] owner: type: integer example: 5 description: Userid of future owner of imported data responses: '201': description: The import was successful headers: location: description: The number at the end is the number of imported entries schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' # EXPORT /exports: summary: Exported files get: tags: ['Exports'] summary: List exports operationId: readall-exports responses: '200': description: A list of exports content: application/json: schema: type: array items: $ref: '#/components/schemas/export' '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Exports'] summary: Register an export request operationId: post-export requestBody: content: application/json: schema: type: object required: ['format'] properties: format: type: string example: "pdf" enum: ["csv", "eln", "json", "pdf", "zip"] description: File format for the export experiments: type: string example: "on" description: Set to "on" to include experiments in the export items: type: string example: "on" description: Set to "on" to include resources in the export experiments_templates: type: string example: "on" description: Set to "on" to include experiments templates in the export items_types: type: string example: "on" description: Set to "on" to include resources categories in the export changelog: type: string example: "on" description: Set to "on" to include the changelog in PDF files json: type: string example: "on" description: Set to "on" to include a full JSON export in the ZIP archives pdfa: type: string example: "on" description: Set to "on" to create PDF files with the PDF/A specification responses: '201': description: The export request was successful headers: location: description: API URL for export record schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /exports/{id}: summary: An export request parameters: - name: id in: path description: ID of the export request required: true schema: type: integer get: tags: ['Exports'] summary: Get export operationId: read-export responses: '200': description: An export request content: application/json: schema: type: array items: $ref: '#/components/schemas/export' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Exports'] summary: Remove an export request and its associated file description: This method will remove the file from the server temporary storage and clear the export request. operationId: delete-export responses: '204': description: The file was deleted '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # COMMENTS /{entity_type}/{id}/comments: summary: Actions on comments of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer post: tags: ['Comments'] summary: Create a comment. operationId: post-entity-comments requestBody: description: Parameters for creating a comment content: application/json: schema: required: ['comment'] type: object properties: comment: type: string responses: '201': description: The comment has been created. headers: location: description: An URL to the comment that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' get: tags: ['Comments'] summary: Read all comments of that entity. operationId: read-entity-comments responses: '200': description: A list of comments content: application/json: schema: type: array items: $ref: '#/components/schemas/comment' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/comments/{subid}: summary: Actions on comment of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the comment required: true schema: type: integer get: tags: ['Comments'] summary: Read a comment of that entity. operationId: read-entity-comment responses: '200': description: A comment. content: application/json: schema: $ref: '#/components/schemas/comment' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Comments'] summary: Modify an entity comment. operationId: patch-entity-comment requestBody: description: Parameters for patching an entity comment. content: application/json: schema: $ref: '#/components/schemas/comment' responses: '200': description: The patched comment content: application/json: schema: $ref: '#/components/schemas/comment' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Comments'] summary: Delete an entity comment. description: The comment gets deleted. operationId: delete-entity-comment responses: '204': description: The comment was deleted '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # ITEMS LINKS /{entity_type}/{id}/items_links: summary: Links from entity to items. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Links to items'] summary: Read all items links of that entity. operationId: read-entity-items-links responses: '200': description: A list of links content: application/json: schema: type: array items: $ref: '#/components/schemas/link' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/items_links/{subid}: summary: Actions on items link of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the item (link) required: true schema: type: integer post: tags: ['Links to items'] summary: Create or import a link. operationId: post-entity-items-links requestBody: description: Parameters for creating or importing a link. content: application/json: schema: type: object properties: action: type: string enum: ['create', 'duplicate'] description: | The `duplicate` action will import the links of that link (inception). responses: '201': description: The link has been created. headers: location: description: An URL to the link that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Links to items'] summary: Delete an item link. description: The link gets deleted. operationId: delete-entitiy-items-link responses: '204': description: The link was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # EXPERIMENTS LINKS /{entity_type}/{id}/experiments_links: summary: Links from entity to experiments. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Links to experiments'] summary: Read all experiments links of that entity. operationId: read-entity-experiments-links responses: '200': description: A list of links content: application/json: schema: type: array items: $ref: '#/components/schemas/link' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/experiments_links/{subid}: summary: Actions on experiments link of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the experiment linked required: true schema: type: integer post: tags: ['Links to experiments'] summary: Create or import a link. operationId: post-entity-experiments-links requestBody: description: Parameters for creating or importing a link. content: application/json: schema: type: object properties: action: type: string enum: ['create', 'duplicate'] description: | The `duplicate` action will import the links of that link (inception). responses: '201': description: The link has been created. headers: location: description: An URL to the link that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Links to experiments'] summary: Delete an experiment link. description: The link gets deleted. operationId: delete-entity-experiments-link responses: '204': description: The link was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # COMPOUNDS LINKS /{entity_type}/{id}/compounds_links: summary: Compounds linked to that entity. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Links to compounds'] summary: Read all compounds links of that entity. operationId: read-entity-compounds-links responses: '200': description: A list of links content: application/json: schema: type: array items: $ref: '#/components/schemas/link' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/compounds_links/{subid}: summary: Actions on compounds link of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the compound linked required: true schema: type: integer post: tags: ['Links to compounds'] summary: Link an entity to a compound. operationId: post-entity-compounds-links requestBody: description: Parameters for creating a link. content: application/json: schema: type: object properties: action: type: string enum: ['create'] description: | The `create` action will create the link. responses: '201': description: The link has been created. headers: location: description: An URL to the link that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Links to compounds'] summary: Delete a compound link. description: The link gets deleted. operationId: delete-entity-compounds-link responses: '204': description: The link was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # EXPERIMENTS_TEMPLATES /experiments_templates: summary: Actions on experiments_templates post: tags: ['Experiments templates'] summary: Create an experiment template operationId: post-experiment_template requestBody: description: Parameters for creating an experiment template content: application/json: schema: $ref: '#/components/schemas/entity_template_editable' responses: '201': description: The experiment template has been created. headers: location: description: An URL to the experiment template that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' get: tags: ['Experiments templates'] summary: Read all experiments_templates that are accessible operationId: read-experiments_templates parameters: *searchParams responses: '200': description: A list of experiments_templates content: application/json: schema: type: array items: $ref: '#/components/schemas/entity_template' '401': $ref: '#/components/responses/Unauthorized' /experiments_templates/{id}: summary: Actions on a specific experiment template parameters: - name: id in: path description: ID of the experiment template required: true schema: type: integer post: tags: ['Experiments templates'] summary: Duplicate an experiment template with its ID operationId: post-experiment_template-by-id parameters: - name: id in: path required: true description: The unique identifier of the experiment template to duplicate. schema: type: integer requestBody: description: Parameters for duplicating an experiment template content: application/json: schema: $ref: '#/components/schemas/entity_duplicate' responses: '201': description: The experiment template has been duplicated. headers: location: description: An URL to the experiment template that was duplicated. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' get: tags: ['Experiments templates'] summary: Read an experiment template operationId: get-experiment_template responses: '200': description: An experiment template content: application/json: schema: $ref: '#/components/schemas/entity_template' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Experiments templates'] summary: Modify an experiment template operationId: patch-experiment_template requestBody: description: Parameters for modifying an experiment template content: application/json: schema: anyOf: - type: object properties: action: type: string enum: ['lock', 'pin', 'update'] - $ref: '#/components/schemas/entity_template_editable' responses: '200': description: The patched experiment template content: application/json: schema: $ref: '#/components/schemas/entity_template' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Experiments templates'] summary: Delete an experiment template. description: The experiment template gets soft-deleted. operationId: delete-experiment_template responses: '204': description: The entry was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # ITEMS_TYPES (Resources Templates) /items_types: summary: Actions on items_types (resources templates) post: tags: ['Items types (Resources Templates)'] summary: Create a resource template operationId: post-items_types requestBody: description: Parameters for creating a resource template content: application/json: schema: $ref: '#/components/schemas/entity_template_editable' responses: '201': description: The resource template has been created. headers: location: description: An URL to the resource template that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' get: tags: ['Items types (Resources Templates)'] summary: Read all resources templates that are accessible operationId: read-items_types parameters: *searchParams responses: '200': description: A list of resources templates. content: application/json: schema: type: array items: $ref: '#/components/schemas/entity_template' '401': $ref: '#/components/responses/Unauthorized' /items_types/{id}: summary: Actions on a specific resource template parameters: - name: id in: path description: ID of the resource template required: true schema: type: integer post: tags: ['Items types (Resources Templates)'] summary: Duplicate a resource template with its ID operationId: post-items_types-by-id parameters: - name: id in: path required: true description: The unique identifier of the resource template to duplicate. schema: type: integer requestBody: description: Parameters for duplicating a resource template content: application/json: schema: $ref: '#/components/schemas/entity_duplicate' responses: '201': description: The resource template has been duplicated. headers: location: description: An URL to the resource template that was duplicated. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' get: tags: ['Items types (Resources Templates)'] summary: Read a resource template operationId: get-items_type responses: '200': description: A resource template content: application/json: schema: $ref: '#/components/schemas/entity_template' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Items types (Resources Templates)'] summary: Modify a resource template operationId: patch-items_type requestBody: description: Parameters for modifying a resource template content: application/json: schema: anyOf: - type: object properties: action: type: string enum: ['lock', 'pin', 'update'] - $ref: '#/components/schemas/entity_template_editable' responses: '200': description: The patched resource template content: application/json: schema: $ref: '#/components/schemas/entity_template' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Items types (Resources Templates)'] summary: Delete a resource template. description: The resource template gets soft-deleted. operationId: delete-items_type responses: '204': description: The entry was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # EVENTS /events: summary: For scheduler booking. get: tags: ['Events'] summary: Read all events in the team. operationId: read-events responses: '200': description: A list of booked slots. content: application/json: schema: type: array items: $ref: '#/components/schemas/event' '401': $ref: '#/components/responses/Unauthorized' /events/{id}: parameters: - name: id in: path description: ID of the item to book. required: true schema: type: integer post: tags: ['Events'] summary: Create an event for the item specified as id. operationId: post-events requestBody: description: Parameters for creating an event. content: application/json: schema: type: object properties: title: type: string description: A name for this booking slot. default: Untitled example: 'This is an event.' start: type: string format: date-time description: ISO 8601 date-time with timezone offset. example: '2026-03-15T13:30:00+01:00' end: type: string format: date-time description: ISO 8601 date-time with timezone offset. example: '2026-03-15T15:30:00+01:00' responses: '201': description: The booking slot has been created. headers: location: description: An URL to the booking slot that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /event/{id}: summary: For scheduler booking. parameters: - name: id in: path description: ID of the event to modify. required: true schema: type: integer get: tags: ['Events'] summary: Read a booking slot. operationId: read-event responses: '200': description: A particular event content: application/json: schema: $ref: '#/components/schemas/event' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Events'] summary: Modify a booking slot. operationId: patch-event requestBody: description: Parameters for modifying an event. required: true content: application/json: schema: oneOf: - type: object required: [target, start, end] properties: target: type: string nullable: true enum: ['datetime'] start: type: string format: date-time description: ISO 8601 date-time with timezone offset. example: "2026-02-19T13:30:00+01:00" end: type: string format: date-time description: ISO 8601 date-time with timezone offset. example: "2026-02-19T15:30:00+01:00" - type: object properties: target: type: string enum: ['experiment', 'item_link'] id: type: integer description: Entity id. - type: object properties: target: type: string enum: ['start', 'end'] delta: type: object description: The difference (delta) of time with the previous value. properties: days: type: integer milliseconds: type: integer months: type: integer years: type: integer responses: '200': description: The patched event. content: application/json: schema: $ref: '#/components/schemas/event' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' delete: tags: ['Events'] summary: Delete a booking slot. operationId: delete-event responses: '204': description: The event was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # FAVTAGS /favtags: summary: Favorite tags for the logged-in user. get: tags: ['Favorite tags'] summary: Read all favorite tags for the user. operationId: read-favtags responses: '200': description: A list of favorite tags. content: application/json: schema: type: object properties: users_id: type: integer tags_id: type: integer tag: type: string '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Favorite tags'] summary: Add a tag as favorite. operationId: post-favtags requestBody: description: Parameters for adding a favorite tag. content: application/json: schema: type: object properties: tag: type: string description: An existing tag responses: '201': description: The favtag has been created. headers: location: description: | Favorite tags don't have an ID, so the returned URL in Location in invalid. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /favtags/{id}: summary: A particular favorite tag. parameters: - name: id in: path description: ID of the tag. required: true schema: type: integer delete: tags: ['Favorite tags'] summary: Unfavorite a tag. operationId: delete-favtag responses: '204': description: The favorite tag was removed. '401': $ref: '#/components/responses/Unauthorized' # REPORTS /reports: summary: Generate usage reports get: tags: ['Reports'] summary: Get usage reports description: Get usage reports at the instance or team level. operationId: get-reports parameters: - name: format in: query schema: type: string enum: ['csv', 'json'] default: json description: | Select the output format examples: csv: summary: Generate a CSV value: csv - name: scope in: query schema: type: string enum: ['compounds', 'compounds_history', 'instance', 'inventory', 'stored_compounds', 'team'] description: | Select the scope. Instance is for sysadmins only. Team will generate report for the current team. If scope is `compounds_history`, you can also provide `start` and `end` (format `YYYY-MM-DD`). examples: instance: summary: Get instance level report value: instance team: summary: Get team level report value: team - name: start in: query required: false schema: type: string format: date example: '2012-01-01' description: | Start date (YYYY-MM-DD). Only used when scope is `compounds_history`. - name: end in: query required: false schema: type: string format: date example: '2038-01-19' description: | End date (YYYY-MM-DD). Only used when scope is `compounds_history`. responses: '200': description: Get usage reports content: application/json: schema: type: object properties: query_parameters: type: object properties: format: type: array items: type: string scope: type: array items: type: string text/csv: schema: type: string '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' # TEAM TAGS /teams/{id}/tags: summary: Manage tags at the team level. parameters: - name: id in: path description: ID of the team. required: true schema: type: integer get: tags: ['Team tags'] summary: Read all tags for the team. operationId: read-team_tags responses: '200': description: A list of tags. content: application/json: schema: type: array items: $ref: '#/components/schemas/tag' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Team tags'] summary: Create a tag in the team. operationId: post-team_tag requestBody: description: Parameters for adding a tag in the team. content: application/json: schema: type: object properties: tag: type: string description: Tag to add responses: '201': description: The tag has been added. headers: location: description: An URL ending with 0 if the tag was already here, or an URL to the newly created tag. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /teams/{id}/tags/{subid}: summary: Retrieve a tag from its id. parameters: - name: id in: path description: ID of the team. required: true schema: type: integer - name: subid in: path description: ID of the tag. required: true schema: type: integer get: tags: ['Team tags'] summary: Read a tag. operationId: read-team_tag responses: '200': description: A tag. content: application/json: schema: $ref: '#/components/schemas/tag' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Team tags'] summary: | Actions on a tag. operationId: patch-team_tag requestBody: description: Parameters for modifying a tag. content: application/json: schema: type: object properties: action: type: string enum: ['updatetag'] tag: type: string description: The content of the tag. description: Update the tag. Requires Admin permissions. responses: '200': description: The team tag has been modified. content: application/json: schema: $ref: '#/components/schemas/tag' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Team tags'] summary: Delete a tag. operationId: delete-team_tag responses: '204': description: The tag was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # TEAMS /teams: summary: Manage teams. get: tags: ['Teams'] summary: Read all teams. Requires Sysadmin permissions. operationId: read-teams responses: '200': description: A list of teams. content: application/json: schema: type: array items: $ref: '#/components/schemas/team' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' post: tags: ['Teams'] summary: Create a new team. operationId: post-teams requestBody: description: Parameters for creating a new team. content: application/json: schema: type: object properties: name: type: string description: Team name. default: New team name responses: '201': description: The team has been created. headers: location: description: An URL to the team that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /teams/{id}: summary: Manage a team. parameters: - name: id in: path description: ID of the team or `current`. required: true schema: oneOf: - type: integer - type: string enum: ['current'] examples: first: summary: Access the current team. value: 'current' second: summary: Access team with ID 3. value: 3 get: tags: ['Teams'] summary: Read a team. Requires Admin permissions. operationId: read-team responses: '200': description: A team. content: application/json: schema: $ref: '#/components/schemas/team' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Teams'] summary: | Actions on a team. operationId: patch-team requestBody: description: Parameters for modifying a team. content: application/json: schema: oneOf: - $ref: '#/components/schemas/team' - type: object description: (Re)send the onboarding email to all users specified in the userids property. Only admins can send emails to their team members. properties: action: enum: ['sendonboardingemails'] type: string userids: description: A list of user ids for which the onboarding email shall be sent. type: array items: type: integer example: [5, 11, 7, 31] responses: '200': description: The updated team. content: application/json: schema: $ref: '#/components/schemas/team' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # EXPERIMENTS CATEGORIES /teams/{id}/experiments_categories: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer get: tags: ['Experiments categories'] summary: Read experiments categories of a team. operationId: read-team-experiments-categories responses: '200': description: A list of experiments categories for the team. content: application/json: schema: type: array items: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Experiments categories'] operationId: post-team-one-expcat summary: Create a new category for experiments. requestBody: description: Parameters for creating a category. content: application/json: schema: type: object properties: name: type: string description: Category name color: type: string description: | Hex color without leading \#. default: type: integer description: Is it the default category for the team? responses: '201': description: Create a category. headers: location: description: An URL to the category that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /teams/{id}/experiments_categories/{subid}: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer - name: subid in: path description: ID of the category. required: true schema: type: integer get: tags: ['Experiments categories'] operationId: read-team-one-expcat summary: Read a category. responses: '200': description: Read a category. content: application/json: schema: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Experiments categories'] operationId: patch-expcat summary: Modify a category. requestBody: description: Parameters for modifying a category. content: application/json: schema: $ref: '#/components/schemas/statuslike' responses: '200': description: The updated category. content: application/json: schema: $ref: '#/components/schemas/statuslike' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Experiments categories'] summary: Delete a category. operationId: delete-expcat responses: '204': description: The category was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # RESOURCES CATEGORIES /teams/{id}/resources_categories: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer get: tags: [ 'Resources categories' ] summary: Read resources categories of a team. operationId: read-team-resources-categories responses: '200': description: A list of resources categories for the team. content: application/json: schema: type: array items: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: [ 'Resources categories' ] operationId: post-team-one-rescat summary: Create a new category for resources. requestBody: description: Parameters for creating a resource category. content: application/json: schema: type: object properties: name: type: string description: Category name color: type: string description: | Hex color without leading \#. default: type: integer description: Is it the default category for the team? responses: '201': description: Create a resource category. headers: location: description: An URL to the category that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /teams/{id}/resources_categories/{subid}: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer - name: subid in: path description: ID of the category. required: true schema: type: integer get: tags: [ 'Resources categories' ] operationId: read-team-one-rescat summary: Read a category. responses: '200': description: Read a resource category. content: application/json: schema: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: [ 'Resources categories' ] operationId: patch-rescat summary: Modify a category. requestBody: description: Parameters for modifying a resource category. content: application/json: schema: $ref: '#/components/schemas/statuslike' responses: '200': description: The updated resource category. content: application/json: schema: $ref: '#/components/schemas/statuslike' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: [ 'Resources categories' ] summary: Delete a category. operationId: delete-rescat responses: '204': description: The category was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # EXPERIMENTS STATUS /teams/{id}/experiments_status: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer get: tags: ['Experiments status'] summary: Read experiments status of a team. operationId: read-team-experiments-status responses: '200': description: A list of status for the team. content: application/json: schema: type: array items: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Experiments status'] operationId: post-team-one-expstatus summary: Create a new experiments status. requestBody: description: Parameters for creating a status. content: application/json: schema: type: object properties: name: type: string description: Status name color: type: string description: | Hex color without leading \#. default: type: integer description: Is it the default status for the team? responses: '201': description: New experiments status created. headers: location: description: An URL to the experiments status that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /teams/{id}/experiments_status/{subid}: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer - name: subid in: path description: ID of the status required: true schema: type: integer get: tags: ['Experiments status'] operationId: read-team-one-expstatus summary: Read a status. responses: '200': description: Read a status. content: application/json: schema: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Experiments status'] operationId: patch-expstatus summary: Modify a status. requestBody: description: Parameters for modifying a status. content: application/json: schema: $ref: '#/components/schemas/statuslike' responses: '200': description: The updated status. content: application/json: schema: $ref: '#/components/schemas/statuslike' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Experiments status'] summary: Delete a status. operationId: delete-expstatus responses: '204': description: The status was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # TEAMS STATUS /teams/{id}/items_status: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer get: tags: ['Resources status'] summary: Read resources status of a team. operationId: read-team-items-status responses: '200': description: A list of resources status for the team. content: application/json: schema: type: array items: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Resources status'] operationId: post-team-one-resstat summary: Create a new status for resources. requestBody: description: Parameters for creating a resources status. content: application/json: schema: type: object properties: name: type: string description: Status name color: type: string description: | Hex color without leading \#. default: type: integer description: Is it the default status for the team? responses: '201': description: New resources status created. headers: location: description: An URL to the resources status that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /teams/{id}/items_status/{subid}: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer - name: subid in: path description: ID of the status required: true schema: type: integer get: tags: ['Resources status'] operationId: read-team-one-resstatus summary: Read a status. responses: '200': description: Read a status. content: application/json: schema: $ref: '#/components/schemas/statuslike' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Resources status'] operationId: patch-resstatus summary: Modify a status. requestBody: description: Parameters for modifying a status. content: application/json: schema: $ref: '#/components/schemas/statuslike' responses: '200': description: The updated status. content: application/json: schema: $ref: '#/components/schemas/statuslike' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Resources status'] summary: Delete a status. operationId: delete-resstatus responses: '204': description: The status was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # TEAMGROUPS /teams/{id}/teamgroups: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer get: tags: ['Teamgroups'] summary: Read teamgroups of a team. operationId: read-team-teamgroups responses: '200': description: A list of teamgroups for the team. content: application/json: schema: type: array items: $ref: '#/components/schemas/teamgroup' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Teamgroups'] operationId: post-teamgroups summary: Create a new teamgroup. requestBody: description: Parameters for creating a teamgroup. content: application/json: schema: type: object properties: name: type: string description: Teamgroup name responses: '201': description: New teamgroup. headers: location: description: An URL to the teamgroup that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /teams/{id}/teamgroups/{subid}: parameters: - name: id in: path description: ID of the team. required: true schema: type: integer - name: subid in: path description: ID of the teamgroup. required: true schema: type: integer get: tags: ['Teamgroups'] operationId: read-teamgroup summary: Read a teamgroup. responses: '200': description: A teamgroup. content: application/json: schema: type: object properties: id: type: integer name: type: string team: type: integer '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Teamgroups'] operationId: patch-teamgroup summary: Modify a teamgroup. requestBody: description: Parameters for modifying a teamgroup. content: application/json: schema: oneOf: - type: object properties: how: type: string enum: ['unreference', 'add'] userid: type: integer - type: object properties: name: type: string responses: '200': description: The updated teamgroup. content: application/json: schema: $ref: '#/components/schemas/teamgroup' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Teamgroups'] summary: Delete a teamgroup. operationId: delete-teamgroup responses: '204': description: The teamgroup was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # TODOLIST /todolist: summary: Todolist for current user. get: tags: ['Todolist'] summary: Read all todoitems. operationId: read-todolist responses: '200': description: A list of things to do. content: application/json: schema: type: array items: $ref: '#/components/schemas/todoitem' '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Todolist'] summary: Create a todo item operationId: post-todolist requestBody: description: Parameters for creating a todoitem. content: application/json: schema: type: object properties: content: type: string description: What to do responses: '201': description: The todo entry has been created. headers: location: description: An URL to the todo item that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /todolist/{id}: summary: Manage a todo entry. parameters: - name: id in: path description: ID of the todoitem. required: true schema: type: integer get: tags: ['Todolist'] summary: Read a todo entry. operationId: read-todoitem responses: '200': description: A todoitem. content: application/json: schema: $ref: '#/components/schemas/todoitem' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Todolist'] summary: | Actions on a todoitem. operationId: patch-todoitem requestBody: description: Parameters for modifying a todoitem. content: application/json: schema: required: ['body'] type: object properties: body: type: string responses: '200': description: The updated todoitem. content: application/json: schema: $ref: '#/components/schemas/todoitem' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Todolist'] summary: Delete a todoitem. operationId: delete-todoitem responses: '204': description: The todoitem was removed. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # UNFINISHED STEPS /unfinished_steps: summary: Unfinished steps from the user or the team, in experiments or items. parameters: - name: scope in: query description: | Set to "team" to extend the list to other members. schema: type: string default: 'user' enum: ['team', 'user'] get: tags: ['Unfinished steps'] summary: Read all unfinished steps. operationId: read-unfinished-steps responses: '200': description: A list of unfinished steps content: application/json: schema: type: array items: $ref: '#/components/schemas/unfinished_steps' '401': $ref: '#/components/responses/Unauthorized' # USERS /users: summary: Display information about users on the instance. get: tags: ['Users'] summary: Read users from instance. description: Get a list of users with an active account on the instance. operationId: read-users parameters: - name: team in: query description: Add a filter on the team required: false schema: type: integer - name: currentTeam in: query description: If set to 1, use the requester's current team as filter. required: false schema: type: integer enum: [0, 1] default: 0 - name: onlyAdmins in: query description: Return only team admins. required: false schema: type: boolean default: false - name: onlyArchived in: query description: Return only archived users. required: false schema: type: boolean default: false responses: '200': description: A list of users. Returned columns will depend if requester is Admin somewhere or not. content: application/json: schema: type: array items: oneOf: - $ref: '#/components/schemas/users' - $ref: '#/components/schemas/users_full' examples: asUser: summary: Response given to a regular user value: - userid: 4 firstname: Brook lastname: Hegmann email: brook@example.com fullname: Brook Hegmann initials: "BH" orcid: "0000-0002-7494-5555" sig_pubkey: "untrusted comment: elabftw/50300: public key 320dd30997373737\nRWQyDdMJlzc3N2zRpeiHjGYQe4cBYxw6Zh43+zc5Nm4v9gwypeYjSxai\n" asAdmin: summary: Response given to an Admin value: - userid: 5 firstname: Lara lastname: Croft email: lara@tombraider.com validated: 1 created_at: "1996-10-25 20:34:04" last_login: "2025-02-14 12:23:45" valid_until: "2025-08-29" is_sysadmin: 0 fullname: Lara Croft initials: "LC" orcid: "0000-0002-7494-5555" auth_service: 10 '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Users'] summary: Create a new user. description: | An Admin can create a user in its own team only. A sysadmin can specify the team. operationId: post-user requestBody: description: Parameters for creating a user. content: application/json: schema: required: ['firstname', 'lastname', 'email'] type: object properties: firstname: type: string description: User's first name. lastname: type: string description: User's last name. email: type: string description: User's email address. team: type: integer description: The team id. valid_until: type: string description: Date in the YYYY-MM-DD format for account expiration date. orgid: type: string description: Internal id. usergroup: type: integer description: Which permissions level the user will get? `1` is Sysadmin, `2` is Admin, `4` is user (default) enum: [1, 2, 4] responses: '201': description: The user has been created. headers: location: description: An URL to the user that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '403': $ref: '#/components/responses/Forbidden' '401': $ref: '#/components/responses/Unauthorized' /users/{id}: summary: Display information about a particular user. parameters: - name: id in: path description: ID of the user or `me`. required: true schema: oneOf: - type: integer - type: string enum: ['me'] examples: first: summary: Access our own user. value: 'me' second: summary: Access user with ID 42. value: 42 get: tags: ['Users'] summary: Read information of a user. description: | Note: it is possible to use "me" instead of the userid to access the user of the API key. operationId: read-user responses: '200': description: Public properties of a user. content: application/json: schema: $ref: '#/components/schemas/users' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Users'] summary: Modify a user. description: | Note: it is possible to use "me" instead of the userid to access the user of the API key. operationId: patch-user requestBody: description: Parameters for modifying a user. content: application/json: schema: oneOf: - $ref: '#/components/schemas/users' - type: object description: Archive or validate a user (will toggle the attribute) properties: action: type: string enum: ['archive', 'validate'] - type: object description: Add or remove a user from a team. properties: action: enum: ['add', 'unreference'] type: string team: type: integer description: ID of the team - type: object description: Disable 2FA (requires Sysadmin privilege or acting on ourself) properties: action: enum: ['disable2fa'] type: string - type: object description: Change the password properties: action: enum: ['updatepassword'] type: string current_password: type: string description: | Current password. Note: Sysadmin user doesn't need to provide it. password: type: string description: New password. - type: object description: Modify ownership of a team properties: action: enum: ['patchuser2team'] type: string team: type: integer description: ID of the team userid: type: integer description: Target userid target: type: string enum: ['group', 'is_owner'] description: The attribute to modify content: type: integer description: Binary value for `is_owner`, integer for `group` (2 for Admin, 4 for User) responses: '200': description: Public properties of a user. content: application/json: schema: $ref: '#/components/schemas/users' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' # USERS UPLOADS /users/{id}/uploads: parameters: - name: id in: path description: ID of the user or `me`. required: true schema: oneOf: - type: integer - type: string enum: ['me'] examples: first: summary: Access our own user. value: 'me' second: summary: Access user with ID 42. value: 42 get: tags: ['User Uploads'] summary: Read attached files from a user operationId: read-user-uploads responses: '200': description: Attachments from a user content: application/json: schema: type: array items: type: object properties: id: type: integer example: 113 real_name: type: string example: example.png long_name: type: string example: 25/2509b6547bcc40c7c56df0fca0930357b7c5e90c1ee59c8040091b956bbbde3cc1726169488d6d485be5b5fed3240939083d8ea708b9a153a2d57d7be1931e43.png created_at: type: string format: date-time example: 2024-06-16 12:34:51 filesize: type: integer example: 40959 type: type: string example: experiments comment: type: string nullable: true example: null entity_id: type: integer example: 311 entity_title: type: string example: image in body I page: type: string example: experiments '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # NOTIFICATIONS /users/{id}/notifications: parameters: - name: id in: path description: ID of the user or `me`. required: true schema: oneOf: - type: integer - type: string enum: ['me'] examples: first: summary: Access our own user. value: 'me' second: summary: Access user with ID 42. value: 42 get: tags: ['Notifications'] summary: Read notifications of a user. operationId: read-notifications responses: '200': description: Notifications of a user. content: application/json: schema: type: object properties: id: type: integer category: type: integer body: type: object is_ack: type: integer created_at: type: string userid: type: integer '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Notifications'] summary: Delete all notifications of the user. description: All notifications for the user are deleted. operationId: delete-notifications responses: '204': description: The notifications were deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /users/{id}/notifications/{subid}: parameters: - name: id in: path description: ID of the user or `me`. required: true schema: oneOf: - type: integer - type: string enum: ['me'] examples: first: summary: Access our own user. value: 'me' second: summary: Access user with ID 42. value: 42 - name: subid in: path description: ID of the notification. required: true schema: type: integer get: tags: ['Notifications'] summary: Read a notification. operationId: read-notification responses: '200': description: A notification. content: application/json: schema: $ref: '#/components/schemas/notification' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Notifications'] summary: Update the acknowledgment status of a notification. operationId: patch-notification requestBody: description: Defines whether the notification is acknowledged. content: application/json: schema: type: object properties: is_ack: type: integer description: Acknowledge the notification. `0` for unacknowledging, `1` for acknowledge. enum: [ 0, 1 ] responses: '200': description: The updated notification. content: application/json: schema: $ref: '#/components/schemas/notification' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # STEPS /{entity_type}/{id}/steps: summary: Show steps for this entity. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates', 'items_types'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Steps'] summary: Read all steps of that entity. operationId: read-steps responses: '200': description: A list of steps content: application/json: schema: type: array items: $ref: '#/components/schemas/step' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Steps'] summary: Create a step. operationId: post-step requestBody: description: Parameters for creating a step. content: application/json: schema: type: object properties: body: type: string description: | The text content of the step. responses: '201': description: The step has been created. headers: location: description: An URL to the step that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/steps/{subid}: summary: Actions on step of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates', 'items_types'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the step required: true schema: type: integer patch: tags: ['Steps'] summary: | Actions on a step. operationId: patch-step requestBody: description: Parameters for modifying a step content: application/json: schema: type: object required: ['action'] properties: action: type: string enum: ['finish', 'notif', 'update'] is_immutable: type: integer enum: [ 0, 1 ] body: type: string description: The text content of the step. finished: type: integer examples: first: summary: Make a step "immutable" value: is_immutable: 1 second: summary: Edit the body of a step value: body: Put on the safety gloves first. responses: '200': description: The updated step. content: application/json: schema: $ref: '#/components/schemas/step' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Steps'] summary: Delete a step. description: The step gets deleted. operationId: delete-step responses: '204': description: The step was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # TAGS /{entity_type}/{id}/tags: summary: Show tags for this entity. parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates', 'items_types'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Tags'] summary: Read all tags of that entity. operationId: read-tags responses: '200': description: A list of tags content: application/json: schema: type: array items: $ref: '#/components/schemas/tag' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Tags'] summary: Create a tag. operationId: post-tag requestBody: description: Parameters for creating a tag. content: application/json: schema: type: object oneOf: - properties: tag: type: string description: The text content of a single tag. required: [tag] - properties: tags: type: array description: A list of tags to create. items: type: string required: [tags] example: tags: ["Project Lambda", "Cell culture"] responses: '201': description: The tag has been created. headers: location: description: An URL to the tag that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Tags'] summary: Delete all tags. description: All the tags from that entity get removed. operationId: delete-tag responses: '204': description: The tags were deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/tags/{subid}: summary: Actions on tag of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates', 'items_types'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the tag required: true schema: type: integer get: tags: ['Tags'] summary: Read a tag. operationId: read-tag responses: '200': description: A tag. content: application/json: schema: $ref: '#/components/schemas/tag' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Tags'] summary: | Actions on a tag (like removing it from the entity). operationId: patch-tag requestBody: description: Parameters for modifying a tag content: application/json: schema: type: object required: ['action'] properties: action: type: string enum: ['unreference'] responses: '200': description: The updated tag. content: application/json: schema: $ref: '#/components/schemas/tag' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' # UPLOADS /{entity_type}/{id}/uploads: parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: state in: query schema: type: string default: "1" examples: first: summary: Display only archived uploads value: "2" second: summary: Display archived and deleted uploads value: "2,3" description: | Filter results based on their state: 1 (Normal), 2 (Archived), 3 (Deleted). Supports comma separated values. get: tags: ['Uploads'] summary: Read attached files of that entity. operationId: read-uploads responses: '200': description: A list of uploads. content: application/json: schema: type: array items: $ref: '#/components/schemas/upload' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Uploads'] summary: Create an upload. operationId: post-upload requestBody: description: Parameters for creating an upload. content: multipart/form-data: schema: type: object required: ['file'] properties: file: type: string format: binary description: The file to upload. comment: type: string description: Optional file comment. responses: '201': description: The file has been uploaded. headers: location: description: An URL to the uploaded file that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/uploads/{subid}: parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the upload required: true schema: type: integer get: tags: ['Uploads'] summary: Read an upload. operationId: read-upload parameters: - name: format in: query schema: type: string enum: ['binary', 'json'] default: json description: | To download the file itself, use `binary` format parameter. In python library, when downloading a file content, make sure to add ` _preload_content=False` into the call to `read_upload()`. examples: first: summary: Get the attached file value: binary responses: '200': description: | An upload. Note: with binary output, Content-Type header will vary depending of the file type being sent. content: application/json: schema: $ref: '#/components/schemas/upload' '*/*': schema: type: string format: binary '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Uploads'] summary: Replace an existing uploaded file. The existing file will be archived and the new one will be added. operationId: post-upload-replace requestBody: description: Parameters for replacing an upload. content: multipart/form-data: schema: type: object required: ['file'] properties: file: type: string format: binary description: The file to upload. comment: type: string description: Optional file comment. responses: '201': description: The file has been uploaded. headers: location: description: An URL to the uploaded file that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Uploads'] summary: | Modify attributes such as "real_name", "comment" or "state" of an upload. operationId: patch-upload requestBody: description: Parameters for modifying an upload attributes. content: application/json: schema: type: object properties: action: type: string enum: ['update'] real_name: type: string comment: type: string state: type: integer enum: [1, 2, 3] anyOf: - required: - real_name - required: - comment - required: - state responses: '200': description: The updated upload. content: application/json: schema: $ref: '#/components/schemas/upload' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Uploads'] summary: Delete an upload. description: The upload gets deleted. operationId: delete-upload responses: '204': description: The upload was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IDPS /idps: get: tags: ['Idps'] summary: Read all IDPs. operationId: read-idps responses: '200': description: A list of idps. content: application/json: schema: type: array items: $ref: '#/components/schemas/idp' '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Idps'] summary: Create an idp. operationId: post-idp requestBody: description: Parameters for creating an idp. content: application/json: schema: type: object required: ['name', 'entityid', 'email_attr'] properties: name: type: string description: A name for the IDP. entityid: type: string description: Entityid. email_attr: type: string description: What attribute to look for the email. fname_attr: type: string description: What attribute to look for the firstname. lname_attr: type: string description: What attribute to look for the lastname. team_attr: type: string description: What attribute to look for the team. nullable: true orgid_attr: type: string description: What attribute to look for the internal id. nullable: true orcid_attr: type: string description: What attribute to look for the ORCID. nullable: true responses: '201': description: The idp has been created. headers: location: description: An URL to the idp that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /idps/{id}: parameters: - name: id in: path description: ID of the idp required: true schema: type: integer get: tags: ['Idps'] summary: Read an idp. operationId: read-idp responses: '200': description: An idp. content: application/json: schema: $ref: '#/components/schemas/idp' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Idps'] summary: Actions on an idp. operationId: patch-idp requestBody: description: Parameters for modifying an idp. content: application/json: schema: type: object required: ['action'] properties: action: type: string enum: ['update'] responses: '200': description: The updated idp. content: application/json: schema: $ref: '#/components/schemas/idp' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Idps'] summary: Delete an idp. description: The idp gets deleted. operationId: delete-idp responses: '204': description: The idp was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IDP ENDPOINTS /idps/{id}/endpoints: parameters: - name: id in: path description: ID of the idp required: true schema: type: integer get: tags: ['Idps'] summary: Read all endpoints for an IdP. operationId: read-idp-endpoints responses: '200': description: A list of endpoints for this IdP. content: application/json: schema: type: array items: $ref: '#/components/schemas/idp_endpoint' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Idps'] summary: Add an endpoint to this IdP. operationId: post-idp-endpoint requestBody: description: Parameters for adding an endpoint to an IdP. content: application/json: schema: type: object required: ['location'] properties: location: type: string binding: type: string enum: [ 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' ] is_slo: type: integer enum: [0, 1] responses: '201': description: The idp endpoint has been created. headers: location: description: An URL to the idp endpoint that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IDP ENDPOINT WITH ID /idps/{id}/endpoints/{endpoint_id}: parameters: - name: id in: path description: ID of the idp required: true schema: type: integer - name: endpoint_id in: path description: ID of the idp endpoint required: true schema: type: integer get: tags: ['Idps'] summary: Read an endpoint for an IdP. operationId: read-idp-endpoint responses: '200': description: IdP endpoint content: application/json: schema: $ref: '#/components/schemas/idp_endpoint' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Idps'] summary: Delete an idp endpoint. description: The idp endpoint gets deleted. operationId: delete-idp-endpoint responses: '204': description: The idp endpoint was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IDP CERTS /idps/{id}/certs: parameters: - name: id in: path description: ID of the idp required: true schema: type: integer get: tags: ['Idps'] summary: Read all certs for an IdP. operationId: read-idp-certs responses: '200': description: A list of certs for this IdP. content: application/json: schema: type: array items: $ref: '#/components/schemas/idp_cert' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: ['Idps'] summary: Add a cert to this IdP. operationId: post-idp-cert requestBody: description: Parameters for adding a cert to an IdP. content: application/json: schema: type: object required: ['x509'] properties: x509: type: string description: PEM representation of the certificate purpose: type: integer description: | Purpose for this cert: `0` for Signing, `1` for Encryption. enum: [0, 1] responses: '201': description: The idp cert has been created. headers: location: description: An URL to the idp cert that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IDP cert WITH ID /idps/{id}/certs/{cert_id}: parameters: - name: id in: path description: ID of the idp required: true schema: type: integer - name: cert_id in: path description: ID of the idp cert required: true schema: type: integer get: tags: ['Idps'] summary: Read a cert for an IdP. operationId: read-idp-cert responses: '200': description: IdP certificate content: application/json: schema: $ref: '#/components/schemas/idp_cert' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Idps'] summary: Delete an idp cert. description: The idp cert gets deleted. operationId: delete-idp-cert responses: '204': description: The idp cert was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # IDPS SOURCES /idps_sources: get: tags: ['Idps Sources'] summary: Read all IDPs sources operationId: read-idps-sources responses: '200': description: A list of idps sources. content: application/json: schema: type: array items: $ref: '#/components/schemas/idp_source' '401': $ref: '#/components/responses/Unauthorized' post: tags: ['Idps Sources'] summary: Create an idp source. operationId: post-idp-source requestBody: description: Parameters for creating an idp source. content: application/json: schema: type: object required: ['url'] properties: url: type: string description: URL to the public XML metadata file responses: '201': description: The idp source has been created. headers: location: description: An URL to the idp source that was created. schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /idps_sources/{id}: parameters: - name: id in: path description: ID of the idps source required: true schema: type: integer get: tags: ['Idps Sources'] summary: Read an IdPs source operationId: read-idps-source responses: '200': description: An IdPs source content: application/json: schema: $ref: '#/components/schemas/idp_source' '401': $ref: '#/components/responses/Unauthorized' patch: tags: ['Idps Sources'] summary: Patch an idp source. operationId: patch-idps-source requestBody: description: Parameters for patching an idp source. content: application/json: schema: type: object required: ['action'] properties: action: type: string description: | Use `update` to toggle autorefresh, `replace` to load IdPs, `validate` to enable all associated IdPs, `finish` to invalidate all associated IdPs. enum: ['update', 'replace', 'validate', 'finish'] responses: '200': description: The updated idp source. content: application/json: schema: $ref: '#/components/schemas/idp_source' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: tags: ['Idps Sources'] summary: Delete an idp source. description: The idp source gets deleted. operationId: delete-idps-source responses: '204': description: The idp source was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # REVISIONS /{entity_type}/{id}/revisions: summary: Actions on revisions of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates'] - name: id in: path description: ID of the entity required: true schema: type: integer get: tags: ['Revisions'] summary: Read all revisions of that entity. operationId: read-entity-revisions responses: '200': description: A list of revisions for that entity content: application/json: schema: type: array items: type: object properties: id: type: integer content_type: type: integer created_at: type: string fullname: type: string '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /{entity_type}/{id}/revisions/{subid}: summary: Actions on a revision of an entity parameters: - name: entity_type in: path description: Entity type required: true schema: type: string enum: ['experiments', 'items', 'experiments_templates'] - name: id in: path description: ID of the entity required: true schema: type: integer - name: subid in: path description: ID of the revision required: true schema: type: integer get: tags: ['Revisions'] summary: Read a revision of that entity. operationId: read-entity-revision responses: '200': description: A revision. content: application/json: schema: $ref: '#/components/schemas/revision' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: ['Revisions'] summary: Restore a revision. operationId: patch-entity-revision requestBody: description: Parameters for restoring an entity revision. content: application/json: schema: type: object properties: action: type: string enum: ['replace'] description: | The `replace` action will restore the revision body to the entity. responses: '200': description: The (unchanged) revision content: application/json: schema: $ref: '#/components/schemas/revision' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' # EXTRA FIELDS KEYS /extra_fields_keys: summary: Search for custom fields keys used by a team. Results are sorted by frequency. parameters: - name: q in: query description: | Search for a term in the custom fields keys. schema: type: string default: '' - name: limit in: query description: | Number of custom fields keys that will be returned. Value >= -1; -1: no limit, 0: users default setting from UCP. schema: type: integer default: 0 get: tags: ['Custom Fields Keys'] summary: Read custom fields keys. operationId: custom-fields-keys responses: '200': description: A list of custom fields keys and their frequency. content: application/json: schema: type: array items: $ref: '#/components/schemas/extra_fields_keys' '401': $ref: '#/components/responses/Unauthorized' # DSPACE /dspace: summary: Interact with the connected DSpace repository. get: tags: ['DSpace'] summary: Read DSpace information. operationId: dspace-read parameters: - name: action in: query description: | Action to perform: - `getcollections`: list available DSpace collections. - `gettypes`: list DSpace item types (submission vocabularies). If omitted or invalid, the endpoint returns an error explaining valid usage. required: true schema: type: string enum: ['getcollections', 'gettypes'] responses: '200': description: | Result depends on the `action` parameter: - `getcollections`: list of collections. - `gettypes`: list of vocabulary entries. **DSpace REST API documentation** - https://wiki.lyrasis.org/display/DSDOC9x/Community+and+Collection+management - https://github.com/DSpace/RestContract/blob/main/collections.md - https://github.com/DSpace/RestContract/blob/main/entitytypes.md content: application/json: schema: oneOf: - type: array description: Collections array returned by DSpace. items: type: object required: - id - uuid - name - type properties: id: type: string format: uuid description: Collection identifier. example: "1abcd2c3-45db-6a7-aeee-8d932f883d70" uuid: type: string format: uuid description: Collection UUID (same value as id). example: "1abcd2c3-45db-6a7-aeee-8d932f883d70" name: type: string description: Human-readable collection name. example: "your-collection" handle: type: string description: Persistent DSpace handle. example: "10673/1221" archivedItemsCount: type: integer description: Number of archived items in the collection. example: 27 type: type: string example: "collection" metadata: type: object description: DSpace metadata fields grouped by key. additionalProperties: type: array items: type: object properties: value: type: string example: "your-collection" language: type: string nullable: true example: null authority: type: string nullable: true example: null confidence: type: integer example: -1 place: type: integer example: 0 _links: type: object description: HAL links for the collection. properties: self: type: object properties: href: type: string format: uri parentCommunity: type: object properties: href: type: string format: uri workflowGroups: type: array items: type: object properties: name: type: string example: "reviewer" href: type: string format: uri - type: object description: Types returned by DSpace vocabulary endpoint. properties: _embedded: type: object properties: entries: type: array items: type: object required: - value - display - type properties: value: type: string description: Internal type value. example: "Animation" display: type: string description: Human-readable label. example: "Animation" type: type: string example: "vocabularyEntry" example: - id: "1abcd2c3-45db-6a7-aeee-8d932f883d70" uuid: "1abcd2c3-45db-6a7-aeee-8d932f883d70" name: "your-collection" handle: "10673/1221" archivedItemsCount: 27 type: "collection" metadata: dc.title: - value: "your-collection" language: null authority: null confidence: -1 place: 0 _links: self: href: "https://demo.dspace.org/server/api/core/collections/1abcd2c3-45db-6a7-aeee-8d932f883d70" workflowGroups: - name: "reviewer" href: "https://demo.dspace.org/server/api/core/collections/1abcd2c3-45db-6a7-aeee-8d932f883d70/workflowGroups/reviewer" '401': $ref: '#/components/responses/Unauthorized' post: tags: ['DSpace'] summary: Create a new DSpace workspace item. operationId: dspace-create requestBody: required: true content: application/json: schema: type: object required: ['collection', 'metadata'] properties: collection: type: string description: UUID of the DSpace collection to submit to. example: "1abcd2c3-45db-6a7-aeee-8d932f883d70" metadata: type: array description: Metadata fields to populate the submission. items: type: object required: ['key', 'value'] properties: key: type: string example: "dc.title" value: type: string example: "The role of science in modern society" responses: '201': description: The workspace was successfully created. headers: Location: description: Last part of the URL is the workspace ID schema: type: string format: uri example: https://elab.local:3148/api/v2/dspace/1799 Cache-Control: description: Cache policy applied to this response schema: type: string example: max-age=0, private, must-revalidate, no-cache, private content: text/html: schema: type: string '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' patch: tags: ['DSpace'] summary: Submit an eLabFTW entry to DSpace. operationId: dspace-submit requestBody: required: true content: application/json: schema: type: object required: ['collection', 'metadata', 'entity'] properties: collection: type: string description: UUID of the collection. example: "1abcd2c3-45db-6a7-aeee-8d932f883d70" metadata: type: array description: > DSpace metadata entries. At minimum, dc.title is required by most DSpace configurations. items: type: object required: ['key', 'value'] properties: key: type: string example: "dc.title" value: type: string example: "Ipsum quidem excepturi aut et aut sit vitae." example: - key: "dc.title" value: "Ipsum quidem excepturi aut et aut sit vitae." - key: "dc.type" value: "Dataset" - key: "dc.date.issued" value: "2025-12-19" - key: "dc.description.abstract" value: "This entry explores the impact of photonic materials." entity: type: object required: ['type', 'id'] properties: type: type: string description: eLabFTW entity type. example: "experiments" id: type: integer description: ID of the entity to export. example: 42 responses: '200': description: Submission was successful. content: application/json: schema: type: object properties: id: type: integer example: 123 uuid: type: string example: "1abcd2c3-45db-6a7-aeee-8d932f883d70" publicUrl: type: string example: "https://demo.dspace.org/items/67e4e922-1d80-489f-9fd9-afba71ce6283" '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized'