openapi: 3.1.0
info:
  title: Kyo Cross Chain API
  version: 1.0.0
  summary: Public API for Kyo Cross Chain integrations.
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
  description: |
    Public integration contract for requesting Kyo Cross Chain quotes, executing the
    returned user transactions, and polling lifecycle status.

    ## API keys

    Public endpoints accept an optional API key in the HTTP bearer header:

    ```http
    Authorization: Bearer <apiKey>
    ```

    Calls without an API key are supported. Partners with an API key can
    receive higher RPS limits (up to 10x) and revshare.

    Visit [portal.kyo.ag](https://portal.kyo.ag) to generate your API key.

    In Scalar, use the **Authorize** panel for the `publicApiKey` security
    scheme and enter the API key value.
servers:
  - url: "{apiBaseUrl}"
    description: API base URL
    variables:
      apiBaseUrl:
        default: https://cross-chain-api.kyo.ag
        description: Replace with the API base URL supplied by Kyo.
x-scalar-environments:
  production:
    description: Production API
    variables:
      apiBaseUrl:
        description: Production API base URL
        default: https://cross-chain-api.kyo.ag
  partner:
    description: Partner environment
    variables:
      apiBaseUrl:
        description: API base URL supplied by Kyo
        default: https://api.example.com
x-scalar-active-environment: production
tags:
  - name: Discovery
    description: Discover supported chains and currencies.
  - name: Quote
    description: Request an executable quote.
  - name: Status
    description: Poll request lifecycle status.
x-tagGroups:
  - name: Kyo Cross Chain
    tags:
      - Discovery
      - Quote
      - Status
paths:
  /v1/chains:
    get:
      tags:
        - Discovery
      operationId: listChains
      summary: List supported chains
      description: Returns the chains currently exposed by the API.
      security:
        - publicApiKey: []
        - {}
      responses:
        "200":
          description: Supported chains.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Chain"
              examples:
                chains:
                  value:
                    - chainId: 1
                      name: Ethereum
                    - chainId: 8453
                      name: Base
        "401":
          $ref: "#/components/responses/UnauthorizedApiKey"
        "403":
          $ref: "#/components/responses/InsufficientScope"
        "429":
          $ref: "#/components/responses/RateLimited"
  /v1/currencies:
    get:
      tags:
        - Discovery
      operationId: listCurrenciesGet
      summary: List supported currencies
      description: |
        Returns currencies for the requested chain IDs. Token amounts in quote
        requests and responses are raw integer units using each token's
        `decimals`.

        `chainIds` may be sent as a comma-separated query value, for example
        `?chainIds=1,8453`. The API also accepts repeated `chainIds` query
        params.
      security:
        - publicApiKey: []
        - {}
      parameters:
        - name: chainIds
          in: query
          required: true
          description: Comma-separated chain IDs.
          schema:
            type: string
            example: "1,8453"
      responses:
        "200":
          description: Supported currencies.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Currency"
              examples:
                currencies:
                  value:
                    - chainId: 1
                      address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
                      symbol: USDC
                      name: USD Coin
                      decimals: 6
                      metadata:
                        verified: true
                    - chainId: 8453
                      address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                      symbol: USDC
                      name: USD Coin
                      decimals: 6
                      metadata:
                        verified: true
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/UnauthorizedApiKey"
        "403":
          $ref: "#/components/responses/InsufficientScope"
        "429":
          $ref: "#/components/responses/RateLimited"
  /v1/quote:
    post:
      tags:
        - Quote
      operationId: createQuote
      summary: Create a quote
      description: |
        Returns quote amounts and the user-signed EVM transactions required to
        execute the route. Submit `transactions` in the returned array order.

        Send `Authorization: Bearer <apiKey>` when using an API key.
      security:
        - publicApiKey: []
        - {}
      x-codeSamples:
        - label: cURL
          lang: bash
          source: |-
            curl 'https://cross-chain-api.kyo.ag/v1/quote' \
              --request POST \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
              --data '{
                "userAddress": "0x1111111111111111111111111111111111111111",
                "recipientAddress": "0x2222222222222222222222222222222222222222",
                "originChainId": 8453,
                "destinationChainId": 999,
                "tokenIn": "0x0000000000000000000000000000000000000000",
                "tokenOut": "0xb88339cb7199b77e23db6e890353e22632ba630f",
                "amountIn": "1000000000000000",
                "slippage": 0.005
              }'
        - label: JavaScript
          lang: JavaScript
          source: |-
            const response = await fetch('https://cross-chain-api.kyo.ag/v1/quote', {
              method: 'POST',
              headers: {
                'content-type': 'application/json',
                authorization: 'Bearer YOUR_SECRET_TOKEN',
              },
              body: JSON.stringify({
                userAddress: '0x1111111111111111111111111111111111111111',
                recipientAddress: '0x2222222222222222222222222222222222222222',
                originChainId: 8453,
                destinationChainId: 999,
                tokenIn: '0x0000000000000000000000000000000000000000',
                tokenOut: '0xb88339cb7199b77e23db6e890353e22632ba630f',
                amountIn: '1000000000000000',
                slippage: 0.005,
              }),
            })

            if (!response.ok) {
              throw new Error(await response.text())
            }

            const quote = await response.json()
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QuoteRequest"
            examples:
              exactInput:
                summary: Base ETH to HyperEVM USDC
                value:
                  userAddress: "0x1111111111111111111111111111111111111111"
                  recipientAddress: "0x2222222222222222222222222222222222222222"
                  originChainId: 8453
                  destinationChainId: 999
                  tokenIn: "0x0000000000000000000000000000000000000000"
                  tokenOut: "0xb88339cb7199b77e23db6e890353e22632ba630f"
                  amountIn: "1000000000000000"
                  slippage: 0.005
      responses:
        "200":
          description: Executable quote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QuoteResponse"
              examples:
                quote:
                  value:
                    userAddress: "0x1111111111111111111111111111111111111111"
                    requestId: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                    originChainId: 1
                    destinationChainId: 8453
                    quote:
                      tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
                      tokenOut: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                      amountIn: "100000000"
                      amountOut: "99500000"
                      minOutputAmount: "99002500"
                      maxInputAmount: null
                      slippage: 0.005
                      partnerFee:
                        feeBps: 5
                        partnerId: 123
                        feeToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                        feeAmount: "50000"
                      partnerId: 123
                    transactions:
                      - from: "0x1111111111111111111111111111111111111111"
                        to: "0x3333333333333333333333333333333333333333"
                        data: "0x"
                        value: "0"
                        chainId: 1
                        stepId: deposit
                        status: pending
                    transactionExplanations:
                      - Deposit token on origin chain
                    timeEstimate: 180
        "400":
          description: Invalid request.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
              examples:
                invalidPartnerFee:
                  value:
                    message: partnerFeeBps must be non-negative
        "401":
          $ref: "#/components/responses/UnauthorizedApiKey"
        "403":
          $ref: "#/components/responses/InsufficientScope"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/transactions/{sourceTxHash}:
    get:
      tags:
        - Status
      operationId: getTransaction
      summary: Get transaction status
      description: |
        Get transaction status by source-chain transaction hash.
      security:
        - publicApiKey: []
        - {}
      parameters:
        - name: sourceTxHash
          in: path
          required: true
          description: Source-chain deposit transaction hash.
          schema:
            type: string
      responses:
        "200":
          description: Transaction status.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionStatus"
              examples:
                status:
                  value:
                    requestId: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                    status:
                      label: Processing
                      kind: processing
                    primaryTransaction:
                      hash: "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                      timestamp: "2026-05-11T00:00:00.000Z"
                      explorerUrl: "https://explorer.example/tx/0xbbbb"
                    updatedAt: "2026-05-11T00:00:30.000Z"
                    source:
                      chainId: 1
                      status:
                        label: Detected
                        kind: processing
                      sender: "0x1111111111111111111111111111111111111111"
                      recipient: "0x3333333333333333333333333333333333333333"
                      token:
                        amount: "100000000"
                        symbol: USDC
                        address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
                        usdValue: "100.00"
                      transaction:
                        hash: "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                        timestamp: "2026-05-11T00:00:00.000Z"
                        explorerUrl: "https://explorer.example/tx/0xbbbb"
                      fee:
                        amount: null
                        symbol: null
                        address: null
                        usdValue: null
                    destination:
                      chainId: 8453
                      status:
                        label: Processing
                        kind: processing
                      sender: null
                      recipient: "0x2222222222222222222222222222222222222222"
                      token:
                        amount: "99500000"
                        symbol: USDC
                        address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                        usdValue: "99.50"
                      transaction:
                        hash: null
                        timestamp: null
                        explorerUrl: null
                      fee:
                        amount: "50000"
                        symbol: USDC
                        address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                        usdValue: "0.05"
        "401":
          $ref: "#/components/responses/UnauthorizedApiKey"
        "403":
          $ref: "#/components/responses/InsufficientScope"
        "404":
          description: Transaction not found.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
              example:
                message: Not found
        "429":
          $ref: "#/components/responses/RateLimited"
