Cymetica Event Cards API

The event-cards API from Cymetica — 11 operation(s) for event-cards.

Operations 11

POST /api/v1/event-cards/backtest-idea Backtest Event Card Idea #
POST /api/v1/event-cards/{card_id}/paper-trade Paper Trade Event Card Basket #
POST /api/v1/event-cards/{card_id}/historical-analogs Historical Analogs #
GET /api/v1/event-cards List Event Cards #
GET /api/v1/event-cards/positions My Positions #
GET /api/v1/event-cards/symbols/search Search Symbols #
GET /api/v1/event-cards/{card_id} Get Event Card #
GET /api/v1/event-cards/{card_id}/index-history Index History #
POST /api/v1/event-cards/{card_id}/buy Buy Event Card #
POST /api/v1/event-cards/{card_id}/sell Sell Event Card #
POST /api/v1/event-cards/{card_id}/short Short Event Card #

Documentation

Specifications

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/cymetica-com:cymetica-com-event-cards-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

cymetica-com-event-cards-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: EventTrader Public Event Cards API
  version: 1.0.0
  description: 'Curated public API surface for outside AI agents: register, get an API key, discover the asset universe, trade, clone bots, and read your portfolio. Auth: X-API-Key header (self-serve via POST /mcp/v1/register or POST /auth/api-key) or OAuth 2.0 bearer with read/portfolio/trade scopes. Start at https://cymetica.com/build and https://cymetica.com/llms.txt.'
