With Invert’s external API, users can request data from the Invert database programmatically using SQL queries. The steps required to do this are outlined below:
Receive a token from Auth0
Tokens for API requests are issued through Auth0. In order to get a valid token use the following command:
curl --request POST \\ --url <https://invert.eu.auth0.com/oauth/token> \\ --header 'content-type: application/json' \\ --data '{"client_id":"<CLIENT_ID>","client_secret":"<CLIENT_SECRET>","audience":"<https://api.invertbio.com/","grant_type":"client_credentials>"}'CLIENT_ID and CLIENT_SECRET will be shared with you separately. The token returned by Auth0 will be valid for 24 hours and will be need to be sent along with each SQL request.
The response will look like this:
{"access_token":"<ACCESS_TOKEN>","expires_in":86400,"token_type":"Bearer"}Requests to and Responses from the API
The views that are available are listed below along with an example request, response and a description of each key in the returned JSON object:
v_bioprocesses✅*parents of bioprocesses (
parent_id) have been moved to a separate table calledexperimentscurl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_bioprocesses LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "6576cf59d1e997545cccc10f", "external_id": "P001", "name": "P001", "parent_id": "6576cf59d1e997545cccc12d", "scheduled_start_timestamp": null, "scheduled_end_timestamp": null, "start_timestamp": "2022-04-01 08:12:00.000000 +00:00", "run_start_timestamp": "2022-04-01 09:12:00.000000 +00:00", "run_end_timestamp": "2022-04-10 18:00:00.000000 +00:00", "end_timestamp": "2022-04-10 18:00:00.000000 +00:00", "duration_ms": 809280000, "status": "Completed", "qc": { "status": "Pass" }, "data": [ { "unit": "", "value": "1", "quantity_id": "65b967abdb81c851c2fdaa38", "measurement_info": { "labels": {} } } ], "events": [ { "id": "65b967abdb81c851c2fdaa38", "event_type": "DbRemovalEvent", "operator": null, "timestamp": { "$date": 1648890720000 }, "user_hash": null, "lot_number": "123", "sample_name": null, "removal_type": "Sample" } ], "induction_event": null, "attachments": [ { "id": "65b967abdb81c851c2fdaa38", "type": "svg" } ], "lineage": null, "last_updated_at": "2024-08-07 19:00:13.718092 +00:00" } ]
Field Name | Type | Description |
| String | Unique identifier for the bioprocess |
| String | An external identifier for the bioprocess. |
| String | Name of the bioprocess. |
| String or null | Identifier of the parent bioprocess, if this is a child process. |
| String or null | Scheduled start time of the bioprocess, in ISO 8601 format. |
| String or null | Scheduled end time of the bioprocess, in ISO 8601 format. |
| String | Record start time of the bioprocess, in ISO 8601 format with timezone. |
| String or null | Start time of the bioprocess run, if different from start_timestamp. |
| String or null | End time of the bioprocess run, if applicable. |
| String | Record end time of the bioprocess, in ISO 8601 format with timezone. |
| Number | Duration of the bioprocess in milliseconds. |
| String |
|
|
|
|
|
|
|
|
|
|
|
|
|
| { |
|
| Quality control information. |
|
| Array of objects | List of data objects associated with the bioprocess. |
| Array[ | List of events associated with the bioprocess. |
| Object or null | Information about the induction event, if applicable. |
| Array | List of attachments associated with the bioprocess. |
| Object or null | Information about the lineage of the bioprocess, if applicable. |
| String | Timestamp of the last update to this bioprocess record, in ISO 8601 format with timezone. |
events
Field Name | Type | Description |
| Object | Unique identifier for the event, typically a MongoDB ObjectId. |
| String | Identifier indicating the type of event. |
| String or null | Name or identifier of the operator associated with the event. |
| Object | Timestamp of when the event occurred, in MongoDB date format. |
| String or null | Hash identifier for the user associated with the event. |
Additional fields are present depending on the specific event type, as indicated by the event_type field.
Common Event Types
DbObservationEvent
Field Name | Type | Description |
| String | Textual observation or comment. |
DbAdditionEvent
Field Name | Type | Description |
| String or null | Lot number of the added material. |
| String or null | Name of the reagent added. |
| String | Type of addition (e.g., "Reagent Bolus", "Feed Start", “Induction”, “Inoculation”). |
| { |
|
| Volume of material added |
|
DbRemovalEvent
Field Name | Type | Description |
| { |
|
| Volume of material removed. |
|
| String or null | Lot number associated with the removal. |
| String or null | Name or identifier of the sample removed. |
| String | Type of removal (e.g., "Sample", "Harvest"). |
DbBioprocessPhaseEvent
Field Name | Type | Description |
| String | Name of the bioprocess phase (e.g., "growth", "production"). |
| String | Indicator of the phase timing (e.g., "start", "end"). |
v_timeseries✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_timeseries LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>{ "data":[ { "id": "667a6c31be82a1281d4391b7", "bioprocess_id": "667a6c2bbe82a1281d439071", "quantity_id": "667a6c2ebe82a1281d4390e9", "start_timestamp": "2022-03-10 23:45:00.000000 +00:00", "end_timestamp": "2022-03-11 23:40:00.000000 +00:00", "duration_ms": 86100000, "unit": "kilogram / meter ** 3", "statistics": { "max": 3.40585542404352, "min": 0.998, "sum": 7.22385542404352, "last": 3.40585542404352, "count": 3, "first": 0.998, "arithmetic_mean": 2.4079518080145066, "standard_deviation": 1.0252738561518857 }, "last_updated_at": "2024-06-25 07:21:20.000000 +00:00" } ], "status": { "state":"success", "message":"Statement executed successfully." } }
Field Name | Type | Description |
| String | Unique identifier for the timeseries. |
| String | Identifier of the associated bioprocess. |
| String | Identifier of the associated quantity. |
| String | Start time of the timeseries, in ISO 8601 format with timezone. |
| String | End time of the timeseries, in ISO 8601 format with timezone. |
| Number | Duration of the timeseries in milliseconds. |
| String | Unit of measurement for the timeseries data. |
| Object | Statistical summary of the timeseries data (see below) |
| String | Timestamp of the last update to this timeseries record, in ISO 8601 format with timezone. |
statistics
Field Name | Type | Description |
| Number or null | Maximum value in the timeseries. |
| Number or null | Minimum value in the timeseries. |
| Number | Sum of all values in the timeseries. |
| Number or null | Last value in the timeseries. |
| Number | Number of data points in the timeseries. |
| Number or null | First value in the timeseries. |
| Number or null | Average (mean) of all values in the timeseries. |
| Number or null | Standard deviation of values in the timeseries. |
v_timeseries_data✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_timeseries_data LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>{ "data":[ { "id":"65b13d63e53c7e9b890bf564", "timestamp":"2022-11-17T06:22:00Z", "value":271.769989, } ], "status": { "state":"success", "message":"Statement executed successfully." } }
Field Name | Type | Description |
| String | Identifier of the timeseries this data point belongs to. |
| String | Timestamp of the data point, in ISO 8601 format with timezone. |
| Number or null | The recorded value at this timestamp. Can be null if no value was recorded. |
|
|
|
Relationship to v_timeseries Model
This data points model is closely related to the v_timeseries Data Model:
The
idin this model is a ref to theidin thev_timeseriesData Model.The range of timestamps in these data points would fall within the
start_timestampandend_timestampof the parent timeseries.The values recorded here would be used to calculate the statistics stored in the
statisticsobject of the parent timeseries.
v_quantities✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_quantities LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>{ "data": [ { "id": "624c91c35b026e398a34ecd8", "name": "Temperature", "alternative_names": [ "Temperature" ], "is_timeseries": true, "data_type": "any", "default_unit": "K", "default_ingestion_unit": "K", "base_units": { "kelvin": 1.0 }, "molar_mass": null, "notes": null, "last_updated_at": "2024-08-07 18:38:09.995152 +00:00" } ], "status": { "state": "success", "message": "Statement executed successfully." } }
Field Name | Type | Description |
| String | Unique identifier for the quantity |
| String | Identifier for the organization associated with this quantity. |
| String | Primary name of the quantity. |
| Array of Strings | List of alternative names for the quantity. |
| Boolean | Indicates whether this quantity represents time series data. |
| String | The data type of the quantity |
| String | The default unit for this quantity, if applicable. Empty string if not applicable. |
| String | The default unit used when ingesting data for this quantity. Empty string if not applicable. |
| Object | An object representing the base units for this quantity. Empty object if not applicable. |
| Number or null | The molar mass of the quantity, if applicable. Null if not applicable. |
| String or null | Additional notes about the quantity. Null if no notes are provided. |
| String | Timestamp of the last update to this quantity record, in ISO 8601 format with timezone. |
v_formulas✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_formulas LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>{ "data": [ { "id": "64245761ef554eeaeb57ed69", "name": "Base flow - integral + derivative", "formula": "time_derivative_hours(time_integral_hours(A))", "log_scale": false, "disable_interpolation": false, "default_unit": null, "run_phase": null, "notes": null, "state": "ready", "last_updated_at": "2024-08-07 18:51:00.373285 +00:00" } ], "status": { "state": "success", "message": "Statement executed successfully." } }Note: state has a default of
readyfor all. Not used anymore
Field Name | Type | Description |
| String | Unique identifier for the formula |
| String | Name of the formula. |
| String | The actual formula or calculation to be applied. |
| Boolean | Indicates whether the formula should be applied on a logarithmic scale. |
| Boolean | Indicates whether interpolation should be disabled for this formula. |
| String or null | The default unit for the formula's result, if applicable. |
| String or null | The phase of the run during which this formula is applicable, if specified. |
| String or null | Additional notes or comments about the formula. |
| String | The current state of the formula (e.g., "ready"). |
| String | Timestamp of the last update to this formula record, in ISO 8601 format with timezone. |
Example Formulas
The formula field shows a variety of calculations, including:
Simple references:
"A","B"Basic arithmetic:
"(A+B+C)/3","A+B"More complex calculations:
"(A*3)*B/100"Time-based operations:
"time_derivative_hours(A)","time_integral_hours(A*2)"Advanced statistical operations:
"log_linear_regression(A)"
v_formula_results✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_formula_results LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>{ "data": [ { "id": "66c193efff71545c6a62445f" "formula_id": "66c193efff71545c6a62445e", "bioprocess_id": "63a1b74769a6451527ac2e5a", "timeseries_id": "624c91c45b026e398a34eef9", "unit": "L/h", "data": { "value": null }, "timeseries": { "data": [ 68.30666666666666, 20.457333333333334, 0.17431666666666668, 28.011666666666667, 2.8011666666666666, ... ], "times_ms": [ 0, 720000, 1440000, 2160000, 2880000 ] }, "timeseries_start_timestamp": "2019-09-25T17:59:09.000000+00:00", "timeseries_offset_ms": 720000, "timeseries_statistics_min": 0.00455133333333, "timeseries_statistics_max": 288.861, "timeseries_statistics_arithmetic_mean": 31.12353122273333, "timeseries_statistics_standard_deviation": 22.12794769405346, "timeseries_statistics_sum": 35792.060906143335, "timeseries_statistics_first": 68.30666666666666, "timeseries_statistics_last": 60.41233333333333, "timeseries_statistics_count": 1150, "last_updated_at": "2024-08-18T06:25:50.514747+00:00" } ], "status": { "state": "success", "message": "Statement executed successfully." } }
Field Name | Type | Description |
| String | Unique identifier for the formula results |
| String | Identifier of the formula used for the calculation. |
| String | Identifier of the bioprocess to which the formula was applied. |
| String | Unit of measurement for the result. Can be empty string if not applicable. |
| Object or null | Contains a single value result if the formula doesn't produce a time series (see example). |
| Object or null | Contains time series data if the formula produces multiple values over time. |
| String | Start time of the time series in ISO 8601 format. |
| Number | Time offset in milliseconds. |
| Number | Minimum value in the time series. |
| Number | Maximum value in the time series. |
| Number | Arithmetic mean of the time series values. |
| Number | Standard deviation of the time series values. |
| Number | Sum of all values in the time series. |
| Number | First value in the time series. |
| Number | Last value in the time series. |
| Number | Number of data points in the time series. |
| String | Timestamp of the last update to this formula result, in ISO 8601 format with timezone. |
When timeseries is not null, it has the following structure:
Field Name | Type | Description |
| Array of Numbers | The series of calculated values over time. |
| Array of Numbers | Timestamps in milliseconds corresponding to each data point. |
When data is not null, it represents a single-point value.
v_experiments✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_experiments LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "6576cf59d1e997545cccc10f", "external_id": "P001", "scheduled_start_timestamp": "2022-04-01 08:12:00.000000 +00:00", "scheduled_end_timestamp": "2022-04-10 18:00:00.000000 +00:00", "last_updated_at": "2024-08-07 19:00:13.718092 +00:00" } ]
Field Name | Type | Description |
| String | Unique identifier for the bioprocess |
| String | An external identifier for the experiment. |
| String or null | Scheduled start time of the bioprocess, in ISO 8601 format. |
| String or null | Scheduled end time of the bioprocess, in ISO 8601 format. |
| String | Timestamp of the last update to this bioprocess record, in ISO 8601 format with timezone. |
v_material_streams✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_material_streams LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "6576cf59d1e997545cccc10f", "name": "P001", "start_timestamp": null, "end_timestamp": null, "unit_operation_id": "6576cf59d1e997545cccc12d", "data": [ { "unit": "", "value": "1", "quantity_id": "65b967abdb81c851c2fdaa38", "measurement_info": { "labels": {} } } ] "is_global_material_stream": "true", "last_updated_at": "2024-08-07 19:00:13.718092 +00:00" } ]
Field Name | Type | Description |
| String | Unique identifier |
| String | Name of the material stream. |
| String or null | Start time in ISO 8601 format. |
| String or null | End time in ISO 8601 format. |
| String or null | Identifier of the associated unit operation |
| Boolean |
|
| Array of objects | List of data objects |
| String | Timestamp of the last update to this record, in ISO 8601 format with timezone. |
v_unit_operations✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_unit_operations LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "6576cf59d1e997545cccc10f", "external_id": "P001", "name": "P001", "experiment_id": "6576cf59d1e997545cccc12d", "run_start_timestamp": "2022-04-01 09:12:00.000000 +00:00", "run_end_timestamp": "2022-04-10 18:00:00.000000 +00:00", "status": "Completed", "qc_status": "Pass", "qc_failure_mode": "Contaminated", "unit_operation_type_id": "6576cf59d1e997545cccc12f", "last_updated_at": "2024-08-07 19:00:13.718092 +00:00" } ]
Field Name | Type | Description |
| String | Unique identifier |
| String | An external identifier for the unit operation. |
| String | Name of the unit operation. |
| String or null | Identifier of the associated experiment |
| String or null | Start time of the run, |
| String or null | End time of the run, |
| String |
|
|
|
|
|
|
|
|
|
|
|
|
|
| String | Quality control information. |
| String | Quality control information. |
| Object or null | Identifier of the associated unit operation type |
| String | Timestamp of the last update to this record, in ISO 8601 format with timezone. |
v_unit_operation_types✅curl -H "Authorization: Bearer <AUTH0_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_unit_operation_types LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "6576cf59d1e997545cccc10f", "name": "Fermentation", "icon": "BioReactor", "last_updated_at": "2024-08-07 19:00:13.718092 +00:00" } ]
Field Name | Type | Description |
| String | Unique identifier |
| String | Name of the unit operation type |
| String or null | Name of the icon |
| String | Timestamp of the last update to this record, in ISO 8601 format with timezone. |
Example Queries
Delta Loads
Request data that was produced after a given date and time. Be careful about use of single and double quotation marks in the request:
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d "{\\"statement\\": \\"SELECT * FROM v_bioprocesses WHERE last_updated_at > '2024-07-29' LIMIT 1\\"}" \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "6576cf59d1e997545cccc10f", "external_id": "P001", "name": "P001", "parent_id": "6576cf59d1e997545cccc12d", "scheduled_start_timestamp": null, "scheduled_end_timestamp": null, "start_timestamp": "2022-04-01 08:12:00.000000 +00:00", "run_start_timestamp": "2022-04-01 09:12:00.000000 +00:00", "run_end_timestamp": "2022-04-10 18:00:00.000000 +00:00", "end_timestamp": "2022-04-10 18:00:00.000000 +00:00", "duration_ms": 809280000, "status": "Completed", "qc": { "status": "Pass" }, "data": [ { "unit": "", "value": "1", "quantity_id": "6576cf59d1e997545cccc12e", "measurement_info": { "labels": {} } } ], "events": [ { "id": "65f325ba173cb161679f2a8e", "event_type": "DbRemovalEvent", "operator": null, "timestamp": { "$date": 1648890720000 }, "user_hash": null, "lot_number": "123", "sample_name": null, "removal_type": "Sample" } ], "induction_event": null, "attachments": [ { "type": "svg", "id": "65b967abdb81c851c2fdaa38" } ], "lineage": null, "last_updated_at": "2024-08-07 19:00:13.718092" } ]Get timeseries that have been updated since a bioprocess has been last updated:
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d "{\\"statement\\": \\"SELECT * FROM v_timeseries WHERE last_updated_at > (SELECT MAX(last_updated_at) FROM v_bioprocesses)\\"}" \\ <https://api.invertbio.com/external/v1/statements/>[ { "id": "63d3c8f0ffc87037935d2bdb", "bioprocess_id": "63d3c8efffc87037935d2bd9", "quantity_id": "624c91c35b026e398a34ecd8", "start_timestamp": "2023-01-27 13:04:00.000000 +00:00", "end_timestamp": "2023-01-27 13:40:00.000000 +00:00", "duration_ms": 2160000, "unit": "kelvin", "statistics": { "max": 298.08, "min": 297.91, "sum": 1191.87, "last": 298.08, "count": 4, "first": 297.91, "arithmetic_mean": 297.9675, "standard_deviation": 0.06647367900154534 }, "last_updated_at": "2024-08-09 10:12:01.698130 +00:00" } ]Get timeseries data for a timeseries that has been updated after a certain time:
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d "{\\"statement\\": \\"SELECT * from v_timeseries WHERE last_updated_at > '2024-7-29 12:00:00' LIMIT 1" \\ <https://api.invertbio.com/external/v1/statements/> # Get the timeseries id from the returned timeseries and use belowcurl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d "{\\"statement\\": \\"SELECT * from v_timeseries_data WHERE id = '66adca37bb9191ddb2399dd9'" \\ <https://api.invertbio.com/external/v1/statements/>View Joins
Get bioprocesses associated to a timeseries:
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{ "statement": "SELECT t.*, b.* FROM v_timeseries t LEFT JOIN v_bioprocesses b ON t.bioprocess_id = b.id LIMIT 1" }' \\ <https://api.invertbio.com/external/v1/statements/>{ "data": [ { "id": "66a909a765c87f6133d0c891", "bioprocess_id": "66a794a8dc52bf7bb99de415", "quantity_id": "66a909a765c87f6133d0c890", "start_timestamp": "2021-07-14T08:41:00Z", "end_timestamp": "2021-07-15T15:41:00Z", "duration_ms": 104400000, "unit": "kilogram / meter ** 3", "statistics": { "max": 8, "min": 3, "sum": 33, "last": 8, "count": 6, "first": 3, "arithmetic_mean": 5.5, "standard_deviation": 1.707825127659933 }, "last_updated_at": "2024-08-13T09:24:27.369424", "external_id": "Trial_test_011", "name": "Trial_test_011", "parent_id": "65b13ca4c229cb2b93c5adae", "scheduled_start_timestamp": null, "scheduled_end_timestamp": null, "run_start_timestamp": "2021-07-14T10:41:00Z", "run_end_timestamp": "2021-07-15T15:41:00Z", "status": "Completed", "qc": null, "data": [], "events": [], "induction_event": null, "attachments": [], "lineage": null, } ], "status": { "state": "success", "message": "Statement executed successfully." } }Error States
Timeouts: Long running requests (>30 seconds) will be terminated and return a
504. If you suspect that the amount of data is very large, please modify your query to reduce/chunk the amount of data.Unauthenticated: If the token that is sent with the request is invalid or expired, the response from the API will be
{"message":"Unauthorized"}. Please try getting a new Auth0 token and try your request again.SQL execution errors:
Query does not return any data -
{ "data":[], "status":{"state":"success", "message":"Statement executed successfully, but returned no results."} }Syntax errors - Here, the use of double quotes around the date is causing a syntax error
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_bioprocesses WHERE last_updated_at > "2024-07-29" LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/> { "detail": [ { "type": "json_invalid", "loc": ["body", 69], "msg": "JSON decode error", "input": {}, "ctx": { "error": "Expecting ',' delimiter" } } ] }Non-existent view -
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \\ -H "Content-Type: application/json" \\ -X POST \\ -d '{"statement": "SELECT * FROM v_non_existent_view LIMIT 1"}' \\ <https://api.invertbio.com/external/v1/statements/> { "data": [], "status": { "state": "error", "message": "(psycopg2.errors.UndefinedTable) relation \\"v_non_existent_view\\" does not exist" } }
Unexpected exceptions: all other exceptions will return:
{ "data":[], "status":{"state":"error", "message":"Error executing statement"} }We will be notified when this occurs, but please let us know if it continues to be problematic.