components:
  securitySchemes:
    publicApiKey:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: |
        Public API key sent as `Authorization: Bearer <apiKey>`.
  responses:
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
    UnauthorizedApiKey:
      description: API key authentication failed.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
          example:
            message: Unauthorized
    InsufficientScope:
      description: API key is not allowed to call this endpoint.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
          example:
            message: Forbidden
    RateLimited:
      description: Rate limit exceeded.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
          example:
            message: Too Many Requests
    InternalError:
      description: Internal server error.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
  schemas:
    ApiError:
      type: object
      additionalProperties: true
      properties:
        message:
          type: string
        errorCode:
          type: string
      required:
        - message
    Chain:
      type: object
      additionalProperties: false
      properties:
        chainId:
          type: integer
        name:
          type: string
      required:
        - chainId
        - name
    Currency:
      type: object
      additionalProperties: true
      properties:
        chainId:
          type: integer
        address:
          type: string
        symbol:
          type: string
        name:
          type: string
        decimals:
          type: integer
        metadata:
          type: object
          additionalProperties: true
          properties:
            logoURI:
              type: string
            verified:
              type: boolean
            isNative:
              type: boolean
      required:
        - chainId
        - address
        - symbol
        - name
        - decimals
    QuoteRequest:
      type: object
      additionalProperties: false
      properties:
        userAddress:
          type: string
          description: Wallet that signs returned transactions.
          examples:
            - "0x1111111111111111111111111111111111111111"
        recipientAddress:
          type: string
          description: Destination recipient. Defaults to `userAddress`.
          examples:
            - "0x2222222222222222222222222222222222222222"
        originChainId:
          type: integer
          description: Source chain ID.
        destinationChainId:
          type: integer
          description: Destination chain ID.
        tokenIn:
          type: string
          description: Source token address on `originChainId`.
        tokenOut:
          type: string
          description: Destination token address on `destinationChainId`.
        amountIn:
          type: string
          description: Exact input amount in raw token units.
        slippage:
          type: number
          description: Slippage as a decimal fraction, for example `0.005` for 0.5%.
          minimum: 0
        partnerFeeBps:
          type: integer
          description: Optional non-negative integer partner fee in basis points.
          minimum: 0
      required:
        - userAddress
        - originChainId
        - destinationChainId
        - tokenIn
        - tokenOut
        - amountIn
        - slippage
      example:
        userAddress: "0x1111111111111111111111111111111111111111"
        recipientAddress: "0x2222222222222222222222222222222222222222"
        originChainId: 8453
        destinationChainId: 999
        tokenIn: "0x0000000000000000000000000000000000000000"
        tokenOut: "0xb88339cb7199b77e23db6e890353e22632ba630f"
        amountIn: "1000000000000000"
        slippage: 0.005
    QuoteResponse:
      type: object
      additionalProperties: false
      properties:
        userAddress:
          type: string
        requestId:
          type: string
          description: Status tracking ID.
        originChainId:
          type: integer
        destinationChainId:
          type: integer
        quote:
          $ref: "#/components/schemas/Quote"
        transactions:
          type:
            - array
            - "null"
          description: User-signed transactions to submit in order.
          items:
            $ref: "#/components/schemas/QuoteTransaction"
        transactionExplanations:
          type:
            - array
            - "null"
          description: Human-readable descriptions aligned by index with `transactions`.
          items:
            type: string
        timeEstimate:
          type: number
          description: Estimated completion time in seconds.
      required:
        - userAddress
        - requestId
        - originChainId
        - destinationChainId
        - quote
        - transactions
        - transactionExplanations
        - timeEstimate
    Quote:
      type: object
      additionalProperties: false
      properties:
        tokenIn:
          type: string
        tokenOut:
          type: string
        amountIn:
          type: string
        amountOut:
          type: string
        minOutputAmount:
          type:
            - string
            - "null"
        maxInputAmount:
          type:
            - string
            - "null"
        slippage:
          type: number
        partnerFee:
          oneOf:
            - $ref: "#/components/schemas/PartnerFee"
            - type: "null"
        partnerId:
          type:
            - integer
            - "null"
      required:
        - tokenIn
        - tokenOut
        - amountIn
        - amountOut
        - minOutputAmount
        - maxInputAmount
        - slippage
        - partnerFee
        - partnerId
    PartnerFee:
      type: object
      additionalProperties: false
      properties:
        feeBps:
          type: integer
        partnerId:
          type:
            - integer
            - "null"
        feeToken:
          type: string
        feeAmount:
          type: string
      required:
        - feeBps
        - partnerId
        - feeToken
        - feeAmount
    QuoteTransaction:
      type: object
      additionalProperties: true
      description: EVM transaction request. Extra route-specific fields may be present.
      properties:
        from:
          type: string
        to:
          type: string
        data:
          type: string
        value:
          type: string
        chainId:
          type: integer
        stepId:
          type: string
        status:
          type: string
        check:
          $ref: "#/components/schemas/TransactionCheck"
    TransactionCheck:
      type: object
      additionalProperties: false
      properties:
        endpoint:
          type: string
        method:
          type: string
      required:
        - endpoint
        - method
    TransactionsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/TransactionStatus"
        nextCursor:
          type:
            - string
            - "null"
      required:
        - items
        - nextCursor
    TransactionStatus:
      type: object
      additionalProperties: false
      properties:
        requestId:
          type: string
        status:
          $ref: "#/components/schemas/StatusLabel"
        primaryTransaction:
          $ref: "#/components/schemas/TransactionRef"
        updatedAt:
          type: string
          format: date-time
        source:
          $ref: "#/components/schemas/TransactionNode"
        destination:
          $ref: "#/components/schemas/TransactionNode"
      required:
        - requestId
        - status
        - primaryTransaction
        - updatedAt
        - source
        - destination
    StatusLabel:
      type: object
      additionalProperties: false
      properties:
        label:
          type: string
        kind:
          type: string
          enum:
            - processing
            - success
            - failed
            - refunding
            - refunded
      required:
        - label
        - kind
    TransactionRef:
      type: object
      additionalProperties: false
      properties:
        hash:
          type:
            - string
            - "null"
        timestamp:
          type:
            - string
            - "null"
          format: date-time
        explorerUrl:
          type:
            - string
            - "null"
      required:
        - hash
        - timestamp
        - explorerUrl
    TransactionToken:
      type: object
      additionalProperties: false
      properties:
        amount:
          type:
            - string
            - "null"
        symbol:
          type:
            - string
            - "null"
        address:
          type:
            - string
            - "null"
        usdValue:
          type:
            - string
            - "null"
      required:
        - amount
        - symbol
        - address
        - usdValue
    TransactionNode:
      type: object
      additionalProperties: false
      properties:
        chainId:
          type:
            - integer
            - "null"
        status:
          $ref: "#/components/schemas/StatusLabel"
        sender:
          type:
            - string
            - "null"
        recipient:
          type:
            - string
            - "null"
        token:
          $ref: "#/components/schemas/TransactionToken"
        transaction:
          $ref: "#/components/schemas/TransactionRef"
        fee:
          $ref: "#/components/schemas/TransactionToken"
      required:
        - chainId
        - status
        - token
        - transaction
        - fee
