> ## Documentation Index
> Fetch the complete documentation index at: https://api-portal.etoro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit KYC Questionnaire Answers

> **Rate limit:** 60 requests per 60 seconds. This is the **default shared quota** — it is shared with every other endpoint that has no dedicated limit, so requests across those endpoints all draw from the same budget.

---

Submits the authenticated user's answers to the KYC questionnaire in a single request. Each answer is applied individually upstream. Returns 200 when every answer is accepted; returns 422 when one or more answers are rejected (partial or full), with a per-question breakdown serialized as a JSON string into error.details. A 207 Multi-Status response is never returned.



## OpenAPI

````yaml /api-reference/partners-openapi.json post /api/v1/kyc-data/questionnaire
openapi: 3.0.1
info:
  title: eToro Api
  version: v1.342.0
  description: >-
    eToro’s public API provides access to real-time financial data, trading
    insights, and account management features, allowing developers to integrate
    eToro’s services into their applications. With access to market prices,
    historical data, and social trading information, the API empowers users to
    enhance their trading strategies. Designed for security and scalability, the
    eToro API ensures smooth and reliable integration for a variety of financial
    applications.


    For more details on integrating with eToro's public WebSocket service,
    please refer to the dedicated [WebSocket
    documentation](./websocket/websocket-doc.html).


    ## Authentication


    Every request must be authenticated with exactly one of two options: an
    OAuth 2.0 access token (`Authorization: Bearer <token>`), or the
    non-interactive credential pair (`x-api-key` + `x-user-key` headers). The
    two options are mutually exclusive — a request carrying both is rejected.
    Each operation lists the OAuth scopes that grant access as alternative
    security requirements: a bearer token needs only ONE of them, and the same
    permissions govern the credential pair.
servers:
  - url: https://public-api.etoro.com
    description: eToro Public API - Partners
security:
  - apiKeyAuth: []
    userKeyAuth: []
  - oauth2: []
tags:
  - name: OPS
  - name: KYC
  - name: Cash Accounts
  - name: FTD
  - name: Crypto Deposit
  - name: Crypto Withdrawals
  - name: Registration
  - name: Sub-Accounts
  - name: Email Verification
  - name: Trusted Partner
  - name: Phone Verification
  - name: Verification
