{
  "openapi": "3.1.0",
  "info": {
    "title": "PepChile Public API",
    "version": "1.0.0",
    "summary": "Read-only API for the PepChile research-peptide catalog in Chile.",
    "description": "PepChile sells research-grade peptides in Chile. This API gives an agent the same\ncatalog, prices and shipping quotes that the storefront shows.\n\n## Onboarding\n\nThere is no API key. There is no account. There is no quota to request.\nEvery endpoint below is free and public. To make your first call, send:\n\n    curl https://pepchile.com/api/products\n\nUse the sandbox server for development. The sandbox runs the same code with a\nseparate database and test data.\n\n## Limits\n\nThe catalog endpoints have no quota for each IP address. Be reasonable: read the\nfull catalog one time instead of one product at a time.\nThe two shipping endpoints enforce 60 requests each minute for each IP address.\nAbove that limit they return 429.\n\n## Conventions\n\nAll prices are Chilean pesos (CLP). The price includes IVA. Text content is Spanish (es-CL). A product URL slug has no dose\nsuffix (\"bpc-157\"). A database id can have one (\"bpc-157-10mg\").\n\n## Other protocols\n\nThe same data is available through the Model Context Protocol at /api/mcp and\nthrough A2A JSON-RPC at /api/a2a. Read\nhttps://pepchile.com/.well-known/agent-instructions.md first.",
    "termsOfService": "https://pepchile.com/legal/terminos/",
    "contact": {
      "name": "PepChile",
      "url": "https://pepchile.com/developers/",
      "email": "contacto@pepchile.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://pepchile.com/legal/terminos/"
    }
  },
  "externalDocs": {
    "description": "Developer documentation and agent instructions.",
    "url": "https://pepchile.com/developers/"
  },
  "servers": [
    {
      "url": "https://pepchile.com",
      "description": "Production. Live catalog and live prices."
    },
    {
      "url": "https://pepchile-dev.pages.dev",
      "description": "Sandbox. The same code, a separate database and test data."
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "catalog",
      "description": "Products, prices and stock."
    },
    {
      "name": "content",
      "description": "Questions, reviews and peptide information."
    },
    {
      "name": "shipping",
      "description": "Courier quotes for Chile."
    },
    {
      "name": "store",
      "description": "Storefront configuration."
    },
    {
      "name": "agents",
      "description": "Protocol endpoints for autonomous agents."
    },
    {
      "name": "orders",
      "description": "Order creation. A person must complete the payment."
    }
  ],
  "paths": {
    "/api/products": {
      "get": {
        "tags": [
          "catalog"
        ],
        "operationId": "listProducts",
        "summary": "Get the full catalog.",
        "description": "Returns every published product with its price, stock and purity. This is the cheapest way to answer a price question or a stock question.",
        "responses": {
          "200": {
            "description": "The catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Product"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/products/{id}": {
      "get": {
        "tags": [
          "catalog"
        ],
        "operationId": "getProduct",
        "summary": "Get one product.",
        "description": "The id must match the database id exactly, for example \"bpc-157-10mg\". To match a bare compound slug, use the MCP tool get_product.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "peptide": {
                "value": "bpc-157-10mg"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The product.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "No product has this id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/faqs": {
      "get": {
        "tags": [
          "content"
        ],
        "operationId": "listFaqs",
        "summary": "Get the storefront questions and answers.",
        "responses": {
          "200": {
            "description": "The questions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "question",
                      "answer"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "question": {
                        "type": "string"
                      },
                      "answer": {
                        "type": "string"
                      },
                      "displayOrder": {
                        "type": "integer"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/reviews/{productId}": {
      "get": {
        "tags": [
          "content"
        ],
        "operationId": "listProductReviews",
        "summary": "Get the published reviews for one product.",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "peptide": {
                "value": "bpc-157-10mg"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The reviews. The list is empty if the product has none.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "productId": {
                        "type": "string"
                      },
                      "rating": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 5
                      },
                      "comment": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "customerName": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "createdAt": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/peptide-info": {
      "get": {
        "tags": [
          "content"
        ],
        "operationId": "listPeptideInfo",
        "summary": "Get the reference article for every peptide.",
        "description": "Each entry holds a slug, a name and a long description in Spanish.",
        "responses": {
          "200": {
            "description": "The entries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PeptideInfo"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/peptide-info/{slug}": {
      "get": {
        "tags": [
          "content"
        ],
        "operationId": "getPeptideInfo",
        "summary": "Get the reference article for one peptide.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "peptide": {
                "value": "bpc-157"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The entry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeptideInfo"
                }
              }
            }
          },
          "404": {
            "description": "No entry has this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/exchange-rate": {
      "get": {
        "tags": [
          "store"
        ],
        "operationId": "getExchangeRate",
        "summary": "Get the reference rate from USD to CLP.",
        "description": "Use this rate to show an approximate foreign price. The customer always pays in CLP.",
        "responses": {
          "200": {
            "description": "The rate.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "rate",
                    "date"
                  ],
                  "properties": {
                    "rate": {
                      "type": "number",
                      "examples": [
                        915.21
                      ]
                    },
                    "date": {
                      "type": "string",
                      "format": "date"
                    },
                    "source": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/store/config": {
      "get": {
        "tags": [
          "store"
        ],
        "operationId": "getStoreConfig",
        "summary": "Get the public storefront configuration.",
        "description": "Shows whether the store accepts orders, which payment gateway is active, and the limit for bacteriostatic water in one cart.",
        "responses": {
          "200": {
            "description": "The configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "storeEnabled": {
                      "type": "boolean"
                    },
                    "paymentGateway": {
                      "type": "string",
                      "examples": [
                        "zeleri"
                      ]
                    },
                    "bannerText": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "maxBacWaterQuantity": {
                      "type": "integer"
                    },
                    "bacWaterExtraPerVial": {
                      "type": "integer"
                    },
                    "affiliatePointsPercent": {
                      "type": "number"
                    },
                    "affiliateReferralDiscountPercent": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/contact-config": {
      "get": {
        "tags": [
          "store"
        ],
        "operationId": "getContactConfig",
        "summary": "Get the Turnstile site key for the contact form.",
        "responses": {
          "200": {
            "description": "The key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "siteKey": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/merchant-feed": {
      "get": {
        "tags": [
          "catalog"
        ],
        "operationId": "getMerchantFeed",
        "summary": "Get the product feed for Google Merchant Center.",
        "responses": {
          "200": {
            "description": "An RSS 2.0 feed with the Google Merchant namespace.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/guides/{slug}": {
      "get": {
        "tags": [
          "content"
        ],
        "operationId": "getGuidePdf",
        "summary": "Download the PDF guide for one product.",
        "description": "The guide gives the reconstitution volume and the dose table. The guide is the authority for those numbers.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "peptide": {
                "value": "bpc-157-10mg"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "302": {
            "description": "The object store did not answer. The response redirects to the CDN copy of the same PDF.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "404": {
            "description": "The product has no guide.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/shipit/rates": {
      "post": {
        "tags": [
          "shipping"
        ],
        "operationId": "quoteShipping",
        "summary": "Quote the courier price to a Chilean commune.",
        "description": "Returns one option for each available courier. PepChile ships only inside Chile.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "communeName"
                ],
                "properties": {
                  "communeName": {
                    "type": "string",
                    "examples": [
                      "Providencia"
                    ]
                  },
                  "deliveryMode": {
                    "type": "string",
                    "enum": [
                      "home_delivery",
                      "branch_pickup"
                    ],
                    "default": "home_delivery"
                  },
                  "vials": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500,
                    "default": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The quote.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "deliveryMode": {
                      "type": "string"
                    },
                    "destinyCommune": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "regionId": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      }
                    },
                    "options": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "courier": {
                            "type": "string",
                            "enum": [
                              "starken",
                              "bluexpress",
                              "chilexpress"
                            ]
                          },
                          "courierLabel": {
                            "type": "string"
                          },
                          "priceClp": {
                            "type": "integer"
                          },
                          "days": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. The limit is 60 each minute for each IP address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/shipit/resolve-commune": {
      "post": {
        "tags": [
          "shipping"
        ],
        "operationId": "resolveCommune",
        "summary": "Find the courier id of a Chilean commune.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "communeName"
                ],
                "properties": {
                  "communeName": {
                    "type": "string",
                    "examples": [
                      "Puente Alto"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The commune.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "commune": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "regionId": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. The limit is 60 each minute for each IP address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/shipit/branch-offices": {
      "get": {
        "tags": [
          "shipping"
        ],
        "operationId": "listBranchOffices",
        "summary": "List the courier branches in one commune.",
        "parameters": [
          {
            "name": "courier",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "starken",
                "bluexpress",
                "chilexpress"
              ]
            }
          },
          {
            "name": "communeId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "providencia": {
                "value": "317"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The branches.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "A parameter is absent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/mcp": {
      "post": {
        "tags": [
          "agents"
        ],
        "operationId": "callMcp",
        "summary": "Call the Model Context Protocol server.",
        "description": "Streamable HTTP transport, protocol version 2025-06-18. The server has no session. Send initialize first, then tools/list. It also answers resources/list, resources/read and prompts/list.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The JSON-RPC response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "202": {
            "description": "A notification. The body is empty."
          }
        }
      },
      "get": {
        "tags": [
          "agents"
        ],
        "operationId": "describeMcp",
        "summary": "Get the reason why GET is not available.",
        "description": "The server sends no events, so it offers no event stream. Use POST.",
        "responses": {
          "405": {
            "description": "Method not allowed. The body names the server card.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/a2a": {
      "post": {
        "tags": [
          "agents"
        ],
        "operationId": "callA2a",
        "summary": "Call the A2A agent.",
        "description": "Send message/send. Put the skill in a DataPart, for example {\"skill\": \"search_products\", \"query\": \"bpc-157\"}.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The JSON-RPC response with an A2A message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "agents"
        ],
        "operationId": "describeA2a",
        "summary": "Get the location of the agent card.",
        "responses": {
          "200": {
            "description": "The agent summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/cart/validate": {
      "post": {
        "tags": [
          "orders"
        ],
        "operationId": "validateCart",
        "summary": "Check a cart against live stock and live prices.",
        "description": "Use this before you show a total. It rejects a line that is out of stock and it corrects a price that changed.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "items"
                ],
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "productId",
                        "quantity"
                      ],
                      "properties": {
                        "productId": {
                          "type": "string"
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result of the check.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/checkout": {
      "post": {
        "tags": [
          "orders"
        ],
        "operationId": "createOrder",
        "summary": "Create an order.",
        "description": "An agent cannot complete a purchase. This endpoint needs a Supabase anonymous session, and the payment step needs a person with a card or a bank transfer. Give the customer the product URL instead.",
        "security": [
          {
            "supabaseAnonymousSession": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "tags": [
          "store"
        ],
        "operationId": "sendContactMessage",
        "summary": "Send a message to the contact address.",
        "description": "The request needs a Cloudflare Turnstile token. Get the site key from /api/contact-config.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The message went out.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid, or the token failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "supabaseAnonymousSession": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "A Supabase anonymous session token. Only /api/checkout needs it. Every other endpoint is open."
      }
    },
    "schemas": {
      "Product": {
        "type": "object",
        "description": "One product in the catalog.",
        "required": [
          "id",
          "name",
          "price",
          "inStock",
          "category"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Database id. It can carry a dose suffix, for example \"bpc-157-10mg\".",
            "examples": [
              "bpc-157-10mg"
            ]
          },
          "name": {
            "type": "string",
            "examples": [
              "BPC-157 - 10mg"
            ]
          },
          "dosage": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "10mg"
            ]
          },
          "useCase": {
            "type": [
              "string",
              "null"
            ],
            "description": "The research goal of the product, in Spanish."
          },
          "price": {
            "type": "integer",
            "description": "Price in CLP. All prices are Chilean pesos (CLP). The price includes IVA.",
            "examples": [
              80000
            ]
          },
          "priceFormatted": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "$80.000"
            ]
          },
          "inStock": {
            "type": "boolean"
          },
          "stock": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Units available. The value is rounded, because exact inventory is not public."
          },
          "purity": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              ">99%"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "janoshikKey": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reference for the Janoshik certificate of analysis."
          },
          "coaImageUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "category": {
            "type": "string",
            "enum": [
              "peptide",
              "accessory"
            ]
          },
          "benefits": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "bestPriceReference": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "discountPercent": {
            "type": "integer"
          },
          "isDiscounted": {
            "type": "boolean"
          },
          "originalPrice": {
            "type": [
              "integer",
              "null"
            ]
          },
          "displayOrder": {
            "type": "integer"
          },
          "imageUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "guideUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "PDF guide for the product."
          },
          "published": {
            "type": "boolean"
          },
          "unitsSold": {
            "type": "integer"
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "PeptideInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "The reason, in Spanish."
          }
        }
      },
      "AgentError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "not_found",
              "method_not_allowed"
            ]
          },
          "message": {
            "type": "string"
          },
          "catalog": {
            "type": "string",
            "format": "uri"
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "required": [
          "jsonrpc",
          "method"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer",
              "null"
            ]
          },
          "method": {
            "type": "string"
          },
          "params": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "required": [
          "jsonrpc"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer",
              "null"
            ]
          },
          "result": {},
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "This origin serves no endpoint at this path.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AgentError"
            }
          }
        }
      }
    }
  }
}