servers:
- url: https://cymetica.com
security:
- ApiKeyAuth: []
- OAuth2: []
tags:
- name: event-cards
paths:
  /api/v1/event-cards/backtest-idea:
    post:
      tags:
      - event-cards
      summary: Backtest Event Card Idea
      description: 'Historical what-if backtest of an ad-hoc basket idea.


        Read-only: no card is created, no ledger or on-chain writes, no money

        moves. Reuses the same engine (run_basket_backtest) as the saved-card

        backtest, so an idea and a published card with the same basket return

        identical numbers.


        Two distinct exclusion lists in the response:

        * ``unresolved_symbols`` — constituents we couldn''t map to a price

        source at all (bad/unknown ticker, or a crypto leg with no

        coingecko_id we could resolve).

        * ``dropped_symbols`` — resolved to a price source fine, but had no

        price history in the requested window (newly listed, etc.); weights

        renormalized over the rest.


        ``requested_weight_covered`` (0..1) is ALWAYS in the response — the

        fraction of the basket''s requested weight that actually priced. If it

        falls below 80% the endpoint returns 422 INSUFFICIENT_BASKET_COVERAGE

        instead of a headline return that would describe a different

        (substitute) basket than the one requested (ET-25808 — a published

        8-leg basket that lost 6 legs to unresolved/no-data equities

        previously renormalized onto the 2 survivors and returned a -85%

        "card result" that was really a 98.5%-weighted single equity leg).'
      operationId: backtest_event_card_idea_api_v1_event_cards_backtest_idea_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BacktestIdeaRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  card_id:
                    type:
                    - string
                    - 'null'
                  period_days:
                    type: integer
                  starting_capital_usdc:
                    type: number
                  ending_capital_usdc:
                    type: number
                  total_return_pct:
                    type: number
                  sharpe_ratio:
                    type:
                    - number
                    - 'null'
                  max_drawdown_pct:
                    type:
                    - number
                    - 'null'
                  equity_curve:
                    type: array
                    items:
                      type: object
                      additionalProperties:
                        type: number
                  basket:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
                  dropped_symbols:
                    type: array
                    items:
                      type: string
                  unresolved_symbols:
                    type: array
                    items:
                      type: string
                  n_points:
                    type: integer
                  started_at:
                    type: string
                  ended_at:
                    type: string
                additionalProperties: true
                required:
                - period_days
                - starting_capital_usdc
                - ending_capital_usdc
                - total_return_pct
                description: Historical buy-and-hold backtest of a basket idea (BacktestResult.as_dict).
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security: []
  /api/v1/event-cards/{card_id}/paper-trade:
    post:
      tags:
      - event-cards
      summary: Paper Trade Event Card Basket
      description: 'Paper-trade a card''s whole basket: split the notional across its legs by

        weight and open SIMULATED positions at live spot, in a per-card paper book

        (``ec:``).


        The bridge from "backtest an idea" to "watch it run" — no real funds move,

        nothing is withdrawable (the same catalog paper rail as the Asset Universe

        page). Read the result back any time via

        ``GET /api/v1/universe/paper/portfolio?book=ec:``.'
      operationId: paper_trade_event_card_basket_api_v1_event_cards__card_id__paper_trade_post
      security:
      - BearerJWT: []
      - ApiKeyAuth: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          title: Card Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaperTradeBasketRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards/{card_id}/historical-analogs:
    post:
      tags:
      - event-cards
      summary: Historical Analogs
      description: 'How did events LIKE this one perform historically?


        Finds up to ``limit`` real PAST events similar to this card (same sector +

        sentiment sign, ranked by asset-profile overlap), builds each one''s basket

        index over the ``window_days`` FOLLOWING its event date, and returns every

        series (re-keyed by day-offset for overlay) plus the distribution of forward

        returns. Read-only: no money, no card creation. Grounded in the real

        headline corpus — a thin corpus returns fewer than ``limit`` (the real

        count), never a fabricated event.'
      operationId: historical_analogs_api_v1_event_cards__card_id__historical_analogs_post
      security: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          title: Card Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HistoricalAnalogsRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards:
    get:
      tags:
      - event-cards
      summary: List Event Cards
      description: 'List Event Cards (defaults to live cards), newest first.


        ``origin=''aib_rally''`` (the Rally Cards deck) is ordered by SPIKE SIZE

        instead — biggest measured move at the top, either direction — with

        newest-first as the tiebreak for cards that predate the measurement.


        User-submitted cards are filtered out by default; toggle

        ``include_user_submitted=true`` to see the full firehose.


        Pagination: ``offset``/``skip``/``page`` all move the window (ET-24574

        — offset was previously accepted but silently ignored, stranding any

        card past the first page of the default feed, e.g. an older

        user-submitted card unreachable at any offset). ``total`` in the

        response is the true row count under the active filter; ``count``

        stays the number of rows in THIS page (unchanged key, for backward

        compatibility). ``q``/``search``/``symbol`` filter the same feed.'
      operationId: list_event_cards_api_v1_event_cards_get
      security: []
      parameters:
      - name: status
        in: query
        required: false
        schema:
          type: string
          default: live
          title: Status
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
          description: 'Row offset for pagination (0-based). Alias: skip.'
          default: 0
          title: Offset
        description: 'Row offset for pagination (0-based). Alias: skip.'
      - name: skip
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            minimum: 0
          - type: 'null'
          description: Alias for offset.
          title: Skip
        description: Alias for offset.
      - name: page
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            minimum: 1
          - type: 'null'
          description: 1-based page number; offset = (page-1)*limit. Takes precedence over offset/skip when given.
          title: Page
        description: 1-based page number; offset = (page-1)*limit. Takes precedence over offset/skip when given.
      - name: q
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Case-insensitive substring match on card title or tradable symbol (EVCDX-*/AIB-*). Alias: search.'
          title: Q
        description: 'Case-insensitive substring match on card title or tradable symbol (EVCDX-*/AIB-*). Alias: search.'
      - name: search
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Alias for q.
          title: Search
        description: Alias for q.
      - name: symbol
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Exact (case-insensitive) match on the card's tradable symbol (EVCDX-*/AIB-*).
          title: Symbol
        description: Exact (case-insensitive) match on the card's tradable symbol (EVCDX-*/AIB-*).
      - name: origin
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Filter to a single card origin (e.g. 'aib_rally' for the Rally Cards deck). Omitted → the full curated feed.
          title: Origin
        description: Filter to a single card origin (e.g. 'aib_rally' for the Rally Cards deck). Omitted → the full curated feed.
      - name: include_user_submitted
        in: query
        required: false
        schema:
          type: boolean
          description: If true, include user-submitted cards in the result. Default is false so the curated system feed stays clean — user-submitted cards are reachable via the user's own /positions or by passing this flag explicitly.
          default: false
          title: Include User Submitted
        description: If true, include user-submitted cards in the result. Default is false so the curated system feed stays clean — user-submitted cards are reachable via the user's own /positions or by passing this flag explicitly.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards/positions:
    get:
      tags:
      - event-cards
      summary: My Positions
      description: 'The authenticated user''s Event Card positions with live valuation.


        Surfaces BOTH spot positions (event_card_positions: bull/bear) AND

        leveraged perp positions (evcdx_perp_positions: long/short). The

        perp short path was previously invisible on /positions — CentCom

        #5970 (expire76): "shorted event card doesn''t appear in positions".'
      operationId: my_positions_api_v1_event_cards_positions_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
      security:
      - BearerJWT: []
      - ApiKeyAuth: []
  /api/v1/event-cards/symbols/search:
    get:
      tags:
      - event-cards
      summary: Search Symbols
      description: 'Search tradable symbols for basket customization across the FULL global

        trading-vehicle catalog (stocks, ETFs, ADRs, REITs, crypto, …), optionally

        filtered to one asset type (``asset_type`` = an ``ontology_class`` such as

        ''etf'', ''common-stock'', ''crypto-assets'', ''leveraged-etf'', ''reit''). Crypto rows

        keep their CoinGecko price/image; non-crypto rows come from the ontology and

        are priced live by the builder''s preview-basket step. Only PRICEABLE vehicles

        are returned (a vehicle explicitly flagged extra.priceable=false — no live

        quote — is excluded so a card can never contain an unquotable leg).'
      operationId: search_symbols_api_v1_event_cards_symbols_search_get
      parameters:
      - name: q
        in: query
        required: false
        schema:
          type: string
          maxLength: 30
          default: ''
          title: Q
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 50
          minimum: 1
          default: 20
          title: Limit
      - name: asset_type
        in: query
        required: false
        schema:
          type: string
          maxLength: 40
          default: ''
          title: Asset Type
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security: []
  /api/v1/event-cards/{card_id}:
    get:
      tags:
      - event-cards
      summary: Get Event Card
      description: Full detail for one Event Card.
      operationId: get_event_card_api_v1_event_cards__card_id__get
      security: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Card Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards/{card_id}/index-history:
    get:
      tags:
      - event-cards
      summary: Index History
      description: 'Event Index price series for the card over 1d / 5d / 30d / all.


        ``all`` = since inception: anchored to the card''s creation time so the

        landing chart matches the AIB fund tiles on /fund-performance, which plot

        their full history rather than a rolling window.


        Downsampled server-side to ≤300 points so the response stays

        sparkline-sized regardless of how fast the pricer ticks.'
      operationId: index_history_api_v1_event_cards__card_id__index_history_get
      security: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          title: Card Id
      - name: interval
        in: query
        required: false
        schema:
          type: string
          default: 5d
          title: Interval
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards/{card_id}/buy:
    post:
      tags:
      - event-cards
      summary: Buy Event Card
      description: 'Open (or add to) a bull position on an Event Card.


        A Trend Card / custom-basket card (backed by a tokenized AIB) routes the buy

        to AIB SHARE ISSUANCE (mint at NAV+spread) instead of per-leg basket

        execution. Ordinary Event Cards keep the bull-position path below.


        Paper mode resolution order:

        1. ``body.paper`` (explicit per-trade override)

        2. ``user.simulation_mode`` (per-user setting)

        3. ``EVENT_CARDS_TRADING_ENABLED`` env (platform-wide gate)'
      operationId: buy_event_card_api_v1_event_cards__card_id__buy_post
      security:
      - BearerJWT: []
      - ApiKeyAuth: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          title: Card Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BuyRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards/{card_id}/sell:
    post:
      tags:
      - event-cards
      summary: Sell Event Card
      description: 'Close (or partially close) a spot position (bull OR bear) on an Event Card.


        Note: close-side paper/live mode is derived from the position''s stored

        is_paper flag (set at open time) — body.paper is accepted for

        forward-compat but ignored. The mode of a close MUST match the open

        to avoid mixed accounting.


        Dispatches by the position''s stored side: the frontend Close button sends

        every SPOT position here, but bear rows previously dead-ended on

        close_bull_position''s "Not a bull position" guard — a user could hold a

        short (bot/NEXUS-opened) they could never exit from the UI (2026-08-04).

        Bear closes are full-position only (the service has no partial bear close),

        so a fraction < 1 on a bear is rejected rather than silently over-closing.'
      operationId: sell_event_card_api_v1_event_cards__card_id__sell_post
      security:
      - BearerJWT: []
      - ApiKeyAuth: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          title: Card Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SellRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/event-cards/{card_id}/short:
    post:
      tags:
      - event-cards
      summary: Short Event Card
      description: 'Open a perpetual position (long or short) on an Event Card index.


        Cash-settled perp contract. Platform is the counterparty.

        Funding rate anchors perp price to NAV (1h cycle).'
      operationId: short_event_card_api_v1_event_cards__card_id__short_post
      security:
      - BearerJWT: []
      - ApiKeyAuth: []
      parameters:
      - name: card_id
        in: path
        required: true
        schema:
          type: string
          title: Card Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShortRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    PaperTradeBasketRequest:
      properties:
        usd_notional:
          type: number
          maximum: 1000000.0
          exclusiveMinimum: 0.0
          title: Usd Notional
          default: 1000.0
        side:
          type: string
          title: Side
          default: buy
      type: object
      title: PaperTradeBasketRequest
      description: 'Paper-trade a saved card''s whole basket — open SIMULATED positions in the

        card''s constituents, weighted, at live spot. No real money moves.'
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    HistoricalAnalogsRequest:
      properties:
        window_days:
          type: integer
          title: Window Days
          default: 30
        limit:
          type: integer
          maximum: 20.0
          minimum: 1.0
          title: Limit
          default: 10
      type: object
      title: HistoricalAnalogsRequest
      description: 'Backtest how similar PAST events performed over the window FOLLOWING each

        event — read-only, no money, no card creation.'
    BacktestIdeaRequest:
      properties:
        constituents:
          items:
            $ref: '#/components/schemas/IdeaConstituent'
          type: array
          maxItems: 20
          minItems: 1
          title: Constituents
        period_days:
          type: integer
          title: Period Days
          default: 30
        starting_capital:
          type: number
          maximum: 1000000.0
          exclusiveMinimum: 0.0
          title: Starting Capital
          default: 1000.0
        fee_rate:
          type: number
          maximum: 0.1
          minimum: 0.0
          title: Fee Rate
          default: 0.0
        slippage_bps:
          type: number
          maximum: 500.0
          minimum: 0.0
          title: Slippage Bps
          default: 0.0
      type: object
      required:
      - constituents
      title: BacktestIdeaRequest
      description: 'Backtest an arbitrary basket the user defines — an ''event card idea'' —

        without creating a card or moving any money.'
    SellRequest:
      properties:
        position_id:
          type: string
          title: Position Id
        fraction:
          type: number
          maximum: 1.0
          exclusiveMinimum: 0.0
          title: Fraction
          default: 1.0
        paper:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Paper
          description: Per-trade paper override; see BuyRequest.paper
      type: object
      required:
      - position_id
      title: SellRequest
    BuyRequest:
      properties:
        amount_usdc:
          type: number
          exclusiveMinimum: 0.0
          title: Amount Usdc
          description: USDC notional to go bull with
        paper:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Paper
          description: Paper-trading override. True → paper (no real USDC moves, synthetic fills at registry price, position.is_paper=True). False → live (requires platform-wide live gate). None (default) → use user.simulation_mode if set, otherwise fall through to the platform-wide EVENT_CARDS_TRADING_ENABLED gate (currently paper-mode by default).
        asset_class:
          anyOf:
          - type: string
          - type: 'null'
          title: Asset Class
          description: 'Active sub-basket: ''crypto'' or ''stock''. None = whole basket. Stock legs are paper-only unless the user has a verified live stock broker connected (then they route to that broker).'
      type: object
      required:
      - amount_usdc
      title: BuyRequest
    IdeaConstituent:
      properties:
        symbol:
          type: string
          maxLength: 32
          minLength: 1
          title: Symbol
        coingecko_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Coingecko Id
          description: CoinGecko id keyed into historical_prices, for a CRYPTO leg. If omitted we best-effort resolve it from the symbol; unresolvable symbols are returned in unresolved_symbols and excluded.
        asset_type:
          anyOf:
          - type: string
          - type: 'null'
          title: Asset Type
          description: '''stock'' or ''crypto''. Tells the resolver which price table and catalog to use, and prevents a ticker that exists as BOTH an equity and a crypto token (e.g. REAL = The RealReal Inc. stock, also the symbol of an unrelated ''RealLink'' crypto token) from being resolved to the wrong instrument. If omitted, we best-effort detect it from event_card_assets / the catalogs; pass it explicitly whenever the symbol is a known collision.'
        weight:
          type: number
          minimum: 0.0
          title: Weight
          description: Relative basket weight (renormalized). 0 is accepted and excluded.
      type: object
      required:
      - symbol
      - weight
      title: IdeaConstituent
      description: One leg of an ad-hoc basket idea.
    ShortRequest:
      properties:
        margin_usdc:
          type: number
          exclusiveMinimum: 0.0
          title: Margin Usdc
          description: USDC margin for the perp position
        leverage:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Leverage
          description: Leverage (1-10x)
          default: 1
        side:
          type: string
          title: Side
          description: '''long'' or ''short'''
          default: short
        paper:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Paper
          description: 'Per-trade paper control. On the spot-bear path (cards whose short_execution is ''spot_bear'', or execution=''broker'') it is honoured exactly like BuyRequest.paper (omitted → inherits the account''s simulation_mode). On the perp path (short_execution ''perp'') there is NO paper book: paper=true is REFUSED with 400 PERP_NO_PAPER_BOOK, and an account in simulation_mode that omits it is refused with 400 ACCOUNT_IN_PAPER_MODE — a paper request is never downgraded to a real-ledger position. Send paper=false to open a real perp on purpose. Read short_execution / perp_symbol on GET /api/v1/event-cards/{id} to know which path a card takes before sending.'
        execution:
          type: string
          title: Execution
          description: '''auto'' (default): perp when the card has an EVCDX token, spot bear otherwise. ''broker'': force the spot-bear path, which SELLS SHORT the card''s equity legs in your OWN connected brokerage account (requires a verified live stock-broker connection, an all-stock basket, and open US markets).'
          default: auto
      type: object
      required:
      - margin_usdc
      title: ShortRequest
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    BearerJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Account session JWT (from /auth/login). Key-management routes accept only this — never an API key.
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://cymetica.com/oauth/authorize
          tokenUrl: https://cymetica.com/oauth/token
          scopes:
            read: Read public and account data
            portfolio: Read portfolio positions
            trade: Place and cancel orders