openapi: 3.0.3
info:
  title: XDAO TON API docs
  version: 1.1.0
  description: |
    Authorization model:
    - Use `Authorization: Bearer <DAO_TOKEN>`.
    - Access is restricted to the DAO bound to the token.

servers:
  - url: https://ton.xdao.app

tags:
  - name: DAO-details
    description: Read-only DAO-scoped endpoints accessible with DAO tokens.

security:
  - DaoBearerAuth: []

paths:
  /api/v1/daos/{dao_address}:
    get:
      tags:
        - DAO-details
      summary: Get DAO details
      description: Returns detailed information about a single DAO.
      operationId: getDaoInfo
      security:
        - DaoBearerAuth: []
      parameters:
        - $ref: "#/components/parameters/DaoAddressPath"
      responses:
        "200":
          description: DAO details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Dao"
              examples:
                example:
                  value:
                    address: "0:698fb737c352c9691994ed676fa5718243d15f11ed7c89d85d1f29e20ee5304c"
                    owner_address: "0:a8f9f41035f7c2208d3e8842f6f2f2df8ab3f9496fba4d472f7f01d8cb9c0011"
                    name: "TON Growth DAO"
                    jetton_address: "0:de3d0f1a5bcb8e3127f0d2b2f9ef4e95f620fbe22088697f7bf7b9a1e83400aa"
                    jetton_metadata:
                      metadata:
                        name: "TON Growth DAO"
                        symbol: "TGDAO"
                        image: "https://cdn.xdao.app/tokens/tgdao.png"
                    success_percentage: 51
                    total_supply: "1000000000000"
                    date_create: "2026-01-15 12:10:44"
                    crowdfunding_status: "enabled"
                    plugins:
                      - address: "0:4d96f12f4cfde1a9e7e4559f6c16f9342f44e6e981a4f440e36ac2ad5d9f9988"
                        type: "lpManagerV65"
                        lp_manager_index: 1
                        lp_jetton_master_address: "0:ca11ab1e7a7c51ec9d6f132a33f7b34a04965af7d15e9c8f2f9b2df8f3168891"
                        lp_token_name: "XDAO LP"
                        lp_token_symbol: "XLP"
                        lp_token_image: "https://cdn.xdao.app/tokens/xlp.png"
                        subaccount_index: null
                        subaccount_name: null
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalError"

  /api/v1/daos/{dao_address}/holders:
    get:
      tags:
        - DAO-details
      summary: Get DAO holders
      description: Returns paginated list of DAO holders.
      operationId: getDaoHolders
      security:
        - DaoBearerAuth: []
      parameters:
        - $ref: "#/components/parameters/DaoAddressPath"
        - $ref: "#/components/parameters/LimitQuery"
        - $ref: "#/components/parameters/OffsetQuery"
      responses:
        "200":
          description: DAO holder list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DaoHoldersList"
              examples:
                example:
                  value:
                    total: 2
                    items:
                      - jetton_wallet_address: "0:1111111111111111111111111111111111111111111111111111111111111111"
                        owner_address: "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                        balance: "1250000000"
                      - jetton_wallet_address: "0:2222222222222222222222222222222222222222222222222222222222222222"
                        owner_address: "0:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                        balance: "980000000"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/Forbidden"
        "500":
          $ref: "#/components/responses/InternalError"

  /api/v1/daos/{dao_address}/proposals:
    get:
      tags:
        - DAO-details
      summary: Get DAO proposals
      description: Returns paginated list of proposals for a DAO.
      operationId: getDaoProposals
      security:
        - DaoBearerAuth: []
      parameters:
        - $ref: "#/components/parameters/DaoAddressPath"
        - $ref: "#/components/parameters/LimitQuery"
        - $ref: "#/components/parameters/OffsetQuery"
      responses:
        "200":
          description: DAO proposal list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalList"
              examples:
                example:
                  value:
                    total: 1
                    items:
                      - proposal_id: 42
                        name: "Treasury rebalance"
                        description: "Reallocate treasury assets"
                        is_user_voted: false
                        address: "0:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"
                        dao_address: "0:698fb737c352c9691994ed676fa5718243d15f11ed7c89d85d1f29e20ee5304c"
                        jetton_master_address: "0:de3d0f1a5bcb8e3127f0d2b2f9ef4e95f620fbe22088697f7bf7b9a1e83400aa"
                        initiated_by_address: "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                        success_amount: "510000000000"
                        current_amount: "312000000000"
                        total_supply: "1000000000000"
                        success_percentage: 51
                        date_start: "2026-03-10 10:00:00"
                        date_expire: "2026-03-17 10:00:00"
                        type: "generic"
                        data:
                          title: "Treasury rebalance"
                          action: "transfer"
                        status: "active"
                        raw_data: "b5ee9c720101010100..."
                        dao:
                          address: "0:698fb737c352c9691994ed676fa5718243d15f11ed7c89d85d1f29e20ee5304c"
                          owner_address: "0:a8f9f41035f7c2208d3e8842f6f2f2df8ab3f9496fba4d472f7f01d8cb9c0011"
                          name: "TON Growth DAO"
                          jetton_address: "0:de3d0f1a5bcb8e3127f0d2b2f9ef4e95f620fbe22088697f7bf7b9a1e83400aa"
                          jetton_metadata:
                            metadata:
                              symbol: "TGDAO"
                          success_percentage: 51
                          total_supply: "1000000000000"
                          date_create: "2026-01-15 12:10:44"
                          crowdfunding_status: "enabled"
                          plugins: []
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/Forbidden"
        "500":
          $ref: "#/components/responses/InternalError"

  /api/v1/daos/{dao_address}/proposals/{proposal_address}/votes:
    get:
      tags:
        - DAO-details
      summary: Get proposal votes
      description: Returns paginated votes for a DAO proposal.
      operationId: getDaoProposalVotes
      security:
        - DaoBearerAuth: []
      parameters:
        - $ref: "#/components/parameters/DaoAddressPath"
        - $ref: "#/components/parameters/ProposalAddressPath"
        - $ref: "#/components/parameters/LimitQuery"
        - $ref: "#/components/parameters/OffsetQuery"
      responses:
        "200":
          description: Proposal votes list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalVotesList"
              examples:
                example:
                  value:
                    total: 2
                    items:
                      - proposal_address: "0:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"
                        voter_address: "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                        amount: "50000000000"
                        date_create: "2026-03-11 11:24:10"
                      - proposal_address: "0:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"
                        voter_address: "0:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                        amount: "21000000000"
                        date_create: "2026-03-11 11:25:22"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/Forbidden"
        "500":
          $ref: "#/components/responses/InternalError"

  /api/v1/daos/{dao_address}/crowdfundings:
    get:
      tags:
        - DAO-details
      summary: Get DAO crowdfunding campaigns
      description: Returns paginated crowdfunding campaigns for a DAO.
      operationId: getDaoCrowdfundings
      security:
        - DaoBearerAuth: []
      parameters:
        - $ref: "#/components/parameters/DaoAddressPath"
        - $ref: "#/components/parameters/LimitQuery"
        - $ref: "#/components/parameters/OffsetQuery"
      responses:
        "200":
          description: DAO crowdfunding campaign list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CrowdfundingCampaignList"
              examples:
                example:
                  value:
                    total: 1
                    items:
                      - address: "0:9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a"
                        daoAddress: "0:698fb737c352c9691994ed676fa5718243d15f11ed7c89d85d1f29e20ee5304c"
                        status: "active"
                        name: "DAO Seed Round"
                        description: "Seed round for protocol growth"
                        daoName: "TON Growth DAO"
                        isNative: true
                        jettonSymbol: null
                        jettonDecimals: null
                        jettonImage: null
                        jettonMasterAddress: ""
                        lpManagerAddress: "0:7777777777777777777777777777777777777777777777777777777777777777"
                        lpJettonMasterAddress: "0:8888888888888888888888888888888888888888888888888888888888888888"
                        destinationAddress: "0:9999999999999999999999999999999999999999999999999999999999999999"
                        feeManagerAddress: "0:1212121212121212121212121212121212121212121212121212121212121212"
                        minTotalAmount: "100000000000"
                        maxTotalAmount: "1000000000000"
                        minAmountPerUser: "1000000000"
                        maxAmountPerUser: "50000000000"
                        startTime: "2026-03-01T00:00:00Z"
                        endTime: "2026-04-01T00:00:00Z"
                        lpPrice: "1000000000"
                        managementFee: 200
                        paused: false
                        totalAmount: "250000000000"
                        totalClaimed: "0"
                        totalRefunded: "0"
                        isEmergencyWithdrawn: false
                        hasWhitelist: false
                        whitelist: []
                        contributors: []
                        participantsCount: 123
                        progressPercentage: 25.0
                        updatedAt: "2026-03-11T13:00:00Z"
                        finishedAt: "0001-01-01T00:00:00Z"
                        daoFeeClaimed: false
                        daoFeeClaimedAt: null
                        daoFeeAmount: "5000000000"
                        dao:
                          address: "0:698fb737c352c9691994ed676fa5718243d15f11ed7c89d85d1f29e20ee5304c"
                          owner_address: "0:a8f9f41035f7c2208d3e8842f6f2f2df8ab3f9496fba4d472f7f01d8cb9c0011"
                          name: "TON Growth DAO"
                          jetton_address: "0:de3d0f1a5bcb8e3127f0d2b2f9ef4e95f620fbe22088697f7bf7b9a1e83400aa"
                          jetton_metadata:
                            metadata:
                              symbol: "TGDAO"
                          success_percentage: 51
                          total_supply: "1000000000000"
                          date_create: "2026-01-15 12:10:44"
                          crowdfunding_status: "enabled"
                          plugins: []
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/Forbidden"
        "500":
          $ref: "#/components/responses/InternalError"

  /api/v1/daos/{dao_address}/lp-masters-with-lp-holders:
    get:
      tags:
        - DAO-details
      summary: Get DAO LP masters with LP holders
      description: Returns LP masters and nested LP holders for a DAO.
      operationId: getDaoLpMastersWithLpHolders
      security:
        - DaoBearerAuth: []
      parameters:
        - $ref: "#/components/parameters/DaoAddressPath"
        - $ref: "#/components/parameters/MastersLimitQuery"
        - $ref: "#/components/parameters/MastersOffsetQuery"
        - $ref: "#/components/parameters/HoldersLimitQuery"
        - $ref: "#/components/parameters/HoldersOffsetQuery"
      responses:
        "200":
          description: DAO LP masters with LP holders
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DaoLpMasterWithLpHoldersList"
              examples:
                example:
                  value:
                    total: 1
                    items:
                      - lpJettonMasterAddress: "0:8888888888888888888888888888888888888888888888888888888888888888"
                        campaignAddresses:
                          - "0:9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a"
                        holdersTotal: 2
                        holders:
                          - lpJettonWalletAddress: "0:abababababababababababababababababababababababababababababababab"
                            ownerAddress: "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                            balance: "800000000"
                          - lpJettonWalletAddress: "0:bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc"
                            ownerAddress: "0:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                            balance: "250000000"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/Forbidden"
        "500":
          $ref: "#/components/responses/InternalError"

