{
  "openapi": "3.1.0",
  "info": {
    "title": "Confident LIMS API — General",
    "description": "Confident LIMS public API — endpoints available to both labs and clients (enumerations, statuses, and other shared data). The guides below cover authentication, request signing, and the response envelope.",
    "version": "0.16.0",
    "contact": {
      "email": "api@confidentlims.com"
    }
  },
  "servers": [
    {
      "url": "https://api.confidentcannabis.com"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Compounds",
      "description": "Compound enumerations used in test results."
    },
    {
      "name": "Orders",
      "description": "Create, inspect, and manage testing orders."
    },
    {
      "name": "Samples",
      "description": "Samples under test and their results, files, and edits."
    },
    {
      "name": "Signing",
      "description": "Utilities for testing request signing."
    },
    {
      "name": "Test Types",
      "description": "Available test type enumerations."
    }
  ],
  "paths": {
    "/v0/compounds": {
      "get": {
        "operationId": "get_compound",
        "summary": "List compounds",
        "tags": [
          "Compounds"
        ],
        "description": "Return every compound known to Confident, including synonyms and alternate spellings. Results are grouped by test category and sorted by name within each category.\n\nAnything listed here can be submitted in test results using the `name` value. When `is_synonym` is true, `synonym_for_compound_name` gives the canonical compound the synonym maps to.\n\nThis response is cacheable and is served with a `Cache-Control: max-age=1800` header.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "compounds": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/CompoundSerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "compounds": [
                    {
                      "category": "cannabinoids",
                      "name": "cbd",
                      "display_name": "CBD",
                      "is_synonym": false,
                      "synonym_for_compound_name": ""
                    },
                    {
                      "category": "cannabinoids",
                      "name": "cannabidiol",
                      "display_name": "Cannabidiol",
                      "is_synonym": true,
                      "synonym_for_compound_name": "cbd"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/orderstatuses": {
      "get": {
        "operationId": "get_order_statuses",
        "summary": "List order statuses",
        "tags": [
          "Orders"
        ],
        "description": "Return every order status an order can be in. Use the `id` of a status as the `status_id` filter when listing orders or samples.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "order_statuses": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/OrderStatusSerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "order_statuses": [
                    {
                      "id": 0,
                      "name": "Canceled"
                    },
                    {
                      "id": 2,
                      "name": "Placed"
                    },
                    {
                      "id": 3,
                      "name": "In Progress"
                    },
                    {
                      "id": 4,
                      "name": "Completed"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/samplecategories": {
      "get": {
        "operationId": "get_sample_categories",
        "summary": "List sample categories",
        "tags": [
          "Samples"
        ],
        "description": "Return every sample category, ordered for display. Each category belongs to a single sample industry, which is included here for convenience.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "sample_categories": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SampleCategorySerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "sample_categories": [
                    {
                      "id": 1,
                      "name": "Plant",
                      "industry_id": 1,
                      "industry_name": "Cannabis & Hemp"
                    },
                    {
                      "id": 2,
                      "name": "Concentrates & Extracts",
                      "industry_id": 1,
                      "industry_name": "Cannabis & Hemp"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/sampleclassifications": {
      "get": {
        "operationId": "get_sample_classifications",
        "summary": "List sample classifications",
        "tags": [
          "Samples"
        ],
        "description": "Return every sample classification. Classifications describe the cannabinoid or genetic profile of a sample, such as `Indica`, `Sativa` or `High CBD`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "sample_classifications": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SampleClassificationSerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "sample_classifications": [
                    {
                      "id": 3,
                      "name": "Indica"
                    },
                    {
                      "id": 4,
                      "name": "Hybrid"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/sampleindustries": {
      "get": {
        "operationId": "get_sample_industries",
        "summary": "List sample industries",
        "tags": [
          "Samples"
        ],
        "description": "Return every sample industry Confident supports. Industries sit at the top of the sample taxonomy: every sample category belongs to one industry, and every sample type belongs to one category.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "sample_industries": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SampleIndustrySerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "sample_industries": [
                    {
                      "id": 1,
                      "name": "Cannabis & Hemp"
                    },
                    {
                      "id": 2,
                      "name": "Agriculture"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/sampleproductionmethods": {
      "get": {
        "operationId": "get_sample_production_methods",
        "summary": "List sample production methods",
        "tags": [
          "Samples"
        ],
        "description": "Return every sample production method, ordered for display. A production method describes how the sample was grown or made (for example `Indoor` for plant material or `CO2` for an extract) and belongs to a single sample category.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "sample_production_methods": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SampleProductionMethodSerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "sample_production_methods": [
                    {
                      "id": 1,
                      "name": "Indoor",
                      "category_id": 1,
                      "category_name": "Plant"
                    },
                    {
                      "id": 5,
                      "name": "CO2",
                      "category_id": 2,
                      "category_name": "Concentrates & Extracts"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/sampletypes": {
      "get": {
        "operationId": "get_sample_types",
        "summary": "List sample types",
        "tags": [
          "Samples"
        ],
        "description": "Return every sample type, ordered for display. Each sample type belongs to a single sample category, which is included here for convenience.\n\nUse the `id` of a sample type as `sample_type_id` when creating a sample.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "sample_types": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SampleTypeSerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "sample_types": [
                    {
                      "id": 1,
                      "name": "Flower - Cured",
                      "category_id": 1,
                      "category_name": "Plant"
                    },
                    {
                      "id": 64,
                      "name": "Biomass",
                      "category_id": 1,
                      "category_name": "Plant"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/signingtest": {
      "post": {
        "operationId": "signing_test_endpoint",
        "summary": "Test request signing",
        "tags": [
          "Signing"
        ],
        "description": "Debug endpoint for verifying your request signing implementation. Use any valid credentials and send any fields you like: field values are folded into the signature but are otherwise ignored.\n\nA correctly signed request succeeds and returns nothing but the success flag; an incorrectly signed one is rejected like any other request.\n\nValues worth signing while testing, because they exercise character escaping: `hello`, `hello, world!` and `foobar!'()*+~\"`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "example_field": {
                    "type": "string",
                    "description": "Any string. Included in the signature, otherwise ignored."
                  }
                }
              },
              "example": {
                "example_field": "hello, world!"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessEnvelope"
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    },
    "/v0/testtypes": {
      "get": {
        "operationId": "get_test_types",
        "summary": "List test types",
        "tags": [
          "Test Types"
        ],
        "description": "Return every test type Confident supports. A test type is a single analysis a lab can run, such as cannabinoids or pesticides; a sample can be assigned any number of test types through its test packages.",
        "parameters": [
          {
            "$ref": "#/components/parameters/SignatureHeader"
          },
          {
            "$ref": "#/components/parameters/TimestampHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "test_types": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/TestTypeSerializer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "test_types": [
                    {
                      "id": 1,
                      "name": "Cannabinoids",
                      "abbreviation": "CAN"
                    },
                    {
                      "id": 2,
                      "name": "Terpenes",
                      "abbreviation": "TER"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-ConfidentLims-APIKey",
        "description": "API key for your organization. Manage keys from your Confident LIMS account settings.\n\nEvery request must also carry `X-ConfidentLims-Timestamp` (unix seconds) and `X-ConfidentLims-Signature`, an HMAC-SHA256 over the request computed with the matching API secret: percent-encode `METHOD + path`; url-encode the lowercased, sorted signed headers as `name=value&...`; url-encode the sorted querystring/form fields (never file uploads) with `api_key=<key>` appended last; join the three parts with `&`; HMAC-SHA256 the result with the API secret; send `CC0-HMAC-SHA256:<signed header names>:<hex digest>`. Reference implementations (Python and JavaScript) and a test vector are in the Request Signing guide: `/v0/docs/request-signing.md`."
      }
    },
    "parameters": {
      "SignatureHeader": {
        "name": "X-ConfidentLims-Signature",
        "in": "header",
        "required": false,
        "description": "HMAC-SHA256 request signature. Required only when request signing is enabled for your API key — see the Request Signing guide.",
        "schema": {
          "type": "string"
        }
      },
      "TimestampHeader": {
        "name": "X-ConfidentLims-Timestamp",
        "in": "header",
        "required": false,
        "description": "Unix timestamp (seconds) of the request, required only when request signing is enabled for your API key. Requests older than 30 seconds are rejected.",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "SuccessEnvelope": {
        "type": "object",
        "description": "Every successful response includes `success: true` plus the endpoint-specific fields.",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "required": [
          "success"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Every error response includes `success: false` and an `error_code`.",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "error_code": {
            "type": "string"
          },
          "error_message": {
            "type": "string",
            "description": "Human-readable description of the error."
          },
          "error_details": {
            "type": "object",
            "description": "Per-field validation errors when error_code is `invalid_request`, keyed by field name.",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "success",
          "error_code"
        ]
      },
      "CompoundSerializer": {
        "type": "object",
        "properties": {
          "category": {
            "type": [
              "string",
              "null"
            ],
            "description": "Test category under which this compound is normally tested"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unique name used to identify the compound"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name for compound"
          },
          "is_synonym": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "True if this is a synonym for another compound"
          },
          "synonym_for_compound_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Name of compound for which this is a synonym"
          }
        }
      },
      "OrderStatusSerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Order Status"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Order Status Name"
          }
        }
      },
      "SampleCategorySerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Sample Category"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Category Name"
          },
          "industry_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Sample Industry"
          },
          "industry_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Industry Name"
          }
        }
      },
      "SampleClassificationSerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Sample Classification"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Classification Name"
          }
        }
      },
      "SampleIndustrySerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Sample Industry"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Industry Name"
          }
        }
      },
      "SampleProductionMethodSerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Sample Production Method"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Production Method Name"
          },
          "category_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Sample Category ID"
          },
          "category_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Category Name"
          }
        }
      },
      "SampleTypeSerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Sample Type"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Type Name"
          },
          "category_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Sample Category ID"
          },
          "category_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sample Category Name"
          }
        }
      },
      "TestTypeSerializer": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unique ID for Test Type"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Test Type Name"
          },
          "abbreviation": {
            "type": [
              "string",
              "null"
            ],
            "description": "Test Type Abbreviation"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was malformed or failed validation. Validation failures include per-field messages in `error_details`.\n\nPossible `error_code` values: `invalid_request`, `request_too_old`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error_code": "invalid_request"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Authentication failed.\n\nPossible `error_code` values: `missing_api_key`, `invalid_api_key`, `invalid_credentials_type`, `api_access_restricted`, `api_access_denied`, `missing_signature`, `missing_timestamp`, `invalid_timestamp`, `invalid_signature`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error_code": "invalid_api_key"
            }
          }
        }
      },
      "PermissionDenied": {
        "description": "The API key is valid but does not have permission for this endpoint (for example, a client key calling a labs endpoint).\n\nPossible `error_code` values: `permission_denied`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error_code": "permission_denied"
            }
          }
        }
      }
    }
  }
}