{
  "openapi": "3.1.0",
  "info": {
    "title": "Practice API (invented practice data, not any broker's API)",
    "version": "1",
    "summary": "Invented practice data from openbrokerapi.com. It is not any broker's API, it is connected to no market, and it cannot place a trade.",
    "description": "Invented practice data from openbrokerapi.com. It is not any broker's API, it is connected to no market, and it cannot place a trade. The account, the instruments and every value are made up, and the paths are this site's own. Nothing in this document describes how any broker's API behaves.\n\nIt is a folder of fixed JSON files: every address answers GET only, always with status 200, and never changes. No address asks for a key, a username or a password, and none should ever be sent. The example errors carry the status a real server would send inside their body, in error.status.\n\nCalls that would change something, such as placing an order, cannot be answered by fixed files and are not in this document. They are on https://openbrokerapi.com/mock#writes as examples to read.\n\nGenerated from the same list of files as https://openbrokerapi.com/mock. Educational only. Nothing here is advice.",
    "x-independent": true,
    "x-practice": true,
    "x-page": "https://openbrokerapi.com/mock"
  },
  "externalDocs": {
    "description": "The practice API page",
    "url": "https://openbrokerapi.com/mock"
  },
  "servers": [
    {
      "url": "https://openbrokerapi.com/mock/v1",
      "description": "The practice API on openbrokerapi.com. Invented data."
    }
  ],
  "tags": [
    {
      "name": "Account"
    },
    {
      "name": "Trade history"
    },
    {
      "name": "Orders"
    },
    {
      "name": "Market data"
    },
    {
      "name": "Example errors"
    }
  ],
  "paths": {
    "/account.json": {
      "get": {
        "operationId": "account",
        "summary": "Account summary",
        "description": "One invented account: its balance, running profit or loss, equity, margin in use and what is available.",
        "tags": [
          "Account"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#account"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "asOf": "2026-01-05T09:30:00Z",
                  "account": {
                    "id": "PRACTICE-001",
                    "name": "Practice account",
                    "type": "DEMO",
                    "currency": "GBP",
                    "balance": 10000,
                    "profitLoss": 67.5,
                    "equity": 10067.5,
                    "marginUsed": 1273.5,
                    "available": 8794
                  }
                }
              }
            }
          }
        }
      }
    },
    "/positions.json": {
      "get": {
        "operationId": "positions",
        "summary": "Open positions",
        "description": "Two invented open positions, one BUY and one SELL, each with its size, opening level, current bid and offer, and running profit or loss.",
        "tags": [
          "Account"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#positions"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "asOf": "2026-01-05T09:30:00Z",
                  "positions": [
                    {
                      "positionId": "P-1001",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "BUY",
                      "size": 2,
                      "openLevel": 5020,
                      "bid": 5057,
                      "offer": 5058,
                      "stopLevel": 4970,
                      "limitLevel": null,
                      "currency": "GBP",
                      "profitLoss": 74,
                      "openedAt": "2025-12-22T08:05:00Z"
                    },
                    {
                      "positionId": "P-1002",
                      "instrumentId": "LNTN",
                      "instrumentName": "Lantern Metals (invented share)",
                      "direction": "SELL",
                      "size": 50,
                      "openLevel": 248.2,
                      "bid": 248.1,
                      "offer": 248.33,
                      "stopLevel": 255,
                      "limitLevel": 240,
                      "currency": "GBP",
                      "profitLoss": -6.5,
                      "openedAt": "2026-01-02T14:40:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/trades/page-1.json": {
      "get": {
        "operationId": "trades-page-1",
        "summary": "Closed trades, page 1",
        "description": "The five most recent of twelve invented closed trades, newest first, with a paging note. Its next field holds the path of page 2.",
        "tags": [
          "Trade history"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#trades-page-1"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "asOf": "2026-01-05T09:30:00Z",
                  "order": "Newest first, by closedAt.",
                  "paging": {
                    "page": 1,
                    "pageSize": 5,
                    "totalPages": 3,
                    "totalRows": 12,
                    "next": "/trades/page-2.json",
                    "nextIs": "A path to add to the base address, or null on the last page."
                  },
                  "trades": [
                    {
                      "tradeId": "T-3012",
                      "instrumentId": "TIDE",
                      "instrumentName": "Tidewater Oil (invented commodity)",
                      "direction": "BUY",
                      "size": 3,
                      "openLevel": 62.4,
                      "closeLevel": 61.8,
                      "profitLoss": -1.8,
                      "currency": "GBP",
                      "openedAt": "2025-12-31T14:00:00Z",
                      "closedAt": "2026-01-01T10:15:00Z"
                    },
                    {
                      "tradeId": "T-3011",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "SELL",
                      "size": 0.5,
                      "openLevel": 5064,
                      "closeLevel": 5050,
                      "profitLoss": 7,
                      "currency": "GBP",
                      "openedAt": "2025-12-31T09:00:00Z",
                      "closedAt": "2025-12-31T13:30:00Z"
                    },
                    {
                      "tradeId": "T-3010",
                      "instrumentId": "LNTN",
                      "instrumentName": "Lantern Metals (invented share)",
                      "direction": "SELL",
                      "size": 10,
                      "openLevel": 249.6,
                      "closeLevel": 248.2,
                      "profitLoss": 14,
                      "currency": "GBP",
                      "openedAt": "2025-12-30T10:10:00Z",
                      "closedAt": "2025-12-30T15:50:00Z"
                    },
                    {
                      "tradeId": "T-3009",
                      "instrumentId": "TIDE",
                      "instrumentName": "Tidewater Oil (invented commodity)",
                      "direction": "BUY",
                      "size": 6,
                      "openLevel": 60.6,
                      "closeLevel": 61.6,
                      "profitLoss": 6,
                      "currency": "GBP",
                      "openedAt": "2025-12-29T08:30:00Z",
                      "closedAt": "2025-12-29T15:00:00Z"
                    },
                    {
                      "tradeId": "T-3008",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "BUY",
                      "size": 1,
                      "openLevel": 5012,
                      "closeLevel": 5040.5,
                      "profitLoss": 28.5,
                      "currency": "GBP",
                      "openedAt": "2025-12-29T08:05:00Z",
                      "closedAt": "2025-12-29T14:20:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/trades/page-2.json": {
      "get": {
        "operationId": "trades-page-2",
        "summary": "Closed trades, page 2",
        "description": "The next five closed trades. Its next field holds the path of page 3.",
        "tags": [
          "Trade history"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#trades-page-2"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "asOf": "2026-01-05T09:30:00Z",
                  "order": "Newest first, by closedAt.",
                  "paging": {
                    "page": 2,
                    "pageSize": 5,
                    "totalPages": 3,
                    "totalRows": 12,
                    "next": "/trades/page-3.json",
                    "nextIs": "A path to add to the base address, or null on the last page."
                  },
                  "trades": [
                    {
                      "tradeId": "T-3007",
                      "instrumentId": "LNTN",
                      "instrumentName": "Lantern Metals (invented share)",
                      "direction": "BUY",
                      "size": 30,
                      "openLevel": 249.4,
                      "closeLevel": 249,
                      "profitLoss": -12,
                      "currency": "GBP",
                      "openedAt": "2025-12-24T09:40:00Z",
                      "closedAt": "2025-12-24T12:00:00Z"
                    },
                    {
                      "tradeId": "T-3006",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "BUY",
                      "size": 2,
                      "openLevel": 5022,
                      "closeLevel": 5010,
                      "profitLoss": -24,
                      "currency": "GBP",
                      "openedAt": "2025-12-23T15:30:00Z",
                      "closedAt": "2025-12-24T09:10:00Z"
                    },
                    {
                      "tradeId": "T-3005",
                      "instrumentId": "TIDE",
                      "instrumentName": "Tidewater Oil (invented commodity)",
                      "direction": "SELL",
                      "size": 4,
                      "openLevel": 61.3,
                      "closeLevel": 61,
                      "profitLoss": 1.2,
                      "currency": "GBP",
                      "openedAt": "2025-12-23T09:00:00Z",
                      "closedAt": "2025-12-23T14:45:00Z"
                    },
                    {
                      "tradeId": "T-3004",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "SELL",
                      "size": 1,
                      "openLevel": 5038,
                      "closeLevel": 5045.5,
                      "profitLoss": -7.5,
                      "currency": "GBP",
                      "openedAt": "2025-12-22T13:15:00Z",
                      "closedAt": "2025-12-23T08:20:00Z"
                    },
                    {
                      "tradeId": "T-3003",
                      "instrumentId": "LNTN",
                      "instrumentName": "Lantern Metals (invented share)",
                      "direction": "SELL",
                      "size": 10,
                      "openLevel": 251.8,
                      "closeLevel": 250.4,
                      "profitLoss": 14,
                      "currency": "GBP",
                      "openedAt": "2025-12-19T10:00:00Z",
                      "closedAt": "2025-12-22T11:30:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/trades/page-3.json": {
      "get": {
        "operationId": "trades-page-3",
        "summary": "Closed trades, page 3",
        "description": "The last two closed trades. Its next field is null, which is how a program knows to stop asking.",
        "tags": [
          "Trade history"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#trades-page-3"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "asOf": "2026-01-05T09:30:00Z",
                  "order": "Newest first, by closedAt.",
                  "paging": {
                    "page": 3,
                    "pageSize": 5,
                    "totalPages": 3,
                    "totalRows": 12,
                    "next": null,
                    "nextIs": "A path to add to the base address, or null on the last page."
                  },
                  "trades": [
                    {
                      "tradeId": "T-3002",
                      "instrumentId": "TIDE",
                      "instrumentName": "Tidewater Oil (invented commodity)",
                      "direction": "BUY",
                      "size": 5,
                      "openLevel": 60.3,
                      "closeLevel": 60.5,
                      "profitLoss": 1,
                      "currency": "GBP",
                      "openedAt": "2025-12-19T09:25:00Z",
                      "closedAt": "2025-12-19T16:05:00Z"
                    },
                    {
                      "tradeId": "T-3001",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "BUY",
                      "size": 1,
                      "openLevel": 5005,
                      "closeLevel": 5021,
                      "profitLoss": 16,
                      "currency": "GBP",
                      "openedAt": "2025-12-19T08:10:00Z",
                      "closedAt": "2025-12-19T15:40:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/orders.json": {
      "get": {
        "operationId": "orders",
        "summary": "Open orders",
        "description": "Two invented working orders that have not been filled: a limit order and a stop order.",
        "tags": [
          "Orders"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#orders"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "asOf": "2026-01-05T09:30:00Z",
                  "orders": [
                    {
                      "orderId": "O-2001",
                      "instrumentId": "TIDE",
                      "instrumentName": "Tidewater Oil (invented commodity)",
                      "direction": "BUY",
                      "type": "LIMIT",
                      "size": 3,
                      "level": 61.5,
                      "stopLevel": 59,
                      "limitLevel": 66,
                      "status": "WORKING",
                      "goodUntil": "CANCELLED",
                      "createdAt": "2026-01-02T16:10:00Z"
                    },
                    {
                      "orderId": "O-2002",
                      "instrumentId": "HBR100",
                      "instrumentName": "Harbour 100 (invented index)",
                      "direction": "SELL",
                      "type": "STOP",
                      "size": 1,
                      "level": 4990,
                      "stopLevel": null,
                      "limitLevel": null,
                      "status": "WORKING",
                      "goodUntil": "2026-01-30T16:30:00Z",
                      "createdAt": "2026-01-05T08:15:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/confirms/my-order-0001.json": {
      "get": {
        "operationId": "confirm-accepted",
        "summary": "An order confirmation: accepted",
        "description": "What a program reads back after sending an order, here with a status of ACCEPTED and the order's id. No order was sent and reading it changes nothing.",
        "tags": [
          "Orders"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#confirm-accepted"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "readOnly": "Reading this file changes nothing. It describes an order that was never sent: the practice API cannot place one.",
                  "confirmation": {
                    "clientReference": "my-order-0001",
                    "status": "ACCEPTED",
                    "reason": null,
                    "orderId": "O-2001",
                    "instrumentId": "TIDE",
                    "direction": "BUY",
                    "type": "LIMIT",
                    "size": 3,
                    "level": 61.5,
                    "receivedAt": "2026-01-02T16:10:00Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/confirms/my-order-0002.json": {
      "get": {
        "operationId": "confirm-rejected",
        "summary": "An order confirmation: rejected",
        "description": "A confirmation with a status of REJECTED and the reason in its body. No order was sent and reading it changes nothing.",
        "tags": [
          "Orders"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#confirm-rejected"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "readOnly": "Reading this file changes nothing. It describes an order that was never sent: the practice API cannot place one.",
                  "confirmation": {
                    "clientReference": "my-order-0002",
                    "status": "REJECTED",
                    "reason": "INSUFFICIENT_FUNDS",
                    "orderId": null,
                    "instrumentId": "HBR100",
                    "direction": "BUY",
                    "type": "MARKET",
                    "size": 500,
                    "level": null,
                    "receivedAt": "2026-01-05T09:12:00Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/instruments.json": {
      "get": {
        "operationId": "instruments",
        "summary": "Instrument search",
        "description": "The four invented instruments. A real search filters by what you ask for. This address cannot, so it always returns all four.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#instruments"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "query": "Fixed files cannot filter. Whatever you put after a question mark, this address returns the same four instruments.",
                  "count": 4,
                  "instruments": [
                    {
                      "id": "HBR100",
                      "name": "Harbour 100 (invented index)",
                      "type": "index",
                      "currency": "GBP",
                      "minSize": 0.5,
                      "status": "OPEN"
                    },
                    {
                      "id": "LNTN",
                      "name": "Lantern Metals (invented share)",
                      "type": "share",
                      "currency": "GBP",
                      "minSize": 1,
                      "status": "OPEN"
                    },
                    {
                      "id": "QUILL",
                      "name": "Quill and Ledger (invented share)",
                      "type": "share",
                      "currency": "GBP",
                      "minSize": 1,
                      "status": "CLOSED"
                    },
                    {
                      "id": "TIDE",
                      "name": "Tidewater Oil (invented commodity)",
                      "type": "commodity",
                      "currency": "GBP",
                      "minSize": 1,
                      "status": "OPEN"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/prices/HBR100.json": {
      "get": {
        "operationId": "price",
        "summary": "Price snapshot",
        "description": "One bid and offer for the invented index HBR100, with the day's high, low and change. It never moves.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#price"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "price": {
                    "instrumentId": "HBR100",
                    "instrumentName": "Harbour 100 (invented index)",
                    "bid": 5057,
                    "offer": 5058,
                    "high": 5062,
                    "low": 5040.5,
                    "change": 11.5,
                    "changePercent": 0.23,
                    "status": "OPEN",
                    "delayed": false,
                    "updatedAt": "2026-01-05T09:30:00Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/history/HBR100.json": {
      "get": {
        "operationId": "history",
        "summary": "Price history",
        "description": "Ten invented daily candles for HBR100, oldest first: open, high, low and close.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#history"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "instrumentId": "HBR100",
                  "instrumentName": "Harbour 100 (invented index)",
                  "resolution": "DAY",
                  "count": 10,
                  "candles": [
                    {
                      "date": "2025-12-19",
                      "open": 5010,
                      "high": 5032.5,
                      "low": 4998,
                      "close": 5021.5
                    },
                    {
                      "date": "2025-12-22",
                      "open": 5021.5,
                      "high": 5040,
                      "low": 5012,
                      "close": 5036
                    },
                    {
                      "date": "2025-12-23",
                      "open": 5036,
                      "high": 5051.5,
                      "low": 5020.5,
                      "close": 5024
                    },
                    {
                      "date": "2025-12-24",
                      "open": 5024,
                      "high": 5030,
                      "low": 5001.5,
                      "close": 5008.5
                    },
                    {
                      "date": "2025-12-29",
                      "open": 5008.5,
                      "high": 5044,
                      "low": 5006,
                      "close": 5041
                    },
                    {
                      "date": "2025-12-30",
                      "open": 5041,
                      "high": 5066.5,
                      "low": 5035,
                      "close": 5060.5
                    },
                    {
                      "date": "2025-12-31",
                      "open": 5060.5,
                      "high": 5071,
                      "low": 5048.5,
                      "close": 5052
                    },
                    {
                      "date": "2026-01-01",
                      "open": 5052,
                      "high": 5058,
                      "low": 5030,
                      "close": 5033.5
                    },
                    {
                      "date": "2026-01-02",
                      "open": 5033.5,
                      "high": 5049.5,
                      "low": 5025,
                      "close": 5046
                    },
                    {
                      "date": "2026-01-05",
                      "open": 5046,
                      "high": 5062,
                      "low": 5040.5,
                      "close": 5057.5
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/prices/LNTN.json": {
      "get": {
        "operationId": "price-lntn",
        "summary": "Price snapshot, second instrument",
        "description": "One bid and offer for the invented share LNTN, with the day's high, low and change. It never moves.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#price-lntn"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "price": {
                    "instrumentId": "LNTN",
                    "instrumentName": "Lantern Metals (invented share)",
                    "bid": 248.1,
                    "offer": 248.33,
                    "high": 249.1,
                    "low": 247.6,
                    "change": -0.2,
                    "changePercent": -0.08,
                    "status": "OPEN",
                    "delayed": false,
                    "updatedAt": "2026-01-05T09:30:00Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/history/LNTN.json": {
      "get": {
        "operationId": "history-lntn",
        "summary": "Price history, second instrument",
        "description": "Ten invented daily candles for LNTN, oldest first, on the same ten dates as HBR100.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#history-lntn"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "instrumentId": "LNTN",
                  "instrumentName": "Lantern Metals (invented share)",
                  "resolution": "DAY",
                  "count": 10,
                  "candles": [
                    {
                      "date": "2025-12-19",
                      "open": 252,
                      "high": 253.4,
                      "low": 250.6,
                      "close": 251.2
                    },
                    {
                      "date": "2025-12-22",
                      "open": 251.2,
                      "high": 252,
                      "low": 249.5,
                      "close": 250.1
                    },
                    {
                      "date": "2025-12-23",
                      "open": 250.1,
                      "high": 251.3,
                      "low": 248.9,
                      "close": 250.8
                    },
                    {
                      "date": "2025-12-24",
                      "open": 250.8,
                      "high": 251,
                      "low": 249.2,
                      "close": 249.6
                    },
                    {
                      "date": "2025-12-29",
                      "open": 249.6,
                      "high": 250.4,
                      "low": 247.8,
                      "close": 248.3
                    },
                    {
                      "date": "2025-12-30",
                      "open": 248.3,
                      "high": 249.9,
                      "low": 247.5,
                      "close": 249.4
                    },
                    {
                      "date": "2025-12-31",
                      "open": 249.4,
                      "high": 250.2,
                      "low": 248.6,
                      "close": 249
                    },
                    {
                      "date": "2026-01-01",
                      "open": 249,
                      "high": 249.5,
                      "low": 247,
                      "close": 247.4
                    },
                    {
                      "date": "2026-01-02",
                      "open": 247.4,
                      "high": 248.9,
                      "low": 246.8,
                      "close": 248.4
                    },
                    {
                      "date": "2026-01-05",
                      "open": 248.4,
                      "high": 249.1,
                      "low": 247.6,
                      "close": 248.2
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/prices/TIDE.json": {
      "get": {
        "operationId": "price-tide",
        "summary": "Price snapshot, third instrument",
        "description": "One bid and offer for the invented commodity TIDE, with the day's high, low and change. It never moves.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#price-tide"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "price": {
                    "instrumentId": "TIDE",
                    "instrumentName": "Tidewater Oil (invented commodity)",
                    "bid": 62.57,
                    "offer": 62.63,
                    "high": 62.9,
                    "low": 62.1,
                    "change": 0.3,
                    "changePercent": 0.48,
                    "status": "OPEN",
                    "delayed": false,
                    "updatedAt": "2026-01-05T09:30:00Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/history/TIDE.json": {
      "get": {
        "operationId": "history-tide",
        "summary": "Price history, third instrument",
        "description": "Ten invented daily candles for TIDE, oldest first, on the same ten dates as HBR100.",
        "tags": [
          "Market data"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#history-tide"
        },
        "responses": {
          "200": {
            "description": "The fixed file. It never changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "instrumentId": "TIDE",
                  "instrumentName": "Tidewater Oil (invented commodity)",
                  "resolution": "DAY",
                  "count": 10,
                  "candles": [
                    {
                      "date": "2025-12-19",
                      "open": 60.2,
                      "high": 60.9,
                      "low": 59.8,
                      "close": 60.5
                    },
                    {
                      "date": "2025-12-22",
                      "open": 60.5,
                      "high": 61.4,
                      "low": 60.1,
                      "close": 61.2
                    },
                    {
                      "date": "2025-12-23",
                      "open": 61.2,
                      "high": 61.8,
                      "low": 60.6,
                      "close": 60.9
                    },
                    {
                      "date": "2025-12-24",
                      "open": 60.9,
                      "high": 61.3,
                      "low": 60.2,
                      "close": 60.4
                    },
                    {
                      "date": "2025-12-29",
                      "open": 60.4,
                      "high": 61.9,
                      "low": 60.3,
                      "close": 61.7
                    },
                    {
                      "date": "2025-12-30",
                      "open": 61.7,
                      "high": 62.8,
                      "low": 61.5,
                      "close": 62.5
                    },
                    {
                      "date": "2025-12-31",
                      "open": 62.5,
                      "high": 63.1,
                      "low": 62,
                      "close": 62.2
                    },
                    {
                      "date": "2026-01-01",
                      "open": 62.2,
                      "high": 62.6,
                      "low": 61.6,
                      "close": 61.9
                    },
                    {
                      "date": "2026-01-02",
                      "open": 61.9,
                      "high": 62.7,
                      "low": 61.6,
                      "close": 62.3
                    },
                    {
                      "date": "2026-01-05",
                      "open": 62.3,
                      "high": 62.9,
                      "low": 62.1,
                      "close": 62.6
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/errors/session-expired.json": {
      "get": {
        "operationId": "error-session-expired",
        "summary": "An expired session",
        "description": "The body a server sends when a session has run out and you must sign in again. Served with status 200, because a host of fixed files cannot choose a status. A real server would send 401, and this body says so in error.status.",
        "tags": [
          "Example errors"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#error-session-expired"
        },
        "responses": {
          "200": {
            "description": "The body a server would send with status 401, served here with 200.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "served": "This file is served with status 200, because a host of fixed files cannot choose a status for each request. The status a real server would send is in error.status.",
                  "error": {
                    "status": 401,
                    "code": "session_expired",
                    "message": "The session has expired. Sign in again to get a new one, then repeat the request."
                  }
                }
              }
            }
          }
        },
        "x-would-be-status": 401
      }
    },
    "/errors/rate-limited.json": {
      "get": {
        "operationId": "error-rate-limited",
        "summary": "A rate limit refusal",
        "description": "The body a server sends when you have asked too often, with a retryAfterSeconds field and the Retry-After header it would carry. Served with status 200, because a host of fixed files cannot choose a status. A real server would send 429, and this body says so in error.status.",
        "tags": [
          "Example errors"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#error-rate-limited"
        },
        "responses": {
          "200": {
            "description": "The body a server would send with status 429, served here with 200.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "served": "This file is served with status 200, because a host of fixed files cannot choose a status for each request. The status a real server would send is in error.status.",
                  "error": {
                    "status": 429,
                    "code": "rate_limited",
                    "message": "Too many requests. Wait for the number of seconds in retryAfterSeconds, then try again.",
                    "retryAfterSeconds": 30,
                    "limit": 60,
                    "window": "minute",
                    "headers": {
                      "Retry-After": "30"
                    }
                  }
                }
              }
            }
          }
        },
        "x-would-be-status": 429
      }
    },
    "/errors/order-rejected.json": {
      "get": {
        "operationId": "error-order-rejected",
        "summary": "A rejected order",
        "description": "The body a server sends when it understood an order and refused it, here for lack of funds. Served with status 200, because a host of fixed files cannot choose a status. A real server would send 422, and this body says so in error.status.",
        "tags": [
          "Example errors"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#error-order-rejected"
        },
        "responses": {
          "200": {
            "description": "The body a server would send with status 422, served here with 200.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "served": "This file is served with status 200, because a host of fixed files cannot choose a status for each request. The status a real server would send is in error.status.",
                  "error": {
                    "status": 422,
                    "code": "order_rejected",
                    "message": "The order was understood and refused. Read reason: sending the same order again will be refused again.",
                    "reason": "INSUFFICIENT_FUNDS",
                    "order": {
                      "instrumentId": "HBR100",
                      "direction": "BUY",
                      "size": 500
                    },
                    "marginNeeded": 126437.5,
                    "available": 8794
                  }
                }
              }
            }
          }
        },
        "x-would-be-status": 422
      }
    },
    "/errors/validation.json": {
      "get": {
        "operationId": "error-validation",
        "summary": "A validation error",
        "description": "The body a server sends when a request is malformed, naming each field to correct. Served with status 200, because a host of fixed files cannot choose a status. A real server would send 400, and this body says so in error.status.",
        "tags": [
          "Example errors"
        ],
        "externalDocs": {
          "description": "This address on the practice API page",
          "url": "https://openbrokerapi.com/mock#error-validation"
        },
        "responses": {
          "200": {
            "description": "The body a server would send with status 400, served here with 200.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "practice"
                  ],
                  "properties": {
                    "practice": {
                      "const": true,
                      "description": "True in every reply from the practice API, so practice data can always be told from the real thing."
                    }
                  }
                },
                "example": {
                  "practice": true,
                  "notice": "Practice data from openbrokerapi.com. Every value is invented. This is not any broker's API.",
                  "served": "This file is served with status 200, because a host of fixed files cannot choose a status for each request. The status a real server would send is in error.status.",
                  "error": {
                    "status": 400,
                    "code": "validation_failed",
                    "message": "The request was not valid, so nothing was done. Each entry in fields names one thing to correct.",
                    "fields": [
                      {
                        "field": "size",
                        "problem": "must be a number greater than 0",
                        "received": "two"
                      },
                      {
                        "field": "direction",
                        "problem": "must be BUY or SELL",
                        "received": "LONG"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-would-be-status": 400
      }
    }
  }
}