{"openapi":"3.1.0","info":{"title":"Erie Coast Analytical Agent API","version":"1.0.0","description":"Live ordering information for AI agents ordering lab testing from Erie Coast Analytical. Every endpoint matches one tool on the MCP server at https://www.erieanalytical.com/api/mcp. Start with GET /status, then read GET /guide.","contact":{"name":"Erie Coast Analytical","email":"support@erieanalytical.com","url":"https://www.erieanalytical.com"}},"servers":[{"url":"https://www.erieanalytical.com/api/v1"}],"paths":{"/status":{"get":{"operationId":"get_ordering_status","summary":"Ordering status","description":"Is ECA taking orders right now, what can be ordered online, current prices, rush, turnaround and payment methods. Call this first.\n\nMCP tool: `get_ordering_status`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[]}},"/guide":{"get":{"operationId":"get_ordering_guide","summary":"Ordering guide","description":"The full step-by-step guide for ordering ECA lab testing for a person: ground rules, what to ask the person, sign-up, building the order, checkout, shipping vials and results.\n\nMCP tool: `get_ordering_guide`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[]}},"/compounds":{"get":{"operationId":"find_compound","summary":"Find a compound","description":"Search ECA's testing catalog by compound name, for example \"BPC-157\" or \"semaglutide\". Returns product ids for get_price, whether each can be ordered online, and its catalog page.\n\nMCP tool: `find_compound`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":true,"description":"Compound name to search for.","schema":{"type":"string","minLength":2,"maxLength":80}}]}},"/price":{"post":{"operationId":"get_price","summary":"Price an order","description":"Price a list of samples with the Basic Bundle, plus optional rush, at ECA's standard prices, the same ones checkout uses. An account with special pricing from ECA sees its own price at checkout. Discount codes are applied at checkout, not here.\n\nMCP tool: `get_price`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"product_id":{"type":"integer","minimum":1,"maximum":2147483647,"description":"Product id from find_compound."},"samples":{"type":"integer","minimum":1,"maximum":500,"description":"Number of samples (vials) of this compound to test."}},"required":["product_id","samples"],"additionalProperties":false},"description":"One entry per compound."},"rush":{"default":false,"description":"true adds rush processing, charged once per order.","type":"boolean"}},"required":["items"],"additionalProperties":false}}}}}},"/cart-link":{"post":{"operationId":"make_cart_link","summary":"Make a cart link","description":"Build one link that opens ECA's website with the whole order already in the cart: each compound's samples, labeled amount and unit, and lot number, plus rush. If any detail is missing, no link is made; you get back ask_person, a message to send the person as is.\n\nMCP tool: `make_cart_link`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"product_id":{"type":"integer","minimum":1,"maximum":2147483647,"description":"Product id from find_compound."},"samples":{"type":"integer","minimum":1,"maximum":500,"description":"Number of samples (vials) of this compound to test."},"labeled_amount":{"description":"The amount printed on the vial label, like \"10 mg\", or just the number with unit set.","anyOf":[{"type":"string","maxLength":40},{"type":"number"}]},"unit":{"description":"mg, mcg, g, IU or mL. Not needed if labeled_amount already has it.","type":"string","maxLength":10},"lot_number":{"description":"The lot number on the vial, or \"none\". Ask the person; never leave it out silently.","type":"string","maxLength":60}},"required":["product_id","samples"],"additionalProperties":false},"description":"One entry per compound."},"rush":{"description":"true for rush processing (charged once per order), false for standard. Ask the person.","type":"boolean"}},"required":["items"],"additionalProperties":false}}}}}},"/shipping-instructions":{"get":{"operationId":"get_shipping_instructions","summary":"Shipping instructions","description":"Where and how the person mails their vials to ECA after paying.\n\nMCP tool: `get_shipping_instructions`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[]}},"/certificates/verify":{"post":{"operationId":"verify_certificate","summary":"Verify a certificate","description":"Check that an ECA Certificate of Analysis is real, using the 14-character verification key printed on it and its order number. Never returns customer details.\n\nMCP tool: `verify_certificate`.","tags":["Public"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input, a body that is not valid JSON, or not orderable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request body in an encoding ECA cannot read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Details are missing: send ask_person to the person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"verification_key":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[ -~]+$","description":"The 14-character key printed at the top right of the certificate."},"order_number":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[ -~]+$","description":"The order or sample number on the certificate, like ECA26-0012."}},"required":["verification_key","order_number"],"additionalProperties":false}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_input","invalid_json","too_large","bad_request","needs_details","not_found","not_orderable","rate_limited","internal_error"]},"message":{"type":"string","description":"Plain-English explanation to act on or pass to the person."},"ask_person":{"type":"string","description":"needs_details only: a message to send the person as is."},"missing":{"type":"array","description":"needs_details only: which line and field is missing.","items":{"type":"object"}},"issues":{"type":"array","description":"invalid_input only: each problem with the input, for code to read.","items":{"type":"object","required":["field","problem"],"properties":{"field":{"type":"string","description":"Like order_number or items[0].samples."},"problem":{"type":"string","enum":["missing","unknown_field","wrong_type","too_small","too_big","invalid"]},"expected":{"type":"string"},"minimum":{"type":"number"},"maximum":{"type":"number"}}}}}}}}}}}