{
  "openapi": "3.1.0",
  "info": {
    "title": "Skarb API",
    "version": "1",
    "description": "Your own data in Skarb by a token: send your trades on every plan, read your portfolio and scores from Pro. Personal and non-commercial use — https://skarb.dev/terms#api. Guide: https://skarb.dev/docs/api."
  },
  "servers": [
    {
      "url": "https://api.skarb.dev"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "The token itself."
    },
    {
      "name": "Ingest",
      "description": "Your own sources and what they send. Every plan."
    },
    {
      "name": "Read",
      "description": "Your portfolio, history and Skarb’s scores. Pro and up."
    }
  ],
  "paths": {
    "/v1/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Who the token is: the plan, the token, its limits and today’s use",
        "tags": [
          "Account"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "userId": {
                      "type": "string",
                      "description": "The person’s id in Skarb."
                    },
                    "plan": {
                      "type": "string",
                      "enum": [
                        "base",
                        "pro",
                        "ultra",
                        "owner"
                      ],
                      "description": "The plan in force right now: base, pro, ultra or owner."
                    },
                    "token": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The token’s id."
                        },
                        "name": {
                          "type": "string",
                          "description": "The name it was given in the settings."
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "ingest",
                              "read",
                              "mcp"
                            ]
                          },
                          "description": "What it was made for."
                        },
                        "connectionId": {
                          "description": "The one connection it sends data to; null for any.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "portfolioSlot": {
                          "anyOf": [
                            {
                              "type": "string",
                              "enum": [
                                "main",
                                "secondary",
                                "third",
                                "p4",
                                "p5",
                                "p6",
                                "p7",
                                "p8",
                                "p9",
                                "p10",
                                "demo"
                              ]
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The one portfolio it reads; null for any."
                        },
                        "expiresAt": {
                          "description": "When it runs out; null for never.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "scopes",
                        "connectionId",
                        "portfolioSlot",
                        "expiresAt"
                      ]
                    },
                    "limits": {
                      "type": "object",
                      "properties": {
                        "requestsPerMinute": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Requests a minute, this token; null where the plan has no limit."
                        },
                        "requestsPerDay": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Requests a day, all of one’s tokens, Kyiv time; null where the plan has no limit."
                        },
                        "ingestRowsPerDay": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Rows sent in a day, Kyiv time; null where the plan has no limit."
                        },
                        "instrumentsPerConnection": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Different instruments a connection holds; null where the plan has no limit."
                        },
                        "batchMaxRows": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows a batch at most."
                        }
                      },
                      "required": [
                        "requestsPerMinute",
                        "requestsPerDay",
                        "ingestRowsPerDay",
                        "instrumentsPerConnection",
                        "batchMaxRows"
                      ]
                    },
                    "usageToday": {
                      "type": "object",
                      "properties": {
                        "requests": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Requests today."
                        },
                        "ingestRows": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows sent in today."
                        },
                        "mcpCalls": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Tools called over MCP today."
                        },
                        "assetScores": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Asset scores today, the screen and the API together."
                        },
                        "tradeChecks": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Trade checks today, the screen and the API together."
                        },
                        "diaryEntries": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Diary entries today, the screen and the API together."
                        }
                      },
                      "required": [
                        "requests",
                        "ingestRows",
                        "mcpCalls",
                        "assetScores",
                        "tradeChecks",
                        "diaryEntries"
                      ]
                    },
                    "day": {
                      "type": "string",
                      "format": "date",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
                      "description": "Today, Kyiv time: when the daily counters start over."
                    },
                    "timezone": {
                      "type": "string",
                      "const": "Europe/Kyiv",
                      "description": "The zone the days are counted in."
                    }
                  },
                  "required": [
                    "userId",
                    "plan",
                    "token",
                    "limits",
                    "usageToday",
                    "day",
                    "timezone"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections": {
      "get": {
        "operationId": "getConnections",
        "summary": "Your own sources, with what their rows hold",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "connections": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The connection’s id, to send rows to."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name."
                          },
                          "portfolio": {
                            "type": "string",
                            "enum": [
                              "main",
                              "secondary",
                              "third",
                              "p4",
                              "p5",
                              "p6",
                              "p7",
                              "p8",
                              "p9",
                              "p10",
                              "demo"
                            ],
                            "description": "The portfolio its account sits in."
                          },
                          "currency": {
                            "type": "string",
                            "enum": [
                              "USD",
                              "EUR"
                            ],
                            "description": "The account’s currency."
                          },
                          "createdAt": {
                            "type": "string",
                            "description": "When it was made."
                          },
                          "counts": {
                            "type": "object",
                            "properties": {
                              "rows": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991,
                                "description": "Rows sent in, every standing."
                              },
                              "pending": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991,
                                "description": "Rows waiting for their instrument."
                              },
                              "rejected": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991,
                                "description": "Rows turned away."
                              },
                              "instruments": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991,
                                "description": "Different instruments its rows name."
                              }
                            },
                            "required": [
                              "rows",
                              "pending",
                              "rejected",
                              "instruments"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "portfolio",
                          "currency",
                          "createdAt",
                          "counts"
                        ]
                      }
                    }
                  },
                  "required": [
                    "connections"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postConnections",
        "summary": "Make a source of your own, with its account",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "What the connection is called on the screens, such as the broker’s name."
                  },
                  "portfolio": {
                    "type": "string",
                    "enum": [
                      "main",
                      "secondary",
                      "third",
                      "p4",
                      "p5",
                      "p6",
                      "p7",
                      "p8",
                      "p9",
                      "p10",
                      "demo"
                    ],
                    "description": "The portfolio its account sits in: main, secondary or demo."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "USD",
                      "EUR"
                    ],
                    "description": "The account’s currency: USD or EUR."
                  }
                },
                "required": [
                  "name",
                  "portfolio",
                  "currency"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The connection’s id, to send rows to."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name."
                    },
                    "portfolio": {
                      "type": "string",
                      "enum": [
                        "main",
                        "secondary",
                        "third",
                        "p4",
                        "p5",
                        "p6",
                        "p7",
                        "p8",
                        "p9",
                        "p10",
                        "demo"
                      ],
                      "description": "The portfolio its account sits in."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "USD",
                        "EUR"
                      ],
                      "description": "The account’s currency."
                    },
                    "createdAt": {
                      "type": "string",
                      "description": "When it was made."
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "rows": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows sent in, every standing."
                        },
                        "pending": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows waiting for their instrument."
                        },
                        "rejected": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows turned away."
                        },
                        "instruments": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Different instruments its rows name."
                        }
                      },
                      "required": [
                        "rows",
                        "pending",
                        "rejected",
                        "instruments"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "portfolio",
                    "currency",
                    "createdAt",
                    "counts"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `limit_connections`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{id}": {
      "get": {
        "operationId": "getConnectionsById",
        "summary": "One of your sources",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The connection’s id, to send rows to."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name."
                    },
                    "portfolio": {
                      "type": "string",
                      "enum": [
                        "main",
                        "secondary",
                        "third",
                        "p4",
                        "p5",
                        "p6",
                        "p7",
                        "p8",
                        "p9",
                        "p10",
                        "demo"
                      ],
                      "description": "The portfolio its account sits in."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "USD",
                        "EUR"
                      ],
                      "description": "The account’s currency."
                    },
                    "createdAt": {
                      "type": "string",
                      "description": "When it was made."
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "rows": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows sent in, every standing."
                        },
                        "pending": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows waiting for their instrument."
                        },
                        "rejected": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Rows turned away."
                        },
                        "instruments": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991,
                          "description": "Different instruments its rows name."
                        }
                      },
                      "required": [
                        "rows",
                        "pending",
                        "rejected",
                        "instruments"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "portfolio",
                    "currency",
                    "createdAt",
                    "counts"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteConnectionsById",
        "summary": "Delete a source with its account; the tokens made for it are revoked",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Confirm",
            "in": "header",
            "required": true,
            "description": "Must be `delete`: what it does cannot be undone.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deletedRows": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows sent in, deleted."
                    },
                    "deletedTrades": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Trades made from them, deleted."
                    },
                    "deletedCashFlows": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Cash movements made from them, deleted."
                    }
                  },
                  "required": [
                    "deletedRows",
                    "deletedTrades",
                    "deletedCashFlows"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`confirm_required`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{id}/reset": {
      "post": {
        "operationId": "postConnectionsByIdReset",
        "summary": "Take out every row a source sent, and what was made of them; the source stays",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Confirm",
            "in": "header",
            "required": true,
            "description": "Must be `reset`: what it does cannot be undone.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deletedRows": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows sent in, deleted."
                    },
                    "deletedTrades": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Trades made from them, deleted."
                    },
                    "deletedCashFlows": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Cash movements made from them, deleted."
                    }
                  },
                  "required": [
                    "deletedRows",
                    "deletedTrades",
                    "deletedCashFlows"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`confirm_required`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{id}/trades": {
      "post": {
        "operationId": "postConnectionsByIdTrades",
        "summary": "Send trades, up to a thousand a batch",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any string up to 255 characters: a batch sent again with it is answered as the first time, for 24 hours.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "trades": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "externalId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "The trade’s id in the source: sent again, it is the same row."
                        },
                        "instrument": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "assetClass": {
                                  "type": "string",
                                  "const": "crypto",
                                  "description": "crypto."
                                },
                                "symbol": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 20,
                                  "description": "The coin’s symbol, such as \"BTC\"."
                                }
                              },
                              "required": [
                                "assetClass",
                                "symbol"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "assetClass": {
                                  "type": "string",
                                  "enum": [
                                    "stock",
                                    "etf"
                                  ],
                                  "description": "stock or etf."
                                },
                                "isin": {
                                  "type": "string",
                                  "pattern": "^[A-Z]{2}[A-Z0-9]{9}\\d$",
                                  "description": "ISIN, such as \"US0378331005\"."
                                },
                                "ticker": {
                                  "description": "The ticker on its venue.",
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 20
                                },
                                "mic": {
                                  "type": "string",
                                  "pattern": "^[A-Z0-9]{4}$",
                                  "description": "The venue’s MIC, ISO 10383, such as \"XNAS\" or \"XETR\"."
                                }
                              },
                              "required": [
                                "assetClass"
                              ],
                              "additionalProperties": false
                            }
                          ],
                          "description": "A share or a fund by its ISIN or its ticker and MIC; a coin by its symbol."
                        },
                        "side": {
                          "type": "string",
                          "enum": [
                            "buy",
                            "sell"
                          ],
                          "description": "buy or sell."
                        },
                        "quantity": {
                          "type": "string",
                          "pattern": "^\\d{1,20}(\\.\\d{1,18})?$",
                          "description": "A decimal above zero as a string with a point, such as \"0.5\". Never a number."
                        },
                        "price": {
                          "type": "string",
                          "pattern": "^\\d{1,20}(\\.\\d{1,18})?$",
                          "description": "A non-negative decimal as a string with a point, such as \"12.5\". Never a number."
                        },
                        "currency": {
                          "type": "string",
                          "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "GBX",
                            "CHF",
                            "JPY",
                            "CNY",
                            "HKD",
                            "SEK",
                            "NOK",
                            "DKK",
                            "USDT",
                            "USDC"
                          ],
                          "description": "The trade’s currency: USD, EUR, GBP, GBX, CHF, JPY, CNY, HKD, SEK, NOK or DKK; for a coin USD, USDT or USDC."
                        },
                        "fee": {
                          "type": "string",
                          "pattern": "^\\d{1,20}(\\.\\d{1,18})?$",
                          "description": "A non-negative decimal as a string with a point, such as \"12.5\". Never a number."
                        },
                        "feeCurrency": {
                          "type": "string",
                          "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "GBX",
                            "CHF",
                            "JPY",
                            "CNY",
                            "HKD",
                            "SEK",
                            "NOK",
                            "DKK",
                            "USDT",
                            "USDC"
                          ],
                          "description": "The trade’s currency: USD, EUR, GBP, GBX, CHF, JPY, CNY, HKD, SEK, NOK or DKK; for a coin USD, USDT or USDC."
                        },
                        "executedAt": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                          "description": "ISO 8601 with a zone, such as \"2026-09-30T14:32:10+02:00\". No zone is refused."
                        },
                        "note": {
                          "description": "Up to 500 characters, kept with the row.",
                          "type": "string",
                          "maxLength": 500
                        }
                      },
                      "required": [
                        "externalId",
                        "instrument",
                        "side",
                        "quantity",
                        "price",
                        "currency",
                        "executedAt"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "trades"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows new to Skarb."
                    },
                    "updated": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows sent before and changed since."
                    },
                    "unchanged": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows sent before, the same."
                    },
                    "rejected": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "externalId": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string",
                            "enum": [
                              "instrument_unresolved",
                              "unsupported_crypto",
                              "limit_instruments"
                            ]
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "externalId",
                          "code",
                          "message"
                        ]
                      },
                      "description": "Rows of this batch turned away, and why."
                    },
                    "pending": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "externalId": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "instrument_unresolved",
                              "unsupported_crypto",
                              "limit_instruments"
                            ]
                          }
                        },
                        "required": [
                          "externalId",
                          "reason"
                        ]
                      },
                      "description": "Rows of this batch waiting for their instrument."
                    },
                    "connection": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "instruments": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "pendingTotal": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "id",
                        "instruments",
                        "pendingTotal"
                      ]
                    }
                  },
                  "required": [
                    "accepted",
                    "updated",
                    "unchanged",
                    "rejected",
                    "pending",
                    "connection"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `limit_connections`, `limit_history`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_in_progress`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`, `batch_too_large`, `idempotency_conflict`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{id}/cash-flows": {
      "post": {
        "operationId": "postConnectionsByIdCashFlows",
        "summary": "Send deposits, withdrawals, dividends, interest, fees and taxes",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any string up to 255 characters: a batch sent again with it is answered as the first time, for 24 hours.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cashFlows": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "externalId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "The movement’s id in the source."
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "deposit",
                            "withdrawal",
                            "dividend",
                            "interest",
                            "fee",
                            "tax",
                            "conversion",
                            "staking_reward"
                          ],
                          "description": "deposit, withdrawal, dividend, interest, fee, tax, conversion or staking_reward."
                        },
                        "amount": {
                          "type": "string",
                          "pattern": "^-?\\d{1,20}(\\.\\d{1,18})?$",
                          "description": "Money in above zero, money out below, as a string: \"1000\", \"-0.36\"."
                        },
                        "currency": {
                          "type": "string",
                          "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "GBX",
                            "CHF",
                            "JPY",
                            "CNY",
                            "HKD",
                            "SEK",
                            "NOK",
                            "DKK"
                          ],
                          "description": "USD, EUR, GBP, GBX, CHF, JPY, CNY, HKD, SEK, NOK or DKK."
                        },
                        "occurredAt": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                          "description": "ISO 8601 with a zone, such as \"2026-09-30T14:32:10+02:00\". No zone is refused."
                        },
                        "instrument": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "assetClass": {
                                  "type": "string",
                                  "const": "crypto",
                                  "description": "crypto."
                                },
                                "symbol": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 20,
                                  "description": "The coin’s symbol, such as \"BTC\"."
                                }
                              },
                              "required": [
                                "assetClass",
                                "symbol"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "assetClass": {
                                  "type": "string",
                                  "enum": [
                                    "stock",
                                    "etf"
                                  ],
                                  "description": "stock or etf."
                                },
                                "isin": {
                                  "type": "string",
                                  "pattern": "^[A-Z]{2}[A-Z0-9]{9}\\d$",
                                  "description": "ISIN, such as \"US0378331005\"."
                                },
                                "ticker": {
                                  "description": "The ticker on its venue.",
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 20
                                },
                                "mic": {
                                  "type": "string",
                                  "pattern": "^[A-Z0-9]{4}$",
                                  "description": "The venue’s MIC, ISO 10383, such as \"XNAS\" or \"XETR\"."
                                }
                              },
                              "required": [
                                "assetClass"
                              ],
                              "additionalProperties": false
                            }
                          ],
                          "description": "A share or a fund by its ISIN or its ticker and MIC; a coin by its symbol."
                        },
                        "note": {
                          "description": "Up to 500 characters, kept with the row.",
                          "type": "string",
                          "maxLength": 500
                        }
                      },
                      "required": [
                        "externalId",
                        "kind",
                        "amount",
                        "currency",
                        "occurredAt"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "cashFlows"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows new to Skarb."
                    },
                    "updated": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows sent before and changed since."
                    },
                    "unchanged": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "Rows sent before, the same."
                    },
                    "rejected": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "externalId": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string",
                            "enum": [
                              "instrument_unresolved",
                              "unsupported_crypto",
                              "limit_instruments"
                            ]
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "externalId",
                          "code",
                          "message"
                        ]
                      },
                      "description": "Rows of this batch turned away, and why."
                    },
                    "pending": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "externalId": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "instrument_unresolved",
                              "unsupported_crypto",
                              "limit_instruments"
                            ]
                          }
                        },
                        "required": [
                          "externalId",
                          "reason"
                        ]
                      },
                      "description": "Rows of this batch waiting for their instrument."
                    },
                    "connection": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "instruments": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "pendingTotal": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "id",
                        "instruments",
                        "pendingTotal"
                      ]
                    }
                  },
                  "required": [
                    "accepted",
                    "updated",
                    "unchanged",
                    "rejected",
                    "pending",
                    "connection"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `limit_connections`, `limit_history`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_in_progress`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`, `batch_too_large`, `idempotency_conflict`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{id}/rows": {
      "get": {
        "operationId": "getConnectionsByIdRows",
        "summary": "The rows a source sent, with their status: what waits for an instrument, what was refused",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "pending, resolved or rejected.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "resolved",
                "rejected"
              ]
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "trade or cash_flow.",
            "schema": {
              "type": "string",
              "enum": [
                "trade",
                "cash_flow"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows a page: 100 unless asked, 500 at most.",
            "schema": {
              "default": 100,
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` of the page before, as it was given.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Skarb’s id for the row."
                          },
                          "externalId": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "trade",
                              "cash_flow"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "resolved",
                              "rejected"
                            ]
                          },
                          "errorCode": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "instrument_unresolved",
                                  "unsupported_crypto",
                                  "limit_instruments"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "instrumentId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "payload": {
                            "description": "The row as it was sent; null once a resolved row is 400 days old — its hash stays, so the same row sent again is still unchanged."
                          },
                          "receivedAt": {
                            "type": "string"
                          },
                          "resolvedAt": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "externalId",
                          "kind",
                          "status",
                          "errorCode",
                          "instrumentId",
                          "payload",
                          "receivedAt",
                          "resolvedAt"
                        ]
                      }
                    },
                    "nextCursor": {
                      "description": "Pass as `cursor` for the next page; null on the last one.",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "rows",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{id}/rows/{externalId}": {
      "delete": {
        "operationId": "deleteConnectionsByIdRowsByExternalId",
        "summary": "Take out one row a source sent, and the trade or movement made of it",
        "tags": [
          "Ingest"
        ],
        "x-scope": "ingest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "externalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "trade or cash_flow.",
            "schema": {
              "default": "trade",
              "type": "string",
              "enum": [
                "trade",
                "cash_flow"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "deleted"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`connection_not_found`, `not_found`, `feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/portfolios": {
      "get": {
        "operationId": "getPortfolios",
        "summary": "Your portfolios and the accounts in each",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "portfolios": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "slot": {
                            "type": "string",
                            "enum": [
                              "main",
                              "secondary",
                              "third",
                              "p4",
                              "p5",
                              "p6",
                              "p7",
                              "p8",
                              "p9",
                              "p10",
                              "demo"
                            ]
                          },
                          "name": {
                            "description": "The person’s name for it; null is the default name.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "accounts": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "kind": {
                                  "type": "string",
                                  "description": "The connection’s kind (`ibkr`, `api`…), `manual` for trades by hand, `file` for an import."
                                },
                                "name": {
                                  "type": "string"
                                },
                                "portfolio": {
                                  "type": "string",
                                  "enum": [
                                    "main",
                                    "secondary",
                                    "third",
                                    "p4",
                                    "p5",
                                    "p6",
                                    "p7",
                                    "p8",
                                    "p9",
                                    "p10",
                                    "demo"
                                  ]
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "name",
                                "portfolio"
                              ]
                            }
                          }
                        },
                        "required": [
                          "slot",
                          "name",
                          "accounts"
                        ]
                      }
                    }
                  },
                  "required": [
                    "portfolios"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/portfolio": {
      "get": {
        "operationId": "getPortfolio",
        "summary": "The holdings with their value, weight and score, and the totals",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "slot",
            "in": "query",
            "required": false,
            "description": "`main`, `secondary`, `demo`, or `all` — the main and the secondary, as on the site. Without it, `all`; a token made for one portfolio reads that one, and no other.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "main",
                "secondary",
                "third",
                "p4",
                "p5",
                "p6",
                "p7",
                "p8",
                "p9",
                "p10",
                "demo"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "asOf": {
                      "type": "string",
                      "description": "When the answer was read, ISO 8601."
                    },
                    "slot": {
                      "type": "string",
                      "enum": [
                        "all",
                        "main",
                        "secondary",
                        "third",
                        "p4",
                        "p5",
                        "p6",
                        "p7",
                        "p8",
                        "p9",
                        "p10",
                        "demo"
                      ]
                    },
                    "baseCurrency": {
                      "type": "string",
                      "description": "What the money of the answer is in."
                    },
                    "totals": {
                      "type": "object",
                      "properties": {
                        "marketValue": {
                          "type": "string",
                          "description": "Holdings and cash."
                        },
                        "cost": {
                          "type": "string",
                          "description": "What the open lots cost; holdings without a cost are left out."
                        },
                        "unrealizedPnl": {
                          "anyOf": [
                            {
                              "type": "string",
                              "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "unrealizedPnlPct": {
                          "anyOf": [
                            {
                              "type": "string",
                              "description": "Per cent as a decimal string, such as \"12.5\" for 12.5%."
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "realizedPnl": {
                          "type": "string",
                          "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                        },
                        "cash": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "currency": {
                                "type": "string"
                              },
                              "amount": {
                                "type": "string",
                                "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                              },
                              "marketValue": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "In the base currency; null without a rate."
                              }
                            },
                            "required": [
                              "currency",
                              "amount",
                              "marketValue"
                            ]
                          }
                        }
                      },
                      "required": [
                        "marketValue",
                        "cost",
                        "unrealizedPnl",
                        "unrealizedPnlPct",
                        "realizedPnl",
                        "cash"
                      ]
                    },
                    "positions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "instrument": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Skarb’s id of the instrument."
                              },
                              "ticker": {
                                "type": "string",
                                "description": "The symbol with its exchange’s suffix, such as \"SHEL.L\"; a US listing has none."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "assetClass": {
                                "type": "string",
                                "enum": [
                                  "stock",
                                  "etf",
                                  "crypto",
                                  "bond"
                                ]
                              },
                              "currency": {
                                "type": "string",
                                "description": "What the instrument is quoted in."
                              },
                              "sector": {
                                "description": "The GICS sector where Skarb knows it.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "holdingClass": {
                                "type": "string",
                                "description": "`stock`, `etf`, `reit`, `crypto` or `stablecoin`."
                              }
                            },
                            "required": [
                              "id",
                              "ticker",
                              "name",
                              "assetClass",
                              "currency",
                              "sector",
                              "holdingClass"
                            ]
                          },
                          "quantity": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          },
                          "avgCost": {
                            "anyOf": [
                              {
                                "type": "string",
                                "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Per unit, in the currency of the trades; null for a balance with no cost."
                          },
                          "lastPrice": {
                            "anyOf": [
                              {
                                "type": "string",
                                "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The price the holding is valued at — only ever of a holding."
                          },
                          "marketValue": {
                            "anyOf": [
                              {
                                "type": "string",
                                "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "weight": {
                            "anyOf": [
                              {
                                "type": "string",
                                "description": "Per cent as a decimal string, such as \"12.5\" for 12.5%."
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Share of `totals.marketValue`."
                          },
                          "unrealizedPnl": {
                            "anyOf": [
                              {
                                "type": "string",
                                "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "unrealizedPnlPct": {
                            "anyOf": [
                              {
                                "type": "string",
                                "description": "Per cent as a decimal string, such as \"12.5\" for 12.5%."
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "score": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "quality": {
                                    "description": "Quality 0–100.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "signal": {
                                    "anyOf": [
                                      {
                                        "type": "integer",
                                        "minimum": -2,
                                        "maximum": 2
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "From −2 to +2; null below the confidence floor."
                                  },
                                  "confidence": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ]
                                  },
                                  "asOf": {
                                    "type": "string",
                                    "format": "date",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
                                    "description": "A day, such as \"2026-10-07\", Kyiv time."
                                  }
                                },
                                "required": [
                                  "quality",
                                  "signal",
                                  "confidence",
                                  "asOf"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Skarb’s score of the holding; null for one never scored."
                          }
                        },
                        "required": [
                          "instrument",
                          "quantity",
                          "avgCost",
                          "lastPrice",
                          "marketValue",
                          "weight",
                          "unrealizedPnl",
                          "unrealizedPnlPct",
                          "score"
                        ]
                      }
                    }
                  },
                  "required": [
                    "asOf",
                    "slot",
                    "baseCurrency",
                    "totals",
                    "positions"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/portfolio/allocation": {
      "get": {
        "operationId": "getPortfolioAllocation",
        "summary": "The portfolio by class, sector and currency",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "slot",
            "in": "query",
            "required": false,
            "description": "`main`, `secondary`, `demo`, or `all` — the main and the secondary, as on the site. Without it, `all`; a token made for one portfolio reads that one, and no other.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "main",
                "secondary",
                "third",
                "p4",
                "p5",
                "p6",
                "p7",
                "p8",
                "p9",
                "p10",
                "demo"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "slot": {
                      "type": "string",
                      "enum": [
                        "all",
                        "main",
                        "secondary",
                        "third",
                        "p4",
                        "p5",
                        "p6",
                        "p7",
                        "p8",
                        "p9",
                        "p10",
                        "demo"
                      ]
                    },
                    "baseCurrency": {
                      "type": "string"
                    },
                    "classes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string",
                            "description": "The key in words, in the person’s language."
                          },
                          "weight": {
                            "type": "string",
                            "description": "Per cent as a decimal string, such as \"12.5\" for 12.5%."
                          },
                          "marketValue": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          }
                        },
                        "required": [
                          "key",
                          "label",
                          "weight",
                          "marketValue"
                        ]
                      }
                    },
                    "sectors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string",
                            "description": "The key in words, in the person’s language."
                          },
                          "weight": {
                            "type": "string",
                            "description": "Per cent as a decimal string, such as \"12.5\" for 12.5%."
                          },
                          "marketValue": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          }
                        },
                        "required": [
                          "key",
                          "label",
                          "weight",
                          "marketValue"
                        ]
                      }
                    },
                    "currencies": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string",
                            "description": "The key in words, in the person’s language."
                          },
                          "weight": {
                            "type": "string",
                            "description": "Per cent as a decimal string, such as \"12.5\" for 12.5%."
                          },
                          "marketValue": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          }
                        },
                        "required": [
                          "key",
                          "label",
                          "weight",
                          "marketValue"
                        ]
                      }
                    }
                  },
                  "required": [
                    "slot",
                    "baseCurrency",
                    "classes",
                    "sectors",
                    "currencies"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/portfolio/health": {
      "get": {
        "operationId": "getPortfolioHealth",
        "summary": "The portfolio’s health and its checks",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "slot",
            "in": "query",
            "required": false,
            "description": "`main`, `secondary`, `demo`, or `all` — the main and the secondary, as on the site. Without it, `all`; a token made for one portfolio reads that one, and no other.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "main",
                "secondary",
                "third",
                "p4",
                "p5",
                "p6",
                "p7",
                "p8",
                "p9",
                "p10",
                "demo"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "slot": {
                      "type": "string",
                      "enum": [
                        "all",
                        "main",
                        "secondary",
                        "third",
                        "p4",
                        "p5",
                        "p6",
                        "p7",
                        "p8",
                        "p9",
                        "p10",
                        "demo"
                      ]
                    },
                    "score": {
                      "description": "The portfolio’s health 0–100; null with nothing to score.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "asOf": {
                      "type": "string"
                    },
                    "checks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "high",
                              "medium",
                              "low",
                              "accepted"
                            ],
                            "description": "How bad an open warning is; `accepted` for one the person accepted."
                          },
                          "text": {
                            "type": "string",
                            "description": "The check in words, in the person’s language, as the site says it."
                          },
                          "values": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            },
                            "description": "The numbers the text is written with, for a program to read."
                          }
                        },
                        "required": [
                          "code",
                          "status",
                          "text",
                          "values"
                        ]
                      }
                    }
                  },
                  "required": [
                    "slot",
                    "score",
                    "asOf",
                    "checks"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/portfolio/trades": {
      "get": {
        "operationId": "getPortfolioTrades",
        "summary": "Every trade of the portfolio, newest first: the brokers’, files’, scripts’ and by hand, and the exchanges’ spot in dollars",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "slot",
            "in": "query",
            "required": false,
            "description": "`main`, `secondary`, `demo`, or `all` — the main and the secondary, as on the site. Without it, `all`; a token made for one portfolio reads that one, and no other.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "main",
                "secondary",
                "third",
                "p4",
                "p5",
                "p6",
                "p7",
                "p8",
                "p9",
                "p10",
                "demo"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows a page: 100 unless asked, 500 at most.",
            "schema": {
              "default": 100,
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` of the page before, as it was given.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "From this day on, Kyiv time.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Up to this day, Kyiv time, inclusive.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "trades": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "externalId": {
                            "description": "Your own id, for a trade your source sent.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "source": {
                            "type": "string",
                            "description": "The connection’s kind, or `manual` and `file`."
                          },
                          "account": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "name"
                            ]
                          },
                          "instrument": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Skarb’s id of the instrument."
                              },
                              "ticker": {
                                "type": "string",
                                "description": "The symbol with its exchange’s suffix, such as \"SHEL.L\"; a US listing has none."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "assetClass": {
                                "type": "string",
                                "enum": [
                                  "stock",
                                  "etf",
                                  "crypto",
                                  "bond"
                                ]
                              },
                              "currency": {
                                "type": "string",
                                "description": "What the instrument is quoted in."
                              },
                              "sector": {
                                "description": "The GICS sector where Skarb knows it.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "ticker",
                              "name",
                              "assetClass",
                              "currency",
                              "sector"
                            ]
                          },
                          "side": {
                            "type": "string",
                            "enum": [
                              "buy",
                              "sell"
                            ]
                          },
                          "quantity": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          },
                          "price": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          },
                          "currency": {
                            "type": "string"
                          },
                          "fee": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          },
                          "executedAt": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "externalId",
                          "source",
                          "account",
                          "instrument",
                          "side",
                          "quantity",
                          "price",
                          "currency",
                          "fee",
                          "executedAt"
                        ]
                      }
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "type": "string",
                          "description": "The `nextCursor` of the page before, as it was given."
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "trades",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/portfolio/cash-flows": {
      "get": {
        "operationId": "getPortfolioCashFlows",
        "summary": "Every movement of money of the portfolio, newest first",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "slot",
            "in": "query",
            "required": false,
            "description": "`main`, `secondary`, `demo`, or `all` — the main and the secondary, as on the site. Without it, `all`; a token made for one portfolio reads that one, and no other.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "main",
                "secondary",
                "third",
                "p4",
                "p5",
                "p6",
                "p7",
                "p8",
                "p9",
                "p10",
                "demo"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows a page: 100 unless asked, 500 at most.",
            "schema": {
              "default": 100,
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` of the page before, as it was given.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "From this day on, Kyiv time.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Up to this day, Kyiv time, inclusive.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "cashFlows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "externalId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "source": {
                            "type": "string"
                          },
                          "account": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "name"
                            ]
                          },
                          "instrument": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "description": "Skarb’s id of the instrument."
                                  },
                                  "ticker": {
                                    "type": "string",
                                    "description": "The symbol with its exchange’s suffix, such as \"SHEL.L\"; a US listing has none."
                                  },
                                  "name": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "assetClass": {
                                    "type": "string",
                                    "enum": [
                                      "stock",
                                      "etf",
                                      "crypto",
                                      "bond"
                                    ]
                                  },
                                  "currency": {
                                    "type": "string",
                                    "description": "What the instrument is quoted in."
                                  },
                                  "sector": {
                                    "description": "The GICS sector where Skarb knows it.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "id",
                                  "ticker",
                                  "name",
                                  "assetClass",
                                  "currency",
                                  "sector"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The holding a dividend came from."
                          },
                          "kind": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "string",
                            "description": "Money into the account above zero, out of it below."
                          },
                          "currency": {
                            "type": "string"
                          },
                          "executedAt": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "externalId",
                          "source",
                          "account",
                          "instrument",
                          "kind",
                          "amount",
                          "currency",
                          "executedAt"
                        ]
                      }
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "type": "string",
                          "description": "The `nextCursor` of the page before, as it was given."
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "cashFlows",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scores": {
      "get": {
        "operationId": "getScores",
        "summary": "Skarb’s score of up to twenty tickers; what you hold or watch is free",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "symbols",
            "in": "query",
            "required": true,
            "description": "Tickers by comma, 20 at most, such as \"AAPL,MSFT,BTC\".",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scores": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "symbol": {
                                "type": "string"
                              },
                              "quality": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "signal": {
                                "anyOf": [
                                  {
                                    "type": "integer",
                                    "minimum": -2,
                                    "maximum": 2
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "signalLabel": {
                                "description": "The signal in words, in the person’s language.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "confidence": {
                                "type": "string",
                                "enum": [
                                  "low",
                                  "medium",
                                  "high"
                                ]
                              },
                              "explanation": {
                                "type": "object",
                                "properties": {
                                  "pros": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "factor": {
                                          "type": "string"
                                        },
                                        "label": {
                                          "type": "string",
                                          "description": "The factor in words, in the person’s language."
                                        },
                                        "value": {
                                          "description": "Its value as shown, unit and all; null where it is kept back.",
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "reference": {
                                          "description": "What it is measured against: the sector’s median, or a scale.",
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "factor",
                                        "label",
                                        "value",
                                        "reference"
                                      ]
                                    }
                                  },
                                  "cons": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "factor": {
                                          "type": "string"
                                        },
                                        "label": {
                                          "type": "string",
                                          "description": "The factor in words, in the person’s language."
                                        },
                                        "value": {
                                          "description": "Its value as shown, unit and all; null where it is kept back.",
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "reference": {
                                          "description": "What it is measured against: the sector’s median, or a scale.",
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "factor",
                                        "label",
                                        "value",
                                        "reference"
                                      ]
                                    }
                                  }
                                },
                                "required": [
                                  "pros",
                                  "cons"
                                ]
                              },
                              "asOf": {
                                "type": "string",
                                "format": "date",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
                                "description": "A day, such as \"2026-10-07\", Kyiv time."
                              }
                            },
                            "required": [
                              "symbol",
                              "quality",
                              "signal",
                              "signalLabel",
                              "confidence",
                              "explanation",
                              "asOf"
                            ]
                          },
                          {
                            "type": "object",
                            "properties": {
                              "symbol": {
                                "type": "string"
                              },
                              "error": {
                                "type": "string",
                                "enum": [
                                  "quota_exceeded",
                                  "not_found",
                                  "not_scored"
                                ],
                                "description": "`quota_exceeded` — no asset scores left today; `not_found`; `not_scored` — outside what Skarb scores."
                              }
                            },
                            "required": [
                              "symbol",
                              "error"
                            ]
                          }
                        ]
                      }
                    }
                  },
                  "required": [
                    "scores"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`validation_failed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/alerts": {
      "get": {
        "operationId": "getAlerts",
        "summary": "Your price alerts",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "alerts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "instrument": {
                            "type": "object",
                            "properties": {
                              "ticker": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "ticker"
                            ]
                          },
                          "condition": {
                            "type": "string",
                            "enum": [
                              "cross",
                              "up",
                              "down"
                            ]
                          },
                          "repeat": {
                            "type": "string",
                            "enum": [
                              "once",
                              "every"
                            ]
                          },
                          "value": {
                            "type": "string",
                            "description": "A decimal as a string, signed where it may be, such as \"-12.50\". Never a number."
                          },
                          "currency": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "live",
                              "paused",
                              "fired",
                              "expired",
                              "over_limit"
                            ]
                          },
                          "createdAt": {
                            "type": "string"
                          },
                          "firedAt": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "instrument",
                          "condition",
                          "repeat",
                          "value",
                          "currency",
                          "status",
                          "createdAt",
                          "firedAt"
                        ]
                      }
                    }
                  },
                  "required": [
                    "alerts"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/diary": {
      "get": {
        "operationId": "getDiary",
        "summary": "Your diary, newest first",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` of the page before, as it was given.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "instrument": {
                            "type": "object",
                            "properties": {
                              "ticker": {
                                "type": "string"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "ticker",
                              "name"
                            ]
                          },
                          "stance": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          },
                          "link": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "string"
                          },
                          "reminders": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "earnings",
                                    "date",
                                    "price"
                                  ]
                                },
                                "status": {
                                  "type": "string"
                                },
                                "date": {
                                  "description": "The day of a dated reminder, or the report’s once known.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "movePct": {
                                  "anyOf": [
                                    {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "The move a price reminder waits for, per cent."
                                },
                                "firedAt": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                }
                              },
                              "required": [
                                "kind",
                                "status",
                                "date",
                                "movePct",
                                "firedAt"
                              ]
                            }
                          }
                        },
                        "required": [
                          "id",
                          "instrument",
                          "stance",
                          "text",
                          "link",
                          "createdAt",
                          "reminders"
                        ]
                      }
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "type": "string",
                          "description": "The `nextCursor` of the page before, as it was given."
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "entries",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/macro": {
      "get": {
        "operationId": "getMacro",
        "summary": "The phase of the economic cycle and what the central banks are doing",
        "tags": [
          "Read"
        ],
        "x-scope": "read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "phase": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "early",
                            "mid",
                            "late",
                            "recession"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The cycle’s phase; null before the first run."
                    },
                    "phaseLabel": {
                      "description": "The phase in words, in the person’s language.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "asOf": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "liquidityZone": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "shrinking",
                            "flat",
                            "printing"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What the central banks’ sum did over three months."
                    }
                  },
                  "required": [
                    "phase",
                    "phaseLabel",
                    "asOf",
                    "liquidityZone"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`, `token_expired`, `token_revoked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`forbidden_scope`, `forbidden_plan`, `ip_not_allowed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`feature_disabled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`, `quota_exceeded`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "skb_ and 48 letters and digits",
        "description": "A token made in the settings, sent as Authorization: Bearer skb_…"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "bad_request",
                  "unauthorized",
                  "token_expired",
                  "token_revoked",
                  "forbidden_scope",
                  "forbidden_plan",
                  "ip_not_allowed",
                  "terms_not_accepted",
                  "limit_connections",
                  "limit_history",
                  "not_found",
                  "connection_not_found",
                  "feature_disabled",
                  "method_not_allowed",
                  "idempotency_in_progress",
                  "payload_too_large",
                  "validation_failed",
                  "batch_too_large",
                  "idempotency_conflict",
                  "confirm_required",
                  "rate_limited",
                  "quota_exceeded",
                  "internal"
                ],
                "description": "What happened, for a program to branch on."
              },
              "message": {
                "type": "string",
                "description": "The same in words, for a person. Not a contract."
              },
              "details": {
                "description": "The fields that were wrong, on `validation_failed`.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string",
                      "description": "Where in the request, such as \"trades[3].quantity\"."
                    },
                    "issue": {
                      "type": "string",
                      "description": "What is wrong with it."
                    }
                  },
                  "required": [
                    "path",
                    "issue"
                  ]
                }
              },
              "requestId": {
                "description": "The `X-Request-Id` of the request, on `internal`: quote it when writing in.",
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
