The HTTP interface of the Biotoolkit Monomer Service. It is the interface Ideation and the other Biotoolkit services use, and it is available to your own integrations.
Base URL and Swagger UI
| Item | Value |
|---|---|
| Base path | https://<host>/HELM2MonomerService/rest |
| Swagger UI | https://<host>/HELM2MonomerService/ |
| OpenAPI document | https://<host>/HELM2MonomerService/rest/openapi.json |
| Version | GET /rest/Version returns the deployed service version as plain text |
Ask your Discngine contact for the host of your deployment. The Swagger UI is the authoritative description of the request and response schemas for the version you are running.
Authentication
Every request carries a JWT, presented as Authorization: Bearer <token> and issued through the Discngine Admin Center. The token identifies your organisation, and every read and write is scoped to it: you see the public library and your own monomers, and nobody else's. A request without a valid token is answered with 401.
Every write is attributed to the user the token names, in the first of its username, name, login and email claims: that is the account the version history and the audit columns show. A token that names no user is attributed to System.
Public monomers are readable by everyone and writable by nobody: a write against one returns 403.
Error envelope
Errors carry a JSON body with an outcome and a message:
outcome |
Status | Meaning |
|---|---|---|
INVALID_PARAMETER |
400 | A path or query parameter is not acceptable |
NOT_FOUND |
404 | No monomer, rule or image matches |
VALIDATION_FAILED |
409 | The monomer violates a rule: duplicate symbol, duplicate structure, duplicate name, missing field, malformed R-groups. A duplicate adds conflictingSymbol and conflictingMonomerId, naming the existing monomer; a duplicate name also adds conflictingName. |
ALIAS_CONFLICT |
409 | A name is already taken: an alias equal to a symbol or an alias in your scope, or a new symbol equal to an alias. Adds conflictingAlias when the obstacle is an alias, and conflictingSymbol and conflictingMonomerId naming the monomer that holds the name. |
ARCHIVED_MATCH |
409 | The symbol or structure matches a deleted monomer. Adds matchType and archived[]; revive it, or repeat the PUT with force=true. |
MONOMER_UNREADABLE |
500 | A stored monomer cannot be served, for example because one of its cap groups is not in the vocabulary. Adds kind (CAP_RESOLUTION or STRUCTURE_CONVERSION); the message names the monomer and the reason. Nothing is written by a request that hits it. Report it to Discngine support. |
INTERNAL_ERROR |
500 | Unexpected failure |
SERVICE_MISCONFIGURED |
503 | The deployment is not configured for the operation. Retrying does not help; report it to Discngine support. |
503 means the database or the chemistry service is unavailable, and carries Retry-After: 30. 501 means the operation is not supported by the storage backend of the deployment.
Monomers
{polymertype} is PEPTIDE, RNA or CHEM. Read operations also accept ALL.
| Method | Path | Description |
|---|---|---|
GET |
/monomer/{polymertype} |
List monomers. Query: monomertype, filter with filterField set to name or symbol (which also matches aliases), limit, offset. The search is case-insensitive. Returns {offset, limit, total, monomers: [...]}; a monomer appears once, under its symbol, however many of its aliases match. |
GET |
/monomer/{polymertype}/{symbolOrId} |
One monomer. A segment made only of digits is read as an identifier, anything else as a name: a symbol or an alias, matched case-exactly. Pass by=symbol or by=id to force it. Found by an alias, the response is still the monomer's own record, with its real symbol. version=<n> on an identifier returns an archived version. |
PUT |
/monomer/{polymertype}/{symbol} |
Create or update the monomer with that symbol. Body: a monomer object. force=true registers a new monomer even when a deleted one matches; without it the request is refused with ARCHIVED_MATCH. aliases=replace applies the body's aliases; onStructureConflict=alias turns a known structure into an alias. See Aliases. chiralFlagAbsent sets how a molfile without the chiral flag is read; see Molfiles and the chiral flag. |
DELETE |
/monomer/{polymertype}/{symbolOrId} |
Delete, archiving the state. force=true also removes the monomer from its monomer sets. purge=true erases the monomer and all its archived versions, irreversibly. force and purge cannot be combined. |
GET |
/monomer/{polymertype}/{id}/versions |
Archived versions, newest first. Empty for a monomer with no history. |
GET |
/monomer/{polymertype}/{symbolOrId}/stereoAnalysis |
The stereo analysis of a monomer against the one it was resolved from: monomer, resolvedFrom, sameGraph, compatible, reason, resolvedGroups[], centres[] (one per stereocentre: parentAtom, childAtom, element, parentLabel, childLabel, configuration as same or inverted, verdict) and warnings[]. resolvedFrom is null and centres empty on a monomer with no link. See Enhanced Stereochemistry. |
GET |
/monomer/{polymertype}/{symbolOrId}/stereoisomers |
The registered stereoisomers of a monomer, in the caller's tenant and the public data: monomer, id, isomerLabel, statement, resolvedFrom and stereoisomers[], one entry per monomer of the same skeleton with relation (enantiomer, racemate, unknownForm, resolvedForm, labelSibling, diastereomer, otherStereoisomer), link (resolvedFrom, resolvedChild or null), id, symbol, name, isomerLabel, statement (abs, &, or, mixed), smiles and status (live or retired). Computed from the stored structures; an empty list for a monomer without stereocentre. See Enhanced Stereochemistry. |
POST |
/monomer/{polymertype}/{id}/revive |
Put a deleted monomer back under its identifier, with its metadata and set memberships. 409 when a live monomer holds its symbol, name or structure. |
POST |
/monomer/export |
Export monomers as a file. Body: format (sdf, csv, xlsx, smiles, json), structure (rgroup, the stored form with its attachment points, or capped, each attachment point replaced by its cap group), delimiter for CSV, and monomers (a list of {polymerType, id} or {polymerType, symbol}, at most 5000) or filter (the list route's parameters). Returns {format, structure, filename, contentType, exported, skipped, warnings, content} (contentBase64 for xlsx). The other form travels in each record as RGROUP_CXSMILES or CAPPED_CXSMILES; a monomer that cannot be capped is exported in its stored form with a NOT_CAPPABLE warning. See How to Export Monomers. |
Monomer object
{
"symbol": "Deg",
"name": "Diethylglycine",
"polymerType": "PEPTIDE",
"monomerType": "Backbone",
"naturalAnalog": "X",
"smiles": "CCC(CC)(N[*:1])C([*:2])=O",
"author": "M. Curie",
"aliases": ["Et2Gly"],
"isomerLabel": null,
"resolvedFrom": null,
"resolvedFromId": null,
"rgroups": [
{"label": "R1", "capGroupName": "H", "capGroupSMILES": "[*:1][H]", "alternateId": "R1-H"},
{"label": "R2", "capGroupName": "OH", "capGroupSMILES": "O[*:2]", "alternateId": "R2-OH"}
]
}
symbol, name, polymerType, monomerType and a structure, smiles or molfile, are required. id, createDate and versionNo are server-owned and ignored on input. aliases is always present on output, [] when there are none, and lists your organisation's aliases and the public ones; on input it is ignored unless the PUT carries aliases=replace. capGroupSMILES may be omitted: it is derived from the cap group name. See Monomer Fields.
Three fields carry enhanced stereochemistry; see Enhanced Stereochemistry:
| Field | On input | On output |
|---|---|---|
isomerLabel |
Optional, 10 characters, trimmed. Accepted only on a structure whose canonical key carries an or group. Part of the uniqueness rule next to the structure. | Always present, null when unset. |
resolvedFrom |
Optional: the symbol of the monomer this one resolves, in your library or in the public one, live or retired. The structure must then be one of the stereoisomers that monomer stands for, or the request is refused with 409. |
The symbol, read from the archive when the parent is retired; null when unset. |
resolvedFromId |
Optional, with resolvedFrom: the parent's identifier as read back. Kept as long as it still carries that symbol, so a symbol reused after a retirement cannot repoint the monomer. |
The parent's identifier. |
A smiles is returned as CXSMILES when the structure carries a stereo group, for example C[C@@H](N[*:1])C([*:2])=O |&1:1|; a molfile as V3000.
Molfiles and the chiral flag
| Query parameter | Values | Effect |
|---|---|---|
chiralFlagAbsent |
racemic (default), absolute |
How a molfile in the body is read when it draws stereocentres with the chiral flag off and no STEABS, STERAC or STEREL collection. racemic, the MDL standard: all those centres in one &1 group. absolute: as drawn. A molfile with the flag or with collections, and a smiles, are read the same either way. Any other value is a 400. |
Accepted on PUT /monomer/{polymertype}/{symbol}, POST /monomer/import and POST /structure/sdf/smiles. See Enhanced Stereochemistry.
A structure stating stereochemistry the library cannot store is refused, with 409 on PUT and a validation: error on an import row, rather than stored as something else:
| Message starts with | Meaning |
|---|---|
Enhanced stereochemistry on bonds (the MDLV30/STEB… collection …) is not supported |
The molfile carries a STEBABS, STEBRACn or STEBRELn collection: an E/Z mixture, an unknown double-bond geometry or an atropisomer axis group |
Axial chirality is not supported (the stereo on atom <n>, …) |
Stereo on a biaryl axis, an allene end or a spiro ring system that the canonical key cannot keep |
Validation messages returned with 409:
| Message | Meaning |
|---|---|
Symbol already exists |
Creation with a symbol in use |
Symbol does not exist |
Update of an unknown symbol |
Duplicate SMILES structure exists |
Same canonical structure as a live monomer of the polymer type |
Monomer has no Symbol, Monomer has no Natural Analog |
Missing field |
Monomer has wrong Monomertype: <value> |
monomerType names no monomer type, for a creation as for an edit |
Monomer has no R-Groups |
No attachment point in the structure |
Number of RGroups does not start by one or does not raise correctly |
Labels are not R1, R2, … without a gap |
Number of R-Groups in Attachmentlist is NOT equal to number of R-Groups in Smiles |
rgroups and the structure disagree |
Labels of RGroups do not match |
An rgroups label has no dummy atom |
An isomer label ('A') is only allowed on a structure that carries an OR enhanced-stereo group … |
isomerLabel on an absolute or racemic structure, or over 10 characters |
Resolved from 'Phx1': no monomer of that symbol in your library or in the public data |
resolvedFrom unknown, or naming the monomer itself |
Resolved from 'Phx1': not the same molecular graph once stereo is removed …, … atom 10 (C) is absolute in the parent and inverted here, … the same stereo statement as the parent: nothing is resolved … |
The structure is not one of the stereoisomers the parent stands for. The message names the centre or the rule. |
The structure of 'Phx1' cannot change: 2 monomer(s) were resolved from it (Phx3, Phx4) … |
A structure change on a monomer that has resolved children. Everything else about it may change. |
A successful PUT carries an X-Monomer-Outcome header: CREATED, UPDATED, or ALIASED when nothing was registered because the symbol became an alias. It may also carry one or more X-Monomer-Warning headers, percent-encoded. The write stands in every case:
- a resolved monomer settled an or group the same way as the child of a labelled sibling, where mirror images were expected; the same text is in
warnings[]of the stereo analysis; - a stereo group said nothing about the structure, which is a meso form: The stereo group &1 (atoms 3, 8) says nothing about this structure: inverting its centres gives the same molecule (a meso form), so its centres are registered as absolute. The monomer is keyed as drawn, so the same compound sent again with or without the group is a duplicate.
Stereoisomers of a monomer
GET /monomer/PEPTIDE/Phx3/stereoisomers, for Phx3 registered as the L form resolved from the unknown Phx1 (label A), with Phx4 its D form resolved from Phx2 (label B) and a racemate racPhx:
{
"monomer": "Phx3",
"id": 1203,
"isomerLabel": null,
"statement": "abs",
"resolvedFrom": "Phx1",
"stereoisomers": [
{
"relation": "enantiomer",
"link": null,
"id": 1204,
"symbol": "Phx4",
"name": "D-phenylalanine analogue",
"isomerLabel": null,
"statement": "abs",
"smiles": "O=C([*:2])[C@H](Cc1ccccc1)N[*:1]",
"status": "live"
},
{
"relation": "unknownForm",
"link": "resolvedFrom",
"id": 1201,
"symbol": "Phx1",
"name": "Phenylalanine analogue, flask A",
"isomerLabel": "A",
"statement": "or",
"smiles": "O=C([*:2])[C@@H](Cc1ccccc1)N[*:1] |o1:3|",
"status": "live"
},
{
"relation": "unknownForm",
"link": null,
"id": 1202,
"symbol": "Phx2",
"name": "Phenylalanine analogue, flask B",
"isomerLabel": "B",
"statement": "or",
"smiles": "O=C([*:2])[C@@H](Cc1ccccc1)N[*:1] |o1:3|",
"status": "retired"
},
{
"relation": "racemate",
"link": null,
"id": 1200,
"symbol": "racPhx",
"name": "Phenylalanine analogue, racemate",
"isomerLabel": null,
"statement": "&",
"smiles": "O=C([*:2])[C@@H](Cc1ccccc1)N[*:1] |&1:3|",
"status": "live"
}
]
}
The same call on Phx1 lists Phx3 as resolvedForm with link: "resolvedChild", Phx4 as resolvedForm, Phx2 as labelSibling and racPhx as racemate. On racPhx, the four others are resolvedForm. Live entries come first, then retired ones; within each group the symbols are sorted. A client that suggests a substitution reads relation and keeps the entries whose status is live.
Aliases
A monomer answers to its symbol and to any number of aliases. Your aliases are visible to your organisation only, and may name your own monomers or public ones; public aliases are read-only. Within a polymer type a name, symbol or alias, points to one monomer, case-sensitively, and an alias cannot contain /. See Monomer Aliases.
| Method | Path | Description |
|---|---|---|
POST |
/monomer/{polymertype}/{symbolOrId}/aliases |
Add an alias owned by your organisation. Body: {"alias": "Sar"}. The monomer is addressed as on GET, by identifier, symbol or alias, and may be public. Returns 200 with the monomer and its aliases. |
DELETE |
/monomer/{polymertype}/{symbolOrId}/aliases/{alias} |
Remove one of your organisation's aliases. Returns 200 with the monomer and its remaining aliases; 404 when your organisation has no alias of that name on the monomer, which is also the answer for a public alias. |
{polymertype} is PEPTIDE, RNA or CHEM on these paths. An alias is stored trimmed, case kept, and at most 500 characters long.
On PUT /monomer/{polymertype}/{symbol}:
| Query parameter | Effect |
|---|---|
aliases=replace |
Your organisation's aliases of the monomer become exactly the body's aliases, in the same transaction as the monomer: names missing from the list are removed, [] removes them all. Public aliases in the list are ignored, so a body read by GET can be sent back unchanged. Without the parameter, the body's aliases is ignored. |
onStructureConflict=alias |
When the structure is already registered under another symbol, the request symbol is added as an alias of that monomer instead of being refused. Nothing else of the body is written. The answer is 200 with X-Monomer-Outcome: ALIASED and the existing monomer. The default, reject, keeps the 409. |
A refused alias, 409 ALIAS_CONFLICT or 400 for a / or an over-long name, leaves nothing written. GET /svg/{polymertype}/{name} also accepts an alias. DELETE /monomer/... and the versions and revive paths do not: they take a symbol or an identifier.
HELM validation and conversion in the other Biotoolkit services accept aliases and keep them as written in their output. They read the library through a cache, so a new alias can take up to five minutes to be accepted there.
Bulk import
| Method | Path | Description |
|---|---|---|
POST |
/monomer/import |
Import a batch. Body: a JSON array of monomer objects, or multipart/form-data with a file part in JSON, SDF, CSV or XLSX. format= overrides the extension. mode=async queues the job. onStructureConflict=alias registers a known structure under a new symbol as an alias, as on PUT. chiralFlagAbsent sets how the molfiles are read; see Molfiles and the chiral flag. |
GET |
/monomer/import/{jobId} |
Job status. Redirects with 303 to the result once finished. |
GET |
/monomer/import/{jobId}/result |
Per-row outcome, status 207. |
GET |
/monomer/import/capabilities |
The limits of the deployment: row caps, upload size, formats. |
A synchronous import returns 207 directly and is limited to 100 rows by default. Above that, or above the upload size, the service answers 413 with the instruction to use mode=async. An asynchronous import returns 202 with a Location header to poll. An organisation is limited to a few submissions per minute and a few concurrent jobs; 429 and 503 name the limit that was hit.
Flat-file conventions for this endpoint: column names are matched ignoring case, spaces, underscores and hyphens; CSV is semicolon-delimited; the rgroups cell is R1:H;R2:OH in one quoted cell; SDF data fields R1 to R10 carry the cap group names. Aliases come from an aliases column or SDF field, /-separated, or a JSON aliases array; they are added to the monomer the row lands on, never removed. Unlike the application's import page, name and monomer_type are required here.
Result body:
{
"rows": [
{"index": 0, "symbol": "Ahp", "status": "CREATED", "errors": []},
{"index": 1, "symbol": "MeNva", "status": "ALREADY_EXISTS_SYMBOL", "errors": ["already-exists: symbol MeNva"]},
{"index": 2, "symbol": "PEG2", "status": "FAILED", "errors": ["validation: Invalid cap group \"OME\" for R2. Valid values: H, OH, NH2, Azide, Ethynyl"]}
],
"counts": {"created": 1, "updated": 0, "alreadyExists": 1, "duplicateStructure": 0, "failed": 1, "aliased": 0},
"total": 3
}
Rows keep the input order. ALREADY_EXISTS_SYMBOL and DUPLICATE_STRUCTURE are benign: the monomer is already there. ALIASED, with onStructureConflict=alias, means the row's symbol was added as an alias of the monomer that has the structure, and is counted in aliased. FAILED is the only error status; an alias refused for a row fails that row, with an alias-conflict: message naming the monomer that holds the name. Error strings start with a category, parse:, validation:, conversion:, duplicate-structure:, already-exists:, aliased:, alias-conflict:, timeout:, persist: or failed:, and never contain database or toolkit internals; a reference such as (ref: 1a2b3c4d5e6f) lets Discngine support find the detail. Re-submitting a batch is safe: the key is the symbol within the polymer type.
Cap groups
The cap group vocabulary: the groups that can close an attachment point. Your organisation's vocabulary is the public cap groups plus its own, whose codes never repeat a public one.
| Method | Path | Description |
|---|---|---|
GET |
/capgroup |
Your organisation's active vocabulary as {"capGroups": [{"code": "OH", "name": "Hydroxyl", "template": "O[*:{n}]"}, ...]}. template is the cap's SMILES, with {n} standing for the R-group number. |
GET |
/capgroup/manage |
Every cap group your organisation owns, active or not, and the active public ones: code, name, template, description, active, displayOrder, origin (system or tenant), overridesSystem, and effective (the row your organisation resolves for that code). |
POST |
/capgroup |
Create a cap group of your organisation. Body: {"code", "name", "template", "description", "active", "displayOrder"}. 201 with the row as /capgroup/manage lists it and a Location of capgroup/{code}; 409 when your organisation already has that code, or when it is the code of a public cap group, active or not, compared case-insensitively. |
PUT |
/capgroup/{code} |
Replace the name, template, description, active and displayOrder of one of your organisation's cap groups. The code cannot change: a body code that differs from the path is a 400. active: true reactivates it; leaving active out keeps its state. |
DELETE |
/capgroup/{code} |
Deactivate one of your organisation's cap groups. Returns {"code": ..., "outcome": "deactivated"}. |
DELETE |
/capgroup/{code}?purge=true |
Delete it instead, only when none of your organisation's monomers uses it: otherwise 409, with the number of monomers in monomers, and the cap group is kept. Deactivate it instead. Returns {"code": ..., "outcome": "purged"}. |
POST |
/capgroup/refresh |
Reload the service's working copy of the vocabulary, so that a cap group added to it is accepted without a redeployment. Returns {"Refresh": "valid", "capGroups": <n>, ...}, or {"Refresh": "kept", "Reason": ...} with status 200 when nothing usable came back and the vocabulary already in place was kept. It changes nothing in the vocabulary itself. |
Rules for a cap group's fields, the same as on the application's Cap groups page: code at most 50 characters, without ,, ; or :, and not manage or refresh; name at most 250 characters, without , or ;; template at most 500 characters, carrying [*:{n}] exactly once and no space; description at most 1000 characters; displayOrder an integer or null. A field that breaks a rule is a 400 naming the field.
The write endpoints address your organisation's cap groups only: a public code, and another organisation's code, are 404, and the public organisation never writes (403). They check no role. Every write reaches the other Biotoolkit services, which reload your vocabulary.
See Attachment Points and CAP Groups and How to Manage Your Organisation's Cap Groups.
Structure conversions
Two conversions that write nothing.
| Method | Path | Description |
|---|---|---|
POST |
/structure/sdf/smiles |
The SMILES of each molfile of an SD file, as the service stores structures: canonical, [*:n] attachment points, enhanced-stereo block when there is one. Body: the SD file, text/plain. chiralFlagAbsent as above. Returns {"chiralFlagAbsent": "racemic", "records": [{"index": 1, "smiles": "..."}, {"index": 2, "error": "..."}]}, one entry per record in file order; a record is the text before a $$$$ line. |
POST |
/structure/capped |
A structure that is not registered, with each R-group replaced by its cap group: the capping of GET /monomer/{polymertype}/{id}/capped, on the body. Body: {"smiles": "...", "rgroups": [{"label": "R1", "capGroupName": "H"}, ...]}. Returns {smiles, molfile, svg}; 422 with CAP_GROUP_UNRESOLVED or NOT_CAPPABLE as on the stored route. |
Images
| Method | Path | Description |
|---|---|---|
GET |
/svg/{polymertype}/{symbol} |
The stored drawing, image/svg+xml. The segment may also be an alias. |
PUT |
/svg/{polymertype}/{symbol} |
Regenerate the drawing of one private monomer |
PUT |
/svg/{polymertype} |
Regenerate the drawings of all private monomers of the type |
Rules
HELM business rules, evaluated by the notation toolkit when a sequence is validated.
| Method | Path | Description |
|---|---|---|
GET |
/rule |
All rules |
GET |
/rule/{id} |
One rule |
PUT |
/rule |
Create or update the rule in the body |
DELETE |
/rule/{id} |
Delete |
Related
- Import File Format: the same fields as the columns of an import file
- Versioning and Deletion: the semantics of
versions,revive,forceandpurge