components:
  securitySchemes:
    DaoBearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        DAO service token in Bearer format.
        The token must be valid, not revoked, and authorized for the same `dao_address` as in path.

  parameters:
    DaoAddressPath:
      name: dao_address
      in: path
      required: true
      description: DAO address in raw format.
      schema:
        type: string

    ProposalAddressPath:
      name: proposal_address
      in: path
      required: true
      description: Proposal address in raw format.
      schema:
        type: string

    LimitQuery:
      name: limit
      in: query
      required: false
      description: Page size.
      schema:
        type: integer
        minimum: 1
        maximum: 1000
        default: 100

    OffsetQuery:
      name: offset
      in: query
      required: false
      description: Pagination offset.
      schema:
        type: integer
        minimum: 0
        default: 0

    MastersLimitQuery:
      name: masters_limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 1000
        default: 100

    MastersOffsetQuery:
      name: masters_offset
      in: query
      required: false
      schema:
        type: integer
        minimum: 0
        default: 0

    HoldersLimitQuery:
      name: holders_limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 1000
        default: 100

    HoldersOffsetQuery:
      name: holders_offset
      in: query
      required: false
      schema:
        type: integer
        minimum: 0
        default: 0

  schemas:
    Plugin:
      type: object
      required:
        - address
        - type
      properties:
        address:
          type: string
        type:
          type: string
        lp_manager_index:
          type: integer
          nullable: true
          description: LP Manager index (v6.1+), null for other plugin types.
        lp_jetton_master_address:
          type: string
          nullable: true
          description: LP token jetton master address (only for LP Manager).
        lp_token_name:
          type: string
          nullable: true
        lp_token_symbol:
          type: string
          nullable: true
        lp_token_image:
          type: string
          nullable: true
        subaccount_index:
          type: integer
          nullable: true
        subaccount_name:
          type: string
          nullable: true

    Holder:
      type: object
      required:
        - jetton_wallet_address
        - owner_address
        - balance
      properties:
        jetton_wallet_address:
          type: string
        owner_address:
          type: string
        balance:
          type: string

    Dao:
      type: object
      required:
        - address
        - owner_address
        - name
        - jetton_address
        - jetton_metadata
        - success_percentage
        - total_supply
        - plugins
        - date_create
        - crowdfunding_status
      properties:
        address:
          type: string
        owner_address:
          type: string
        name:
          type: string
        jetton_address:
          type: string
        jetton_metadata:
          type: object
          additionalProperties: true
        success_percentage:
          type: number
        total_supply:
          type: string
        date_create:
          type: string
        plugins:
          type: array
          items:
            $ref: "#/components/schemas/Plugin"
        crowdfunding_status:
          type: string
          enum: [legacy, enabled, ready]

    Vote:
      type: object
      required:
        - proposal_address
        - voter_address
        - amount
        - date_create
      properties:
        proposal_address:
          type: string
        voter_address:
          type: string
        amount:
          type: string
        date_create:
          type: string

    ProposalStatus:
      type: string
      enum: [active, rejected, executed, mine, unknown]

    Proposal:
      type: object
      required:
        - proposal_id
        - address
        - dao_address
        - jetton_master_address
        - initiated_by_address
        - success_amount
        - current_amount
        - total_supply
        - success_percentage
        - date_start
        - date_expire
        - type
        - data
        - status
        - raw_data
        - dao
      properties:
        proposal_id:
          type: integer
          format: int64
        name:
          type: string
        is_user_voted:
          type: boolean
        description:
          type: string
        address:
          type: string
        dao_address:
          type: string
          deprecated: true
        jetton_master_address:
          type: string
        initiated_by_address:
          type: string
        success_amount:
          type: string
        current_amount:
          type: string
        total_supply:
          type: string
        success_percentage:
          type: number
        date_start:
          type: string
        date_expire:
          type: string
        type:
          type: string
        data:
          type: object
          additionalProperties: true
        status:
          $ref: "#/components/schemas/ProposalStatus"
        raw_data:
          type: string
        dao:
          $ref: "#/components/schemas/Dao"

    CampaignStatus:
      type: string
      enum: [active, successful, failed, emergency_withdrawn]

    CrowdfundingContributor:
      type: object
      required:
        - address
        - amount
      properties:
        address:
          type: string
        amount:
          type: string

    CrowdfundingParticipant:
      type: object
      required:
        - address
        - masterAddress
        - ownerAddress
        - amount
      properties:
        address:
          type: string
        masterAddress:
          type: string
        ownerAddress:
          type: string
        amount:
          type: string
        isClaimed:
          type: boolean
        isRefunded:
          type: boolean
        claimedAt:
          type: string
          format: date-time
        refundedAt:
          type: string
          format: date-time
        dateCreate:
          type: string
          format: date-time

    CrowdfundingCampaign:
      type: object
      required:
        - address
        - daoAddress
        - status
      properties:
        address:
          type: string
        daoAddress:
          type: string
        name:
          type: string
        description:
          type: string
        daoName:
          type: string
        isNative:
          type: boolean
        jettonSymbol:
          type: string
          nullable: true
        jettonDecimals:
          type: integer
          nullable: true
        jettonImage:
          type: string
          nullable: true
        jettonMasterAddress:
          type: string
        lpManagerAddress:
          type: string
        lpJettonMasterAddress:
          type: string
        destinationAddress:
          type: string
        feeManagerAddress:
          type: string
        minTotalAmount:
          type: string
        maxTotalAmount:
          type: string
        minAmountPerUser:
          type: string
        maxAmountPerUser:
          type: string
        startTime:
          type: string
          format: date-time
        endTime:
          type: string
          format: date-time
        lpPrice:
          type: string
        managementFee:
          type: integer
        status:
          $ref: "#/components/schemas/CampaignStatus"
        paused:
          type: boolean
        totalAmount:
          type: string
        totalClaimed:
          type: string
        totalRefunded:
          type: string
        isEmergencyWithdrawn:
          type: boolean
        hasWhitelist:
          type: boolean
        whitelist:
          type: array
          items:
            type: string
        contributors:
          type: array
          items:
            $ref: "#/components/schemas/CrowdfundingContributor"
        participantsCount:
          type: integer
        progressPercentage:
          type: number
          format: float
        updatedAt:
          type: string
          format: date-time
        finishedAt:
          type: string
          format: date-time
        dao:
          $ref: "#/components/schemas/Dao"
        userHelper:
          $ref: "#/components/schemas/CrowdfundingParticipant"
        daoFeeClaimed:
          type: boolean
        daoFeeClaimedAt:
          type: string
          format: date-time
          nullable: true
        daoFeeAmount:
          type: string

    CrowdfundingLpHolder:
      type: object
      required:
        - lpJettonWalletAddress
        - ownerAddress
        - balance
      properties:
        lpJettonWalletAddress:
          type: string
        ownerAddress:
          type: string
        balance:
          type: string

    DaoLpMasterWithLpHolders:
      type: object
      required:
        - lpJettonMasterAddress
        - campaignAddresses
        - holdersTotal
        - holders
      properties:
        lpJettonMasterAddress:
          type: string
        campaignAddresses:
          type: array
          items:
            type: string
        holdersTotal:
          type: integer
          format: int64
        holders:
          type: array
          items:
            $ref: "#/components/schemas/CrowdfundingLpHolder"

    DaoHoldersList:
      type: object
      required: [total, items]
      properties:
        total:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: "#/components/schemas/Holder"

    ProposalList:
      type: object
      required: [total, items]
      properties:
        total:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: "#/components/schemas/Proposal"

    ProposalVotesList:
      type: object
      required: [total, items]
      properties:
        total:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: "#/components/schemas/Vote"

    CrowdfundingCampaignList:
      type: object
      required: [total, items]
      properties:
        total:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: "#/components/schemas/CrowdfundingCampaign"

    DaoLpMasterWithLpHoldersList:
      type: object
      required: [total, items]
      properties:
        total:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: "#/components/schemas/DaoLpMasterWithLpHolders"

    Error:
      type: object
      required: [error]
      properties:
        error:
          type: string

  responses:
    UnauthorizedError:
      description: Token is missing, invalid, expired, or revoked.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "missing token"

    Forbidden:
      description: Token does not have access to this DAO or endpoint.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "dao token is not allowed for requested dao"

    NotFound:
      description: Requested resource was not found.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "not found"

    InternalError:
      description: Internal server error.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "internal server error"
