Confident LIMS API v0
These are the official docs for the v0 API. Version 0 is currently under active development and is not yet considered stable — as such, there may be breaking changes introduced without incrementing the version number.
API Endpoints
All endpoints use the standard HTTP verbs to describe their behavior (GET, POST, PUT, DELETE) and use status codes to categorize their responses (200, 301/302, 400, 401, 403, 404, 405, 500). In general, a correctly signed and formatted request will return with status code 200.
When sending data, use a correctly escaped querystring for GET
endpoints or a standard form upload
(application/x-www-form-urlencoded) for POST/PUT/DELETE.
If you are using a request library, this is likely handled for you
automatically.
Request bodies are form-encoded, not JSON. The API
does not accept application/json request bodies. Endpoints
that take complex objects (like creating an order) accept a
JSON-encoded string as a single form field — each endpoint's reference
documents this.
Every endpoint returns a JSON formatted response. After receiving a
200, you should always check the success field to see if
your request completed as expected.
GET requests generally always succeed, but any POST/PUT/DELETE request
can fail because of pre-requisites or invalid state (like a name
conflict or requiring something to exist), which will set the
success flag to false. When
success is false, there will be an
error_code field (and potentially
error_message and error_details) to help you
identify and react to whatever caused the problem.
Response Envelope
Every response body has roughly the same pieces:
success— true/false flag that is always presenterror_code— a string code if an error occurred (always present whensuccessis false)error_message— a human readable error messageerror_details— per-field validation errors whenerror_codeisinvalid_request, keyed by field name
Common error codes returned by every endpoint:
| Code | Status | Meaning |
|---|---|---|
missing_api_key |
401 | Missing X-ConfidentLims-APIKey header |
invalid_api_key |
401 | API key is not valid (deleted, not found, etc.) |
invalid_credentials_type |
401 | The key is not an API-secret credential |
api_access_denied |
401 | Account does not have access to the API |
api_access_restricted |
401 | The organization's API access has been restricted |
missing_signature |
401 | Missing X-ConfidentLims-Signature header |
missing_timestamp |
401 | Missing X-ConfidentLims-Timestamp header |
invalid_timestamp |
401 | Timestamp header is not a valid epoch timestamp |
request_too_old |
400 | Signed request timestamp is too old — includes current_server_time in the response for calibration |
invalid_signature |
401 | Request is not correctly signed |
permission_denied |
403 | Account does not have permission for this action |
not_found |
404 | The requested record does not exist or is not visible to this organization |
invalid_request |
400 | Generic problem with the request (usually validation) |
Authentication and Signing
All endpoints (even GETs) require an API key header
(X-ConfidentLims-APIKey). By default, requests must also
be signed with a signature generated using the matching API secret —
incorrectly signed requests are rejected with a 401 response. Signing
can be disabled per credential from the organization settings page to
speed up development.
The signature is the hex-encoded SHA256-HMAC of the API key, the data fields (sorted alphabetically, ascending), and the API secret. Never send your API secret in a request — it should only be used for generating signatures.
Read the full, step-by-step signing instructions — including complete reference implementations in Python and JavaScript — on the Request Signing page.
Summary of steps to generate a signature
- Create the base string by combining method and route — e.g.
GET/v0/labs/orders - Create an ascii-sorted (ascending), lowercased list of
(key, value) pairs from the headers dictionary (must include
X-ConfidentLims-Timestampbut notX-ConfidentLims-APIKeyorX-ConfidentLims-Signature) - Create a url-encoded string
key=value&...for the ascii-ordered header fields, lowercased - Create a semicolon-separated list of lowercase header keys —
e.g.
host;x-confidentlims-timestamp - Create an ascii-sorted list of (key, value) pairs from the form data (or the querystring for GET requests)
- Add
('api_key', <your api key>)to the END of the list - Create a url-encoded param string
key=value&...for the ordered data fields - Percent-encode the base string from step 1
- Combine the percent-encoded base string, url-encoded header
string, and url-encoded parameter string with
&between them - Create the SHA256 HMAC signature of that string using your API secret
- Prefix with the signing algorithm and header list string:
CC0-HMAC-SHA256:host;x-confidentlims-timestamp:<signature>
Additional Notes
Updates
All updates and notifications regarding the API are sent via an email list. Please email api@confidentlims.com to automatically subscribe. This includes notifications of upcoming features, breaking changes, and version upgrades.
Signing
Getting signing right is the hardest (but most important) part of
interacting with the API — the
POST /v0/signingtest
endpoint exists explicitly for testing your signing code during
development.
Paging
Many endpoints that return dynamic lists (e.g. clients, orders, and
samples — but not test types, sample categories, etc.) are limited to
100 results and include a more_results
boolean field. If more_results is true, additional results
exist, which can be queried by passing a number for start
(default 0) and optionally limit (default
100), allowing you to iterate through pages until
more_results is false.
Timestamps
Timestamps are always returned in isoformat — for example:
2016-10-04T13:20:42.395276.
Dates with times should always be sent in UTC time in the format
YYYY-MM-DD HH:MM:SS — for example:
2016-10-04 13:20:42.
Dates should always be sent as YYYY-MM-DD — for example:
2016-10-04.
Currency and Pricing
All currency and pricing numbers are always represented as integer cents (instead of floating point dollars). Currency and pricing fields are generally named to reflect this.
File Uploads
Several endpoints support uploading files (images, PDFs, etc.). These
file fields are not included when generating
signatures, so be sure to exclude them during the signing process. Send
files as standard multipart/form-data uploads.
Machine-readable docs
Every page of these docs is available as Markdown by appending .md to
its URL (this page: index.md). llms.txt
indexes every page, llms-full.txt
holds them all in one file, and each section publishes its OpenAPI 3.1
spec at openapi.json (this section: openapi.json).
Additional Help
If you need any help or just have questions, comments, or complaints, please reach out at api@confidentlims.com. We want to make sure you have the best experience possible, so definitely let us know what you think or if you get stuck!