paths:
  /api/v1/kyc-data/questionnaire:
    post:
      tags:
        - KYC
      summary: Submit KYC Questionnaire Answers
      description: >-
        **Rate limit:** 60 requests per 60 seconds. This is the **default shared
        quota** — it is shared with every other endpoint that has no dedicated
        limit, so requests across those endpoints all draw from the same budget.


        ---


        Submits the authenticated user's answers to the KYC questionnaire in a
        single request. Each answer is applied individually upstream. Returns
        200 when every answer is accepted; returns 422 when one or more answers
        are rejected (partial or full), with a per-question breakdown serialized
        as a JSON string into error.details. A 207 Multi-Status response is
        never returned.
      operationId: SubmitKycQuestionnaire
      parameters:
        - name: x-request-id
          in: header
          required: true
          schema:
            type: string
            format: uuid
            example: 73bb69b8-72ea-4f80-b7f9-e71398392780
          description: A unique request identifier.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                answers:
                  type: array
                  description: List of answers to submit, one entry per question.
                  items:
                    type: object
                    properties:
                      questionId:
                        type: integer
                        format: int32
                        description: Identifier of the question being answered.
                      answerIds:
                        type: array
                        description: >-
                          Selected answer identifiers for this question.
                          Multiple values allowed for multi-select questions.
                        items:
                          type: integer
                          format: int32
                      freeTexts:
                        type: array
                        description: >-
                          Free-text payload for answers that accept additional
                          text input.
                        items:
                          type: object
                          properties:
                            answerId:
                              type: integer
                              format: int32
                              description: >-
                                Identifier of the answer the free text belongs
                                to.
                            text:
                              type: string
                              description: Free-text content provided by the user.
            example:
              answers:
                - questionId: 101
                  answerIds:
                    - 11
                    - 12
                  freeTexts:
                    - answerId: 12
                      text: Freelance software development
                - questionId: 102
                  answerIds:
                    - 21
                  freeTexts: []
      responses:
        '200':
          description: >-
            All submitted answers were accepted. Returns a per-question
            breakdown with counts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireBulkResult'
              example:
                results:
                  - questionId: 101
                    status: Accepted
                  - questionId: 102
                    status: Accepted
                successCount: 2
                failureCount: 0
          headers:
            RateLimit-Limit:
              description: >-
                Maximum number of requests allowed per window. This is the
                default shared pool used by every endpoint without a dedicated
                limit, so it is NOT per-endpoint — requests across those
                endpoints all draw from this one budget.
              schema:
                type: integer
              example: 60
            RateLimit-Remaining:
              description: Requests remaining in the current window for this quota.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
            RateLimit-Policy:
              description: Quota policy in the form `<limit>;w=<window-seconds>`.
              schema:
                type: string
              example: 60;w=60
        '400':
          description: >-
            Structural validation failed (missing or empty body, empty answers
            array, empty answerIds).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KycFacadeApi_ErrorResponse'
              examples:
                AnswersRequired:
                  summary: answers is required
                  value:
                    errorCode: RequestBodyRequired
                    errorMessage: Answers is required
                AnswerIdsEmpty:
                  summary: answerIds must be non-empty
                  value:
                    errorCode: RequestBodyRequired
                    errorMessage: AnswerIds must be non-empty for questionId {questionId}
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KycFacadeApi_ErrorResponse'
        '422':
          description: >-
            One or more answers were rejected (partial or full). The
            per-question outcome is serialized as a JSON string in
            error.details. A 207 Multi-Status response is never returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireBulkError'
              example:
                success: false
                error:
                  code: VALIDATION_FAILED
                  message: 1 of 2 answers were not accepted.
                  details: >-
                    {"results":[{"questionId":101,"status":"Accepted"},{"questionId":102,"status":"Failed","error":{"code":"UNKNOWN_QUESTION","message":"Question
                    102 is not in the
                    catalogue"}}],"successCount":1,"failureCount":1}
        '429':
          description: >-
            Too Many Requests — the shared rate limit (60 requests / 60s) was
            exceeded.
          headers:
            RateLimit-Limit:
              description: >-
                Maximum number of requests allowed per window. This is the
                default shared pool used by every endpoint without a dedicated
                limit, so it is NOT per-endpoint — requests across those
                endpoints all draw from this one budget.
              schema:
                type: integer
              example: 60
            RateLimit-Remaining:
              description: Requests remaining in the current window for this quota.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
            RateLimit-Policy:
              description: Quota policy in the form `<limit>;w=<window-seconds>`.
              schema:
                type: string
              example: 60;w=60
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
              example: 60
        '500':
          description: >-
            No answers were accepted due to an unexpected internal error. The
            per-question outcome is serialized as a JSON string in
            error.details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireBulkError'
              example:
                success: false
                error:
                  code: INTERNAL_ERROR
                  message: 2 of 2 answers were not accepted.
                  details: >-
                    {"results":[{"questionId":101,"status":"Failed","error":{"code":"INTERNAL_ERROR","message":"Unexpected
                    internal
                    error"}},{"questionId":102,"status":"Failed","error":{"code":"INTERNAL_ERROR","message":"Unexpected
                    internal error"}}],"successCount":0,"failureCount":2}
        '502':
          description: >-
            No answers were accepted because the upstream KYC service is
            unavailable (outage, timeout, or circuit open). Safe to retry
            unchanged. The per-question outcome is serialized as a JSON string
            in error.details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionnaireBulkError'
              example:
                success: false
                error:
                  code: DEPENDENCY_UNAVAILABLE
                  message: 2 of 2 answers were not accepted.
                  details: >-
                    {"results":[{"questionId":101,"status":"Failed","error":{"code":"INTERNAL_ERROR","message":"UserApi
                    dependency
                    failed"}},{"questionId":102,"status":"Failed","error":{"code":"INTERNAL_ERROR","message":"UserApi
                    dependency failed"}}],"successCount":0,"failureCount":2}
      security:
        - apiKeyAuth: []
          userKeyAuth: []
        - oauth2:
            - etoro-public:kyc:answers:write
components:
  schemas:
    QuestionnaireBulkResult:
      type: object
      description: Per-question outcome of a bulk questionnaire submission.
      properties:
        results:
          type: array
          description: Per-question result entries.
          items:
            type: object
            properties:
              questionId:
                type: integer
                format: int32
                description: Identifier of the question this result refers to.
              status:
                type: string
                description: 'Outcome for this question. Values: "Accepted", "Failed".'
              error:
                type: object
                description: Error details, present only when status is "Failed".
                properties:
                  code:
                    type: string
                    description: >-
                      Machine-readable error code (e.g. "UNKNOWN_QUESTION",
                      "INTERNAL_ERROR").
                  message:
                    type: string
                    description: Human-readable error message.
        successCount:
          type: integer
          format: int32
          description: Number of answers that were accepted.
        failureCount:
          type: integer
          format: int32
          description: Number of answers that failed.
    KycFacadeApi_ErrorResponse:
      type: object
      properties:
        errorCode:
          type: string
        errorMessage:
          type: string
    QuestionnaireBulkError:
      type: object
      description: >-
        Error envelope for a bulk questionnaire submission where one or more
        answers were not accepted. The per-question breakdown is serialized as a
        JSON string in error.details (schema QuestionnaireBulkResult).
      properties:
        success:
          type: boolean
          description: Always false for error responses.
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Top-level error code. "VALIDATION_FAILED" when answers are
                rejected (422); "INTERNAL_ERROR" when nothing was accepted due
                to an unexpected internal error (500); "DEPENDENCY_UNAVAILABLE"
                when the upstream KYC service is unavailable (502).
            message:
              type: string
              description: >-
                Human-readable summary (e.g. "1 of 2 answers were not
                accepted.").
            details:
              type: string
              description: >-
                JSON string containing the QuestionnaireBulkResult breakdown
                (results[], successCount, failureCount).
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key of the application. Only valid together with the x-user-key
        header — the pair is an alternative to OAuth bearer authentication,
        never sent alongside it. The pair is granted the same permissions the
        operation's OAuth scopes describe.


        Demo credential for trying the API from these docs:
        `lhgfaslk21490FAScVPkdsb53F9dNkfHG4faZSG5vfjndfcfgdssdgsdHF4663`
      x-default: lhgfaslk21490FAScVPkdsb53F9dNkfHG4faZSG5vfjndfcfgdssdgsdHF4663
    userKeyAuth:
      type: apiKey
      in: header
      name: x-user-key
      description: >-
        User-specific authentication key. Only valid together with the x-api-key
        header — the pair is an alternative to OAuth bearer authentication,
        never sent alongside it.


        Demo credential for trying the API from these docs:
        `eyJlYW4iOiJVbnJlZ2lzdGVyZWRBcHBsaWNhdGlvbiIsImVrIjoiOE5sZ2cwcW5EUVdROUFNWGpXT2lmOWktZnpidG5KcUlqWGJ3WHJZZkpZcldrbG90ZEhvLVBjSWhQaU8xU1ZtMW84aU1WZGZqN2xWNzFjLXFxLmcybXE1dnh4Q1hUT25xaWRUaTFlcEhmVk1fIn0_`
      x-default: >-
        eyJlYW4iOiJVbnJlZ2lzdGVyZWRBcHBsaWNhdGlvbiIsImVrIjoiOE5sZ2cwcW5EUVdROUFNWGpXT2lmOWktZnpidG5KcUlqWGJ3WHJZZkpZcldrbG90ZEhvLVBjSWhQaU8xU1ZtMW84aU1WZGZqN2xWNzFjLXFxLmcybXE1dnh4Q1hUT25xaWRUaTFlcEhmVk1fIn0_
    oauth2:
      type: oauth2
      description: >-
        eToro OAuth2 — send the access token as `Authorization: Bearer <token>`.
        Each operation lists the scopes that grant access as separate `security`
        requirements (OpenAPI OR semantics): the caller's token only needs ONE
        of them — you do NOT need all of them. Mutually exclusive with the
        x-api-key/x-user-key credential pair: never send both.
      flows:
        authorizationCode:
          authorizationUrl: ''
          tokenUrl: ''
          scopes:
            etoro-public:demo:read: Grants access to the 'etoro-public:demo:read' scope.
            etoro-public:kyc:answers:read: Grants access to the 'etoro-public:kyc:answers:read' scope.
            etoro-public:kyc:answers:write: Grants access to the 'etoro-public:kyc:answers:write' scope.
            etoro-public:kyc:questions:read: Grants access to the 'etoro-public:kyc:questions:read' scope.
            etoro-public:kyc:read: Grants access to the 'etoro-public:kyc:read' scope.
            etoro-public:kyc:regulations:read: Grants access to the 'etoro-public:kyc:regulations:read' scope.
            etoro-public:kyc:write: Grants access to the 'etoro-public:kyc:write' scope.
            etoro-public:money.accounts:read: Grants access to the 'etoro-public:money.accounts:read' scope.
            etoro-public:money.accounts:write: Grants access to the 'etoro-public:money.accounts:write' scope.
            etoro-public:money.deposit.crypto:read: >-
              Grants access to the 'etoro-public:money.deposit.crypto:read'
              scope.
            etoro-public:money.deposit.crypto:write: >-
              Grants access to the 'etoro-public:money.deposit.crypto:write'
              scope.
            etoro-public:money.ftd:read: Grants access to the 'etoro-public:money.ftd:read' scope.
            etoro-public:money.ftd:write: Grants access to the 'etoro-public:money.ftd:write' scope.
            etoro-public:money.withdraw.crypto:read: >-
              Grants access to the 'etoro-public:money.withdraw.crypto:read'
              scope.
            etoro-public:money.withdraw.crypto:write: >-
              Grants access to the 'etoro-public:money.withdraw.crypto:write'
              scope.
            etoro-public:partner-default: Grants access to the 'etoro-public:partner-default' scope.
            etoro-public:partner:registration:read: >-
              Grants access to the 'etoro-public:partner:registration:read'
              scope.
            etoro-public:partner:registration:write: >-
              Grants access to the 'etoro-public:partner:registration:write'
              scope.
            etoro-public:real:read: Grants access to the 'etoro-public:real:read' scope.
            etoro-public:sub-accounts:delete: Grants access to the 'etoro-public:sub-accounts:delete' scope.
            etoro-public:verification.address:read: >-
              Grants access to the 'etoro-public:verification.address:read'
              scope.
            etoro-public:verification.address:write: >-
              Grants access to the 'etoro-public:verification.address:write'
              scope.
            etoro-public:verification.email:write: >-
              Grants access to the 'etoro-public:verification.email:write'
              scope.
            etoro-public:verification.personaldetails:read: >-
              Grants access to the
              'etoro-public:verification.personaldetails:read' scope.
            etoro-public:verification.personaldetails:write: >-
              Grants access to the
              'etoro-public:verification.personaldetails:write' scope.
            etoro-public:verification.phone:write: >-
              Grants access to the 'etoro-public:verification.phone:write'
              scope.
            etoro-public:verification.trusted.email:write: >-
              Grants access to the
              'etoro-public:verification.trusted.email:write' scope.
            etoro-public:verification.trusted.phone:write: >-
              Grants access to the
              'etoro-public:verification.trusted.phone:write' scope.
            etoro-public:verification:trusted:user:write: >-
              Grants access to the
              'etoro-public:verification:trusted:user:write' scope.

````