{
  "openapi": "3.1.0",
  "info": {
    "title": "Sportily Scores API",
    "version": "v1",
    "x-lifecycle": "preview",
    "summary": "Horse-racing model scores as clean JSON, for programmatic use.",
    "description": "**Preview.** The Scores API is invitation-only and under a signed data licence.\nRequest access at https://sportily.app/developers.\n\nModel win probabilities, speed figures and value edge for every scored runner,\nwith the detail needed to identify a race and a runner.\n\nOwn use only. No redistribution, resale, or onward sharing of Sportily data or any derived value. Access is per-account and non-transferable.",
    "contact": {
      "name": "Sportily",
      "url": "https://sportily.app/developers"
    }
  },
  "servers": [
    {
      "url": "https://sportily.app/api/v1",
      "description": "Production (preview — access on request)"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/scores": {
      "get": {
        "operationId": "getScores",
        "summary": "Scores for a racing day",
        "description": "Every scored race for a single LOCAL racing day, with per-runner model output. Limited to a rolling 365-day window. Before a day's scores reach their publish time the endpoint returns 409 `not_yet_published` rather than partial data.",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Local racing day, YYYY-MM-DD.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Narrow the day to one region.",
            "schema": {
              "type": "string",
              "enum": [
                "GB",
                "IRE",
                "AUS"
              ]
            }
          },
          {
            "name": "course",
            "in": "query",
            "required": false,
            "description": "Narrow the day to one course, matched case-insensitively by name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Scores for the day.",
            "headers": {
              "x-quota-remaining-minute": {
                "description": "Units left in the current minute window on the lane this call spent from.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining-day": {
                "description": "Units left in the current day window on the lane this call spent from.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoresResponse"
                },
                "example": {
                  "date": "2026-08-12",
                  "publishedAt": "2026-08-12T07:00:00Z",
                  "races": [
                    {
                      "raceId": "sr_9Qk2m",
                      "course": "Newmarket",
                      "offTime": "2026-08-12T13:50:00Z",
                      "raceName": "Sportily Handicap",
                      "fieldSize": 8,
                      "runners": [
                        {
                          "horseId": "hrs_4Tn8v",
                          "runnerNumber": 1,
                          "horseName": "Example Runner",
                          "jockeyName": "A. Jockey",
                          "trainerName": "B. Trainer",
                          "modelWinPct": 28.4,
                          "modelRank": 1,
                          "modelGapNext": 6.1,
                          "speedFigure": 92.5
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account not enabled for the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No races for the requested date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Scores not published yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Date outside the rolling window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/races/{raceId}": {
      "get": {
        "operationId": "getRace",
        "summary": "One race card by id",
        "description": "The same race object the day search returns, fetched directly. Gated on the race's OWN racing day: a future card returns 409 until its publish time, and a race older than the rolling window is out of reach by id too.",
        "parameters": [
          {
            "name": "raceId",
            "in": "path",
            "required": true,
            "description": "The raceId from /scores or /lenses/matches.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The race.",
            "headers": {
              "x-quota-remaining-minute": {
                "description": "Units left in the current minute window on the lane this call spent from.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining-day": {
                "description": "Units left in the current day window on the lane this call spent from.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaceResponse"
                },
                "example": {
                  "date": "2026-08-12",
                  "race": {
                    "raceId": "sr_9Qk2m",
                    "course": "Newmarket",
                    "offTime": "2026-08-12T13:50:00Z",
                    "raceName": "Sportily Handicap",
                    "fieldSize": 8,
                    "runners": [
                      {
                        "horseId": "hrs_4Tn8v",
                        "runnerNumber": 1,
                        "horseName": "Example Runner",
                        "jockeyName": "A. Jockey",
                        "trainerName": "B. Trainer",
                        "modelWinPct": 28.4,
                        "modelRank": 1,
                        "modelGapNext": 6.1,
                        "speedFigure": 92.5
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account not enabled for the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No race with that id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The race's day is not published yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The race's day is outside the rolling window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/lenses": {
      "get": {
        "operationId": "getLenses",
        "summary": "The account's Race Lens definitions",
        "description": "The id dictionary for /lenses/matches. Lenses are created and edited in the Race Lens app, never via the API. Free.",
        "responses": {
          "200": {
            "description": "Lens definitions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LensesResponse"
                },
                "example": {
                  "lenses": [
                    {
                      "id": "lns_7Hd3k",
                      "name": "Front-runners at 5f"
                    },
                    {
                      "id": "lns_2Rw9p",
                      "name": "Top pick, big gap"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account not enabled for the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/lenses/matches": {
      "get": {
        "operationId": "getLensMatches",
        "summary": "Which runners passed your lenses on a racing day",
        "description": "The races where your lenses matched, served as the FULL field: every runner in the same shape as /scores, each carrying a `lenses` array of the lens ids it passed (empty for the rest of the field). Membership is precomputed before the day publishes and refreshed through the racing day (lens edits, non-runners, re-scores); runner values are joined live. A lens listed in `stale` has NOT been computed for that day (or was edited since) — that is a different answer from an empty `races` and must not be read as \"no matches\". On TODAY a stale lens is recomputed automatically: `stale[].refresh` reports queued/retry_shortly, and `retryAfterSeconds` says when one short retry will usually serve it. Past days are never recomputed. Charged on a separate, smaller Race Lens allowance; one call reads up to 6 lenses and costs far less than separate calls.",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": false,
            "description": "Local racing day, YYYY-MM-DD. Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "lens",
            "in": "query",
            "required": false,
            "description": "Comma-separated lens ids (from /lenses). Defaults to every lens on the account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matched races for the day, full field.",
            "headers": {
              "x-quota-remaining-minute": {
                "description": "Units left in the current minute window on the lane this call spent from.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining-day": {
                "description": "Units left in the current day window on the lane this call spent from.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LensMatchesResponse"
                },
                "example": {
                  "date": "2026-08-12",
                  "computedAt": "2026-08-12T06:45:12Z",
                  "lenses": [
                    {
                      "lensId": "lns_7Hd3k",
                      "name": "Front-runners at 5f",
                      "computedAt": "2026-08-12T06:45:12Z"
                    },
                    {
                      "lensId": "lns_2Rw9p",
                      "name": "Top pick, big gap",
                      "computedAt": "2026-08-12T06:45:14Z"
                    }
                  ],
                  "races": [
                    {
                      "raceId": "sr_9Qk2m",
                      "course": "Newmarket",
                      "offTime": "2026-08-12T13:50:00Z",
                      "raceName": "Sportily Handicap",
                      "fieldSize": 8,
                      "runners": [
                        {
                          "horseId": "hrs_4Tn8v",
                          "runnerNumber": 1,
                          "horseName": "Example Runner",
                          "jockeyName": "A. Jockey",
                          "trainerName": "B. Trainer",
                          "modelWinPct": 28.4,
                          "modelRank": 1,
                          "modelGapNext": 6.1,
                          "speedFigure": 92.5,
                          "lenses": [
                            "lns_7Hd3k",
                            "lns_2Rw9p"
                          ]
                        },
                        {
                          "horseId": "hrs_8Kc2j",
                          "runnerNumber": 2,
                          "horseName": "Rest Of Field",
                          "jockeyName": "C. Jockey",
                          "trainerName": "D. Trainer",
                          "modelWinPct": 22.3,
                          "modelRank": 2,
                          "modelGapNext": 4.9,
                          "speedFigure": 88.1,
                          "lenses": []
                        }
                      ]
                    }
                  ],
                  "stale": [
                    {
                      "lensId": "lns_5Xb1q",
                      "reason": "ast_changed",
                      "refresh": "queued"
                    }
                  ],
                  "retryAfterSeconds": 10
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account not enabled for the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A requested lens id does not exist on this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Data for the requested date is not published yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Date outside the rolling window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Race Lens allowance exceeded; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Current spend against both allowances",
        "description": "Free, so budget checks never cost budget.",
        "responses": {
          "200": {
            "description": "Usage for the current minute and day windows.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                },
                "example": {
                  "general": {
                    "minute": {
                      "used": 4,
                      "limit": 300,
                      "resetsAt": "2026-08-12T09:31:00Z"
                    },
                    "day": {
                      "used": 812,
                      "limit": 20000,
                      "resetsAt": "2026-08-13T00:00:00Z"
                    }
                  },
                  "raceLens": {
                    "minute": {
                      "used": 6,
                      "limit": 30,
                      "resetsAt": "2026-08-12T09:31:00Z"
                    },
                    "day": {
                      "used": 45,
                      "limit": 600,
                      "resetsAt": "2026-08-13T00:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account not enabled for the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Key check plus today's publish clock",
        "description": "Free. Use it to verify a key and to learn when today publishes.",
        "responses": {
          "200": {
            "description": "API status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                },
                "example": {
                  "ok": true,
                  "lifecycle": "preview",
                  "version": "v1",
                  "keyPrefix": "sportily_ab12cd3",
                  "now": "2026-08-12T09:30:41Z",
                  "today": "2026-08-12",
                  "todayPublishesAt": "2026-08-12T07:00:00Z",
                  "todayPublished": true
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sportily_… (issued per account; store hashed, treat as a secret)"
      }
    },
    "schemas": {
      "ScoresResponse": {
        "type": "object",
        "required": [
          "date",
          "races"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "races": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Race"
            }
          }
        }
      },
      "Race": {
        "type": "object",
        "properties": {
          "raceId": {
            "type": "string",
            "description": "Stable Sportily race id. Use it to key your own records."
          },
          "course": {
            "type": "string",
            "description": "Racecourse name."
          },
          "offTime": {
            "type": "string",
            "description": "Scheduled off time, ISO 8601."
          },
          "raceName": {
            "type": "string",
            "description": "Published race title."
          },
          "fieldSize": {
            "type": "integer",
            "description": "Number of declared runners."
          },
          "runners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Runner"
            }
          }
        }
      },
      "Runner": {
        "type": "object",
        "properties": {
          "horseId": {
            "type": "string",
            "description": "Stable horse id. With raceId, the key for your own records and for /lenses/matches."
          },
          "runnerNumber": {
            "type": "integer",
            "description": "Saddlecloth number."
          },
          "horseName": {
            "type": "string",
            "description": "Horse name."
          },
          "jockeyName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Jockey."
          },
          "trainerName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Trainer."
          },
          "modelWinPct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Win probability as a percentage, 0–100. Null when the runner is not scored."
          },
          "modelRank": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Rank within the field by model win probability, 1 = most favoured."
          },
          "modelGapNext": {
            "type": [
              "number",
              "null"
            ],
            "description": "Model win-probability gap to the next-ranked runner. A separation measure."
          },
          "speedFigure": {
            "type": [
              "number",
              "null"
            ],
            "description": "Sportily speed figure for the runner's recent form."
          },
          "edgePct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Model probability minus market-implied probability, in points."
          },
          "impliedProbPct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Market-implied probability as a percentage, 0–100."
          }
        }
      },
      "RaceResponse": {
        "type": "object",
        "required": [
          "date",
          "race"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "race": {
            "$ref": "#/components/schemas/Race"
          }
        }
      },
      "MatchedRunner": {
        "type": "object",
        "description": "A /scores runner plus the lenses it passed.",
        "properties": {
          "horseId": {
            "type": "string",
            "description": "Stable horse id. With raceId, the key for your own records and for /lenses/matches."
          },
          "runnerNumber": {
            "type": "integer",
            "description": "Saddlecloth number."
          },
          "horseName": {
            "type": "string",
            "description": "Horse name."
          },
          "jockeyName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Jockey."
          },
          "trainerName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Trainer."
          },
          "modelWinPct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Win probability as a percentage, 0–100. Null when the runner is not scored."
          },
          "modelRank": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Rank within the field by model win probability, 1 = most favoured."
          },
          "modelGapNext": {
            "type": [
              "number",
              "null"
            ],
            "description": "Model win-probability gap to the next-ranked runner. A separation measure."
          },
          "speedFigure": {
            "type": [
              "number",
              "null"
            ],
            "description": "Sportily speed figure for the runner's recent form."
          },
          "edgePct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Model probability minus market-implied probability, in points."
          },
          "impliedProbPct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Market-implied probability as a percentage, 0–100."
          },
          "lenses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Ids of your lenses this runner passed. Empty for the rest of the field."
          }
        }
      },
      "MatchedRace": {
        "type": "object",
        "description": "A /scores race whose runners carry lens membership.",
        "properties": {
          "raceId": {
            "type": "string",
            "description": "Stable Sportily race id. Use it to key your own records."
          },
          "course": {
            "type": "string",
            "description": "Racecourse name."
          },
          "offTime": {
            "type": "string",
            "description": "Scheduled off time, ISO 8601."
          },
          "raceName": {
            "type": "string",
            "description": "Published race title."
          },
          "fieldSize": {
            "type": "integer",
            "description": "Number of declared runners."
          },
          "runners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchedRunner"
            }
          }
        }
      },
      "LensesResponse": {
        "type": "object",
        "required": [
          "lenses"
        ],
        "properties": {
          "lenses": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "LensMatchesResponse": {
        "type": "object",
        "required": [
          "date",
          "races",
          "stale"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "computedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The OLDEST served snapshot — the payload is only as current as its stalest lens."
          },
          "lenses": {
            "type": "array",
            "description": "Names and snapshot times of the lenses actually served.",
            "items": {
              "type": "object",
              "required": [
                "lensId",
                "computedAt"
              ],
              "properties": {
                "lensId": {
                  "type": "string"
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "computedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "races": {
            "type": "array",
            "description": "Every race where at least one lens matched, as the FULL field with membership flags.",
            "items": {
              "$ref": "#/components/schemas/MatchedRace"
            }
          },
          "stale": {
            "type": "array",
            "description": "Lenses with no usable snapshot for this day. NOT the same as zero matches.",
            "items": {
              "type": "object",
              "required": [
                "lensId",
                "reason",
                "refresh"
              ],
              "properties": {
                "lensId": {
                  "type": "string"
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "missing",
                    "ast_changed"
                  ]
                },
                "refresh": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "retry_shortly",
                    "unavailable"
                  ],
                  "description": "Self-repair state. `queued`: a recompute was just started by this read. `retry_shortly`: one is already under way or just ran. `unavailable`: this day will not be recomputed (past days never are)."
                }
              }
            }
          },
          "retryAfterSeconds": {
            "type": "integer",
            "description": "Present when a stale lens is being recomputed: poll again after this many seconds and the lens will usually be served."
          }
        }
      },
      "UsageWindow": {
        "type": "object",
        "required": [
          "used",
          "limit",
          "resetsAt"
        ],
        "properties": {
          "used": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "resetsAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UsageResponse": {
        "type": "object",
        "required": [
          "general",
          "raceLens"
        ],
        "properties": {
          "general": {
            "type": "object",
            "properties": {
              "minute": {
                "$ref": "#/components/schemas/UsageWindow"
              },
              "day": {
                "$ref": "#/components/schemas/UsageWindow"
              }
            }
          },
          "raceLens": {
            "type": "object",
            "properties": {
              "minute": {
                "$ref": "#/components/schemas/UsageWindow"
              },
              "day": {
                "$ref": "#/components/schemas/UsageWindow"
              }
            }
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "required": [
          "ok",
          "lifecycle",
          "version"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "lifecycle": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "keyPrefix": {
            "type": "string"
          },
          "now": {
            "type": "string",
            "format": "date-time"
          },
          "today": {
            "type": "string",
            "format": "date"
          },
          "todayPublishesAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "todayPublished": {
            "type": "boolean"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthorized",
                  "forbidden",
                  "rate_limited",
                  "not_yet_published",
                  "out_of_window",
                  "not_found",
                  "invalid_request",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}