LabKey
client libraries provide flexible authentication mechanisms and automatically handle cookies & sessions, CSRF tokens, marshalling of parameters & payloads, and returning results in native data structures that are easy to manipulate. We strongly recommend using them to interact programmatically with LabKey Server.
If absolutely required (e.g., a client library does not exist for your preferred language), you can interact with a LabKey Server through
direct HTTP requests, as covered in this topic. Note that this requires significantly more effort than using a LabKey client library.
Topics
Overview
The HTTP Interface exposes a set of API endpoints that accept parameters & JSON payloads and return JSON results. These may be called from any program capable of making an HTTP request and decoding the JSON format used for responses (
e.g., C++, C#,
etc.).
This document describes the API actions that can be used by HTTP requests, detailing their URLs, inputs and outputs. For information on using the JavaScript helper objects within web pages, see
JavaScript API. For an example of using the HTTP Interface from Perl, see
Example: Access APIs from Perl.
Calling API Actions from Client Applications and Scripts
The API actions documented below may be used by any client application or script capable of making an HTTP request and handling the response. Consult your programming language’s or operating environment’s documentation for information on how to submit an HTTP request and process the response. Most modern languages include HTTP and JSON libraries or helpers.
Several actions accept or return information in the JavaScript Object Notation (JSON) format, which is widely supported. See
https://json.org for information on the format, and to obtain libraries/plug-ins for most languages.
Basic Authentication
Most API actions require the user to be authenticated so that the correct permissions can be evaluated. Clients should use basic authentication over HTTPS so that the headers will be encrypted.
LabKey Server uses form-based authentication by default for all user-agents (browsers). However, it will also accept http basic authentication headers if presented. This can be useful for command line tools that you might use to automate certain tasks.
For instance, to use wget to retrieve a page readable by 'user1' with password 'secret' you could write:
wget <<protectedurl>> --user user1 --password secret
See
https://en.wikipedia.org/wiki/Basic_authentication_scheme for details on the HTTP headers to include, and how to encode the user name and password. The "realm" can be set to any string, as the LabKey server does not support the creation of multiple basic authentication realms. The credentials provided can be a username & password combination or an API key, as described in more detail on
this page.
Additional details about HTTP authentication can be found
here.
CSRF Token
Important: All mutating API actions (including insertRows, updateRows, and deleteRows) require a CSRF token in addition to user credentials. (For background and rationale, see
Cross-Site Request Forgery (CSRF) Protection.) CSRF tokens are handled automatically by the client libraries, but code that invokes APIs via direct HTTP must obtain a CSRF token, send it with every API request. Follow these steps:
- Execute a GET request to the whoAmI API:
https://<MyServer>/<MyProject>/<MyFolder>/login-whoAmI.api
- Retrieve the CSRF token from the JSON response
- Send the "X-LABKEY-CSRF" cookie back to the server on every request. Note: Many HTTP libraries will re-send server cookies automatically.
- Add an "X-LABKEY-CSRF" header with the value of the CSRF token to every request. Note: Many HTTP libraries have a mechanism for setting an HTTP header globally.
You can verify that your code is correctly handling CSRF tokens by invoking the test csrf action and ensuring a success response:
https://<MyServer>/<MyProject>/<MyFolder>/login-csrf.api
If you are looking for information on building a custom login page, see
Modules: Custom Login Page.
The following sections document the supported API actions in the current release of LabKey Server.
For further examples of these actions in use, plus a tool for experimenting with "Get" and "Post" parameters, see
Examples: Controller Actions / API Test Page
Query Controller API Actions
selectRows Action
The selectRows action may be used to obtain any data visible through LabKey’s standard query grid views.
Example URL where "<MyServer>", "<MyProject>", and "<MyFolder>" are placeholders for your server, project, and folder names:
https://<MyServer>/<MyProject>/<MyFolder>/query-selectRows.api?schemaName=lists&query.queryName=my%20list
HTTP Method: GET
Parameters: Essentially, anything you see on a query string for an existing query grid is legal for this action.
The following table describes the basic set of parameters.
Parameter | Description |
---|
schemaName | Name of a public schema. |
query.queryName | Name of a valid query in the schema. |
query.viewName | (Optional) Name of a valid custom grid view for the chosen queryName. |
query.columns | (Optional) A comma-delimited list of column names to include in the results. You may refer to any column available in the query, as well as columns in related tables using the 'foreign-key/column' syntax (e.g., 'RelatedPeptide/Protein'). If not specified, the default set of visible columns will be returned. |
query.maxRows | (Optional) Maximum number of rows to return (defaults to 100) |
query.offset | (Optional) The row number at which results should begin. Use this with maxRows to get pages of results. |
query.showAllRows | (Optional) Include this parameter, set to true, to get all rows for the specified query instead of a page of results at a time. By default, only a page of rows will be returned to the client, but you may include this parameter to get all the rows on the first request. If you include the query.showAllRows parameter, you should not include the query.maxRows nor the query.offset parameters. Reporting applications will typically set this parameter to true, while interactive user interfaces may use the query.maxRows and query.offset parameters to display only a page of results at a time. |
query.sort | (Optional) Sort specification. This can be a comma-delimited list of column names, where each column may have an optional dash (-) before the name to indicate a descending sort. |
query.<column-name>~<oper>=<value> | (Optional) Filter specification. You may supply multiple parameters of this type, and all filters will be combined using AND logic. The list of valid operators are as follows: eq = equals neq = not equals gt = greater-than gte = greater-than or equal-to lt = less-than lte = less-than or equal-to dateeq = date equal (visitdate~dateeq=2001-01-01 is equivalent to visitdate >= 2001-01-01:00:00:00 and visitdate < 2001-01-02:00:00:00) dateneq = date not equal neqornull = does not equal or is null isblank = is null isnonblank = is not null contains = contains doesnotcontain = does not contain startswith = starts with doesnotstartwith = does not start with in = equals one of a semi-colon delimited list of values ('a;b;c'). Examples: query.BodyTemperature~gt=98.6 https://www.labkey.org/home/query-executeQuery.view?schemaName=core&query.queryName=Modules&query.Name~eq=API |
Response Format:The response can be parsed into an object using any one of the many JSON parsers available via
https://www.json.org.
The response object contains four top-level properties:
- metaData
- columnModel
- rows
- rowCount
metaData: This property contains type and lookup information about the columns in the resultset. It contains the following properties:
Property | Description |
---|
root | The name of the property containing rows. This is mainly for the Ext grid component. |
totalProperty | The name of the top-level property containing the row count (in our case). This is mainly for the Ext grid component. |
sortInfo | The sort specification in Ext grid terms. This contains two sub-properties, field and direction, which indicate the sort field and direction (“ASC” or “DESC”) respectively. |
id | The name of the primary key column. |
fields | an array of field information. name = name of the field type = JavaScript type name of the field lookup = if the field is a lookup, there will be three sub-properties listed under this property: schema, table, and column, which describe the schema, table, and display column of the lookup table (query). |
columnModel: The columnModel contains information about how one may interact with the columns within a user interface. This format is generated to match the requirements of the Ext grid component. See
Ext.grid.ColumnModel for further information.
rows: This property contains an array of rows, each of which is a sub-element/object containing a property per column.
rowCount: This property indicates the number of total rows that could be returned by the query, which may be more than the number of objects in the rows array if the client supplied a value for the query.maxRows or query.offset parameters. This value is useful for clients that wish to display paging UI, such as the Ext grid.
updateRows Action
The updateRows action allows clients to update rows in a list or user-defined schema. This action may not be used to update rows returned from queries to other LabKey module schemas (e.g., ms2, flow, etc). To interact with data from those modules, use API actions in their respective controllers.
Example URL: https://<MyServer>/<MyProject>/<MyFolder>/query-updateRows.api
HTTP Method: POST
POST body: The post body should contain JSON in the following format:
{"schemaName": "lists",
"queryName": "Names",
"rows": [
{"Key": 5,
"FirstName": "Dave",
"LastName": "Stearns"}
]
}
Content-Type Header: Because the post body is JSON and not HTML form values, you must include the 'Content-Type' HTTP header set to 'application/json' so that the server knows how to parse the incoming information.
The schemaName and queryName properties should match a valid schema/query name, and the rows array may contain any number of rows. Each row must include its primary key value as one of the properties, otherwise, the update will fail.
By default, all updates are transacted together (meaning that they all succeed or they all fail). To override this behavior, include a 'transacted': false property at the top level. If 'transacted' is set to 'false', updates are not automatic and partial updates may occur if an error occurs mid-transaction. For example, if some rows have been updated and an update produces an error, the rows that have been updated before the error will still be updated.
The response from this action, as well as the insertRows and deleteRows actions, will contain JSON in the following format:
{ "schemaName": "lists",
"queryName": "Names",
"command": "update",
"rowsAffected": 1,
"rows": [
{"Key": 5,
"FirstName": "Dave",
"LastName": "Stearns"}
]
}
The response can be parsed into an object using any one of the many JSON parsers available via
https://www.json.org.
The response object will contain five properties:
- schemaName
- queryName
- command
- rowsAffected
- rows
The
schemaName and
queryName properties will contain the same schema and query name the client passed in the HTTP request. The
command property will be "update", "insert", or "delete" depending on the API called (see below). These properties are useful for matching requests to responses, as HTTP requests are typically processed asynchronously.
The
rowsAffected property will indicate the number of rows affected by the API action. This will typically be the same number of rows passed in the HTTP request.
The
rows property contains an array of row objects corresponding to the rows updated, inserted, or deleted, in the same order as the rows supplied in the request. However, the field values may have been modified by server-side logic, such as LabKey's automatic tracking feature (which automatically maintains columns with certain names, such as "Created", "CreatedBy", "Modified", "ModifiedBy", etc.), or database triggers and default expressions.
insertRows Action
Example URL: https://<MyServer>/<MyProject>/<MyFolder>/query-insertRows.api
HTTP Method: POST (GET effective version 23.6)
Content-Type Header: Because the post body is JSON and not HTML form values, you must include the 'Content-Type' HTTP header set to 'application/json' so that the server knows how to parse the incoming information.
The post body for insertRows should look the same as updateRows, except that primary key values for new rows need not be supplied if the primary key columns are auto-increment.
deleteRows Action
Example URL: https://<MyServer>/<MyProject>/<MyFolder>/query-deleteRows.api
HTTP Method: POST
Content-Type Header: Because the post body is JSON and not HTML form values, you must include the 'Content-Type' HTTP header set to 'application/json' so that the server knows how to parse the incoming information.
The post body for deleteRows should look the same as updateRows, except that the client need only supply the primary key values for the row. All other row data will be ignored.
executeSql Action
This action allows clients to execute SQL.
Example URL: https://<MyServer>/<MyProject>/<MyFolder>/query-executeSql.api
HTTP Method: POST
Post Body:The post body should be a JSON-encoded object with two properties:
schemaName and
sql. Example:
{
schemaName: 'study',
sql: 'select MyDataset.foo, MyDataset.bar from MyDataset'
}
The response comes back in exactly the same shape as the selectRows action, which is described at the beginning of the Query Controller API Actions section of this page.
Project Controller API Actions
getWebPart Action
The getWebPart action allows the client to obtain the HTML for any web part, suitable for placement into a <div> defined within the current HTML page.
Example URL: https://<MyServer>/<MyProject>/<MyFolder>/project-getWebPart.api?webpart.name=Wiki&name=home
HTTP Method: GET
Parameters: The “webpart.name” parameter should be the name of a web part available within the specified container. Look at the
Select Web Part drop-down menu for the valid form of any web part name.
All other parameters will be passed to the chosen web part for configuration. For example, the Wiki web part can accept a “name” parameter, indicating the wiki page name to display. Note that this is the page name, not the page title (which is typically more verbose).
Assay Controller API Actions
assayList Action
The assayList action allows the client to obtain a list of assay definitions for a given folder. This list includes all assays visible to the folder, including those defined at the folder and project level.
Example URL: https://<MyServer>/<MyProject>/<MyFolder>/assay-assayList.api
HTTP Method: POST
Parameters: None
Post Body: None
Return value: Returns an array of assay definition descriptors.
Each returned assay definition descriptor includes the following properties (this list is not exhaustive):
Property | Description |
---|
Name | String name of the assay, such as "Cell Culture" |
protocolSchemaName | The full schema/type/assay name, such as "assay.General.Cell Culture" |
id | Unique integer ID for the assay. |
Type | String name of the assay type. "ELISpot", for example. |
projectLevel | Boolean indicating whether this is a project-level assay. |
description | String containing the assay description. |
domainTypes | The domains included, such as Batch, Run, Result/Data, etc. |
domains | An object mapping from String domain name to an array of domain property objects. (See below.) |
Domain property objects include the following properties (this list is not exhaustive):
Property | Description |
---|
name | The String name of the property. |
typeName | The String name of the type of the property. (Human readable.) |
typeURI | The String URI uniquely identifying the property type. (Not human readable.) |
label | The String property label. |
description | The String property description. |
formatString | The String format string applied to the property. |
required | Boolean indicating whether a value is required for this property. |
lookupContainer | If this property is a lookup, this contains the String path to the lookup container or null if the lookup in the same container. Undefined otherwise. |
lookupSchema | If this property is a lookup, this contains the String name of the lookup schema. Undefined otherwise. |
lookupQuery | If this property is a lookup, this contains the String name of the lookup query. Undefined otherwise. |
Troubleshooting Tips
If you hit an error, here are a few "obvious" things to check:
Spaces in Parameter Names. If the name of any parameter used in the URL contains a space, you will need to use "%20" or "+" instead of the space.
Controller Names: "project" vs. "query" vs "assay." Make sure your URL uses the controller name appropriate for your chosen action. Different actions are provided by different controllers. For example, the "assay" controller provides the assay API actions while the "project" controller provides the web part APIs.
Container Names: Different containers (projects and folders) provide different schemas, queries and grid views. Make sure to reference the correct container for your query (and thus your data) when executing an action.
Capitalization: The parameters schemaName, queryName and viewName are case sensitive.
Related Topics