Confident Cannabis API - Lab Endpoints

Endpoints for laboratories to manage samples, orders, the order-status lifecycle, test results, file uploads (COA, images, documents), and client relationships.

OpenAPI Specification

confident-cannabis-lab-openapi.json Raw ↑
{
  "openapi": "3.1.0",
  "info": {
    "title": "Confident Cannabis API - Lab Endpoints",
    "version": "0.16.0",
    "description": "API endpoints for laboratories to manage samples, orders, test results, and client relationships. Includes endpoints for submitting test results, uploading files, and managing order lifecycle.",
    "contact": {
      "name": "Confident Cannabis API Support",
      "url": "https://www.confidentcannabis.com"
    }
  },
  "servers": [
    {
      "url": "https://api.confidentcannabis.com",
      "description": "Production server"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": [],
      "SignatureAuth": [],
      "TimestampAuth": []
    }
  ],
  "tags": [
    {
      "description": "Client relationship management",
      "name": "Clients"
    },
    {
      "description": "Order lifecycle state transitions",
      "name": "Order Status"
    },
    {
      "description": "Order management operations",
      "name": "Orders"
    },
    {
      "description": "Reference data endpoints",
      "name": "Reference Data"
    },
    {
      "description": "Sample management operations",
      "name": "Samples"
    },
    {
      "description": "Submit and manage test results",
      "name": "Test Results"
    },
    {
      "description": "Upload sample images and documents",
      "name": "Sample Files"
    }
  ],
  "paths": {
    "/v0/labs/sample/{sample_id}/weight_on_hand": {
      "post": {
        "summary": "Adjust weight on hand",
        "description": "Adjusts the weight on hand for a sample with a reason code.",
        "operationId": "adjustWeightOnHand",
        "tags": [
          "Samples"
        ],
        "parameters": [
          {
            "name": "sample_id",
            "in": "path",
            "required": true,
            "description": "Sample identifier (lab_internal_id, public_key, or regulator_id_to_attach)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "weight_change",
                  "units",
                  "change_reason"
                ],
                "properties": {
                  "weight_change": {
                    "type": "string",
                    "description": "Weight change amount (can be negative). As string to preserve precision.",
                    "example": "-2.5"
                  },
                  "units": {
                    "type": "string",
                    "description": "Weight units",
                    "enum": [
                      "g",
                      "units"
                    ],
                    "example": "g"
                  },
                  "change_reason": {
                    "type": "integer",
                    "description": "Reason code: 0=other, 1=initial, 2=destroyed, 3=used, 4=returned, 5=lost, 6=stolen, 7=addition",
                    "enum": [
                      0,
                      1,
                      2,
                      3,
                      4,
                      5,
                      6,
                      7
                    ],
                    "example": 3
                  },
                  "notes": {
                    "type": "string",
                    "description": "Optional notes about the change"
                  }
                }
              },
              "examples": {
                "adjustment": {
                  "summary": "Record sample usage",
                  "value": {
                    "weight_change": "-2.5",
                    "units": "g",
                    "change_reason": 3,
                    "notes": "Used for additional testing"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Weight adjusted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v0/labs/order/{order_id}/status/cancel": {
      "post": {
        "summary": "Cancel order",
        "description": "Moves order to 'Canceled' (status_id 5).",
        "operationId": "cancelOrder",
        "tags": [
          "Order Status"
        ],
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "description": "Order identifier (lab_internal_id)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cancel_reason": {
                    "type": "string",
                    "description": "Optional reason for cancellation"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order canceled successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v0/labs/order/{order_id}/status/complete": {
      "post": {
        "summary": "Complete order",
        "description": "Moves order from 'In Progress' (status_id 3) to 'Completed' (status_id 4).",
        "operationId": "completeOrder",
        "tags": [
          "Order Status"
        ],
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "description": "Order identifier (lab_internal_id)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "date_completed": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order completed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v0/labs/clients": {
      "post": {
        "summary": "Create client",
        "description": "Creates a new client organization for this lab.",
        "operationId": "createClient",
        "tags": [
          "Clients"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Client organization name"
                  },
                  "email": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Client created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "client"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "client": {
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "training": {
                          "type": "boolean"
                        },
                        "last_modified": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "email": {
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List clients",
        "description": "Returns a paginated list of clients associated with this lab.",
        "operationId": "getClients",
        "tags": [
          "Clients"
        ],
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "Pagination offset",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum records to return (max 100)",
            "schema": {
              "type": "integer",
              "default": 100,
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response with list of clients",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "clients",
                    "more_results"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "clients": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "name": {
                            "type": "string"
                          },
                          "training": {
                            "type": "boolean"
                          },
                          "last_modified": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "more_results": {
                      "type": "boolean",
                      "example": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error_code",
                    "error_message"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error_code": {
                      "type": "string"
                    },
                    "error_message": {
                      "type": "string"
                    },
                    "error_details": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v0/labs/order": {
      "post": {
        "summary": "Create order",
        "description": "Creates a new order with one or more samples.",
        "operationId": "createOrder",
        "tags": [
          "Orders"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "client_id",
                  "lab_internal_id",
                  "samples"
                ],
                "properties": {
                  "client_id": {
                    "type": "integer",
                    "description": "Client ID"
                  },
                  "lab_internal_id": {
                    "type": "string",
                    "description": "Lab's internal order ID"
                  },
                  "samples": {
                    "type": "array",
                    "description": "Array of samples to include in order",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "required": [
                        "name",
                        "sample_type_id",
                        "lab_internal_id"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "sample_type_id": {
                          "type": "integer"
                        },
                        "lab_internal_id": {
                          "type": "string"
                        },
                        "strain": {
                          "type": "string"
                        },
                        "regulator_batch_id": {
                          "type": "string"
                        },
                        "harvest_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              },
              "examples": {
                "single_sample": {
                  "summary": "Order with one sample",
                  "value": {
                    "client_id": 123,
                    "lab_internal_id": "ORD-2025-100",
                    "samples": [
                      {
                        "name": "OG Kush - Batch 42",
                        "sample_type_id": 1,
                        "lab_internal_id": "SAMP-2025-100",
                        "regulator_batch_id": "BATCH-42"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "order"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "order": {
                      "properties": {
                        "lab_internal_id": {
                          "type": "string"
                        },
                        "status_id": {
                          "type": "integer"
                        },
                        "status_name": {
                          "type": "string"
                        },
                        "client_id": {
                          "type": "integer"
                        },
                        "client_name": {
                          "type": "string"
                        },
                        "num_samples": {
                          "type": "integer"
                        },
                   

# --- truncated at 32 KB (142 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/confident-cannabis/refs/heads/main/openapi/confident-cannabis-lab-openapi.json