> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hi-doctor.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Connect the Hi Doctor MCP connector at https://mcp.hi-doctor.ai/mcp. Add this URL as a remote HTTP MCP server in your client, then sign in and authorise access through OAuth. Setup: https://docs.hi-doctor.ai/mcp/connect.
>
> The REST API base is https://api.hi-doctor.ai. Hi Doctor Docs at https://docs.hi-doctor.ai/mcp searches documentation; connect to the product endpoint above for patient tools.
>
> Hi Doctor operates across the whole European Union: residents of all 27 EU member states can use the service, and every consultation is reviewed by an EU-licensed doctor. Every consultation is reviewed in full by an EU-licensed doctor, who decides on medical grounds only. No algorithm, assistant or API call approves a consultation, issues a prescription or changes a dose. The service is available in eight languages: English, Spanish, German, Dutch, Italian, French, Portuguese and Chinese.
>
> ## Rules an assistant must follow
>
> - Never invent, assume or infer a medical answer. "I don't know" is a real answer: ask the patient to pick the closest option rather than guessing for them.
> - Never give medical advice and never suggest a medication or a dose. An EU-licensed doctor decides those.
> - If a questionnaire returns `ineligible`, say so plainly. Do not retry with altered answers.
> - Before anything that costs money or cancels a plan, state exactly what will happen and get an explicit yes.
> - Cancellation takes effect at the **end of the paid period**, not immediately. Say so.
> - An early order is irreversible: it creates the renewal consultation immediately and uses up the period's one early order. Explain that and get an explicit yes.
> - Prescription and invoice links are medical documents. A `signed_redirect` link opens without signing in: give it only to the patient, never repeat it anywhere shared.
> - Send option `value`s, not the labels shown to the patient. Labels are translated, values are stable.
> - Never ask for card details. Payment happens on Stripe's hosted checkout via a link.
> - On severe or sudden symptoms (chest pain, difficulty breathing, severe allergic reaction, suicidal thoughts), stop and direct the patient to their local emergency number.

# Answer an information request by id

> Answers an open information request with the requested question keys and, when documents were requested, upload ids (at most 10, each used once). A request with reason_code identity_document_required is answered with identity_document (it may carry no question keys); the document is validated, stored on the patient's account in live mode and never echoed. The consultation returns to review once answered; a retry after a successful answer is refused with 409 info_request_not_open.

Checks run in this order: the request must exist (404), be open (409 info_request_not_open, also for a request withdrawn by a consent withdrawal), the patient must not have withdrawn consent (409 consent_withdrawn) and the consultation must still await information (409 case_closed). Then the body must carry at least one answer, one upload or the identity document: an empty body is refused with 422 invalid_request before identity_document_required or any other check of its contents. Requires the consultations:write scope. Same as the nested route, addressed by the request id alone.

### Access, effects and retries
**Ownership:** The API key's own partner and mode (test or live); another partner's or mode's records answer 404.

**Prerequisites:** A partner API key with the `consultations:write` scope.

**Effects:** Stores the answers, attaches the uploads and returns the consultation to review; emits a consultation webhook event.

**Retries:** A retry after a successful answer answers 409 info_request_not_open.



## OpenAPI

````yaml /api-reference/partner/openapi.json post /v1/partner/info-requests/{request_id}/answer/
openapi: 3.0.3
info:
  title: Hi Doctor Partner API
  version: '1.0'
  description: >-
    The Hi Doctor Partner API lets a partner submit online medical consultations
    for its patients, follow their clinical review, answer the doctor's
    information requests and read the resulting prescriptions. Partner requests
    use Authorization: Bearer <api key> with a partner API key; test keys and
    live keys are separate. See https://docs.hi-doctor.ai/partners/overview for
    the partner guides.
  contact:
    name: Hi Doctor
    email: hello@hi-doctor.ai
    url: https://docs.hi-doctor.ai
servers:
  - url: https://api.hi-doctor.ai
    description: Production
security: []
tags:
  - name: Connectivity
    description: Check that a key works.
  - name: Products
    description: What you can offer, where, and at what price.
  - name: Questionnaires
    description: The questions a patient answers for a product.
  - name: Files
    description: Photos and documents attached to answers.
  - name: Consultations
    description: Submit consultations and follow their review.
  - name: Patients
    description: The patients you submitted consultations for, and their consent.
  - name: Information requests
    description: Questions the doctor sends back during review.
  - name: Prescriptions
    description: Prescriptions issued after an approval.
  - name: Webhooks
    description: Receive events instead of polling.
  - name: Test mode
    description: Tools that only work with test keys.
paths:
  /v1/partner/info-requests/{request_id}/answer/:
    post:
      tags:
        - Information requests
      summary: Answer an information request by id
      description: >-
        Answers an open information request with the requested question keys
        and, when documents were requested, upload ids (at most 10, each used
        once). A request with reason_code identity_document_required is answered
        with identity_document (it may carry no question keys); the document is
        validated, stored on the patient's account in live mode and never
        echoed. The consultation returns to review once answered; a retry after
        a successful answer is refused with 409 info_request_not_open.


        Checks run in this order: the request must exist (404), be open (409
        info_request_not_open, also for a request withdrawn by a consent
        withdrawal), the patient must not have withdrawn consent (409
        consent_withdrawn) and the consultation must still await information
        (409 case_closed). Then the body must carry at least one answer, one
        upload or the identity document: an empty body is refused with 422
        invalid_request before identity_document_required or any other check of
        its contents. Requires the consultations:write scope. Same as the nested
        route, addressed by the request id alone.


        ### Access, effects and retries

        **Ownership:** The API key's own partner and mode (test or live);
        another partner's or mode's records answer 404.


        **Prerequisites:** A partner API key with the `consultations:write`
        scope.


        **Effects:** Stores the answers, attaches the uploads and returns the
        consultation to review; emits a consultation webhook event.


        **Retries:** A retry after a successful answer answers 409
        info_request_not_open.
      operationId: answer_info_request
      parameters:
        - in: path
          name: request_id
          schema:
            type: string
            format: uuid
          description: The information request id.
          required: true
          example: 2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e
        - in: query
          name: locale
          schema:
            type: string
          description: >-
            Language for the question labels: one of en, es, zh. Defaults to the
            partner's default locale; any other value falls back to English.
          example: en
        - in: header
          name: Idempotency-Key
          schema:
            type: string
            pattern: ^[A-Za-z0-9_-]{8,128}$
          description: >-
            Accepted but not used for replay on this operation. Only POST
            /v1/partner/consultations stores and replays responses by
            Idempotency-Key.
          example: b7c1d2e3f4a5b6c7
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InfoRequestAnswerRequest'
            examples:
              example-1:
                value:
                  answers:
                    - question_key: scalp_photo_top
                      value: 3d4e5f60-7182-4934-a5b6-c7d8e9f0a1b2
                  uploads: []
                summary: Illustrative request example
              example-2:
                value:
                  identity_document:
                    type: id_card
                    number: 12345678Z
                    issuing_state: ES
                summary: Illustrative request example
        required: true
      responses:
        '200':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InfoRequest'
              examples:
                example-1:
                  value:
                    id: 9c8b7a69-5847-4362-9150-4f3e2d1c0b0a
                    object: info_request
                    consultation_id: 7f8b1c2e-4d5a-4e6f-9a0b-1c2d3e4f5a6b
                    status: answered
                    reason_code: photo_quality
                    reason_label: A photo is not clear enough for a clinical review.
                    question_keys:
                      - scalp_photo_top
                    questions:
                      - key: scalp_photo_top
                        label: Photo of the top of your head
                        type: upload
                    documents_requested: []
                    requested_at: '2026-11-03T11:20:00Z'
                    answered_at: '2026-11-03T12:40:00Z'
                    withdrawn_at: null
                    answered_question_keys:
                      - scalp_photo_top
                    answer_count: 1
                    answer_document_count: 1
                  summary: Illustrative response example
          description: The answered information request.
        '400':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerError'
              examples:
                example-1:
                  value:
                    error:
                      type: invalid_request
                      code: parse_error
                      message: >-
                        JSON parse error - Expecting value: line 1 column 1
                        (char 0)
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-2:
                  value:
                    error:
                      type: invalid_request
                      code: brand_header_not_allowed
                      message: >-
                        Brand headers are not accepted on partner requests; the
                        brand comes from the API key.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
          description: >-
            The request is malformed. Partner routes also refuse the patient-app
            brand header with 400 brand_header_not_allowed, before
            authentication (no rate-limit headers).
        '401':
          headers:
            WWW-Authenticate:
              schema:
                type: string
              description: >-
                The authentication scheme to use: Bearer
                realm="hi-doctor-partner".
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerError'
              examples:
                example-1:
                  value:
                    error:
                      type: authentication_error
                      code: not_authenticated
                      message: Authentication credentials were not provided.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-2:
                  value:
                    error:
                      type: authentication_error
                      code: invalid_token
                      message: The API key is not valid.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-3:
                  value:
                    error:
                      type: authentication_error
                      code: key_revoked
                      message: The API key has been revoked.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-4:
                  value:
                    error:
                      type: authentication_error
                      code: key_expired
                      message: The API key has expired.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-5:
                  value:
                    error:
                      type: authentication_error
                      code: partner_suspended
                      message: The partner account is suspended.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
          description: >-
            The API key is missing, malformed, unknown, revoked or expired, or
            the partner account is suspended. The response carries
            WWW-Authenticate: Bearer realm="hi-doctor-partner" and no rate-limit
            headers.
        '403':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerError'
              examples:
                example-1:
                  value:
                    error:
                      type: permission_error
                      code: insufficient_scope
                      message: This endpoint requires the consultations:write scope.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-2:
                  value:
                    error:
                      type: permission_error
                      code: partner_not_live
                      message: Live mode is not enabled for this partner.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
          description: >-
            The key lacks the consultations:write scope (insufficient_scope), or
            a live key was used while live mode is not enabled for the partner
            (partner_not_live).
        '404':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/PartnerError'
                  - $ref: '#/components/schemas/PartnerFlagOffError'
              examples:
                example-1:
                  value:
                    error:
                      type: not_found
                      code: not_found
                      message: No such resource.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-2:
                  value:
                    error:
                      type: not_found
                  summary: Illustrative response example
          description: >-
            No such resource for this key's partner and mode. While the Partner
            API is switched off for the environment, every route answers 404
            with only {"error": {"type": "not_found"}}, before authentication.
        '409':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerError'
              examples:
                example-1:
                  value:
                    error:
                      type: conflict
                      code: info_request_not_open
                      message: The information request is no longer open.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-2:
                  value:
                    error:
                      type: conflict
                      code: patient_conflict
                      message: >-
                        The identity document does not match the patient's
                        account.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-3:
                  value:
                    error:
                      type: conflict
                      code: consent_withdrawn
                      message: >-
                        The patient withdrew consent; the consultation is not
                        processed.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-4:
                  value:
                    error:
                      type: conflict
                      code: case_closed
                      message: The consultation is no longer awaiting information.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-5:
                  value:
                    error:
                      type: conflict
                      code: consultation_busy
                      message: The consultation is busy; retry shortly.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
          description: >-
            The request conflicts with the information request's current state.
            A request withdrawn by a consent withdrawal is refused with
            info_request_not_open (the request's status is checked first);
            consent_withdrawn is returned only for a request still open for a
            patient who withdrew consent.
        '422':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerError'
              examples:
                example-1:
                  value:
                    error:
                      type: validation_error
                      code: unexpected_question_key
                      message: >-
                        Only the questions named in the information request may
                        be answered.
                      errors:
                        - question_key: hair_loss_pattern
                          code: unexpected_question_key
                          message: >-
                            Only the questions named in the information request
                            may be answered.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-2:
                  value:
                    error:
                      type: validation_error
                      code: identity_document_required
                      message: >-
                        The answer to this information request needs the
                        identity document.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-3:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: The request body is invalid.
                      errors:
                        - field: identity_document
                          code: invalid_identity_document
                          message: >-
                            Enter a valid document number for this document type
                            and issuing state.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-4:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: The request body is invalid.
                      errors:
                        - field: identity_document.type
                          code: invalid_choice
                          message: This is not a valid choice.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-5:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: The request body is invalid.
                      errors:
                        - field: identity_document
                          code: unexpected_field
                          message: >-
                            identity_document is accepted only on an
                            identity_document_required request.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-6:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: >-
                        Send at least one answer, one upload or the identity
                        document.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-7:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: answers must be a list of entries-v1 objects.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-8:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: uploads must be a list of upload ids.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-9:
                  value:
                    error:
                      type: validation_error
                      code: invalid_request
                      message: At most 10 uploads per answer.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-10:
                  value:
                    error:
                      type: validation_error
                      code: invalid_answers
                      message: Each question may be answered once.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-11:
                  value:
                    error:
                      type: validation_error
                      code: out_of_range
                      message: A value is outside the schema's input bounds.
                      errors:
                        - question_key: body_measurements
                          field: height
                          code: out_of_range
                          message: The value is outside the allowed range.
                          min: 100
                          max: 250
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
                example-12:
                  value:
                    error:
                      type: validation_error
                      code: upload_unusable
                      message: Each upload can be used once.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
          description: The request body is invalid.
        '429':
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Requests allowed in the current window for the most restrictive
                limit that applies. Absent on refusals made before the throttles
                run (brand header, flag off, partner_not_live).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix time, in seconds, when the window frees up.
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerError'
              examples:
                example-1:
                  value:
                    error:
                      type: rate_limited
                      code: throttled
                      message: Request was throttled. Expected available in 12 seconds.
                      request_id: req_5f0c3a9d2b7e4f18a6c1d9e3b2a7f4c8
                  summary: Illustrative response example
          description: Too many requests; wait for the number of seconds in Retry-After.
      security:
        - PartnerApiKey: []
      x-codeSamples:
        - lang: Shell
          label: curl
          source: >
            set -eu

            umask 077

            # Path values must be URL-encoded; query string excludes the leading
            question mark.

            url="${HD_BASE_URL:?Set API
            origin}/v1/partner/info-requests/${HD_PATH_REQUEST_ID:?Set the path
            fixture}/answer/${HD_QUERY_STRING:+?${HD_QUERY_STRING}}"

            printf 'Accept: application/json\n' >
            "${HD_REQUEST_HEADERS_FILE:?Private header file}"

            printf 'Authorization: Bearer %s\n' "${HD_PARTNER_API_KEY:?Set
            partner API key}" >> "$HD_REQUEST_HEADERS_FILE"

            curl --silent --show-error --max-time 30 --request POST \
              --header "@$HD_REQUEST_HEADERS_FILE" \
              --dump-header "${HD_HEADERS_FILE:?Private response header file}" \
              --output "${HD_RESPONSE_FILE:?Private response file}" \
              --write-out '%{http_code}\n%{content_type}\n' \
              --header 'Content-Type: application/json' \
              --data-binary "@${HD_REQUEST_FILE:?JSON fixture file}" \
              "$url"
        - lang: Python
          label: requests
          source: >
            import os, json

            from pathlib import Path

            from urllib.parse import quote

            import requests

            os.umask(0o077)

            url = os.environ["HD_BASE_URL"].rstrip("/") +
            '/v1/partner/info-requests/{request_id}/answer/'

            url = url.replace('{request_id}',
            quote(os.environ['HD_PATH_REQUEST_ID'], safe=""))

            if os.environ.get("HD_QUERY_STRING"): url += "?" +
            os.environ["HD_QUERY_STRING"]

            headers = {"Accept": 'application/json'}

            headers["Authorization"] = "Bearer " +
            os.environ["HD_PARTNER_API_KEY"]

            kwargs = {}

            kwargs["json"] =
            json.loads(Path(os.environ["HD_REQUEST_FILE"]).read_text())

            response = requests.request('POST', url, headers=headers,
            timeout=30, allow_redirects=False, **kwargs)

            Path(os.environ["HD_RESPONSE_FILE"]).write_bytes(response.content)

            Path(os.environ["HD_HEADERS_FILE"]).write_text(json.dumps(dict(response.headers)))

            print(response.status_code)

            print(response.headers.get("Content-Type", ""))
        - lang: JavaScript
          label: fetch
          source: >
            import { readFileSync, writeFileSync } from "node:fs";

            const env = process.env;

            let url = env.HD_BASE_URL.replace(/\/$/, "") +
            "/v1/partner/info-requests/{request_id}/answer/";

            url = url.replace("{request_id}",
            encodeURIComponent(env.HD_PATH_REQUEST_ID));

            if (env.HD_QUERY_STRING) url += "?" + env.HD_QUERY_STRING;

            const headers = { "Accept": "application/json" };

            headers.Authorization = "Bearer " + env.HD_PARTNER_API_KEY;

            const options = { method: "POST", headers, redirect: "manual",
            signal: AbortSignal.timeout(30000) };

            headers["Content-Type"] = "application/json";

            options.body = readFileSync(env.HD_REQUEST_FILE, "utf8");

            const response = await fetch(url, options);

            writeFileSync(env.HD_RESPONSE_FILE, Buffer.from(await
            response.arrayBuffer()), {mode: 0o600});

            writeFileSync(env.HD_HEADERS_FILE,
            JSON.stringify(Object.fromEntries(response.headers)), {mode:
            0o600});

            console.log(response.status);

            console.log(response.headers.get("content-type") ?? "");
components:
  schemas:
    InfoRequestAnswerRequest:
      type: object
      description: >-
        Send at least one answer, one upload or (on an
        identity_document_required request) the identity document;

        a body with none of them is refused with 422 invalid_request before the
        answer's contents are checked. null is

        the same as omitting a member; any other type is refused with 422
        invalid_request.
      properties:
        answers:
          type: array
          items:
            $ref: '#/components/schemas/InfoRequestAnswerEntry'
          nullable: true
          description: >-
            Answers for the requested question keys only; may be omitted when
            uploads or the identity document are sent. Each question may be
            answered once (otherwise 422 invalid_answers).
        uploads:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 10
          uniqueItems: true
          nullable: true
          description: >-
            upload_id values for requested documents: at most 10 (more is
            refused with 422 invalid_request). Each upload can be used once: a
            duplicate, here or between uploads and an upload answer in answers,
            is refused with 422 upload_unusable, as is an upload that does not
            exist, expired or was already used.
        identity_document:
          description: >-
            The patient's identity document. Accepted only on a request with
            reason_code identity_document_required (on any other request it is
            refused with 422 invalid_request, field identity_document, code
            unexpected_field), and required there: once the body carries an
            answer or an upload, a missing document is refused with 422
            identity_document_required (a body with no answer, upload or
            document is refused with 422 invalid_request first). Validated like
            patient.identity_document on submission: a document that breaks the
            rules (unknown issuing state, wrong check letter, number format), a
            non-object or unknown members is refused with 422 invalid_request,
            field identity_document, code invalid_identity_document; a
            structural error keeps its nested field error instead, for example
            field identity_document.type with code invalid_choice for an
            unsupported type, or identity_document.number with code required,
            blank or max_length. A document different from the one stored for
            the patient is refused with 409 patient_conflict. Never echoed or
            returned; live mode stores it on the patient's account, test mode
            stores nothing.
          anyOf:
            - $ref: '#/components/schemas/IdentityDocumentAnswer'
            - enum:
                - null
              type: string
              nullable: true
      anyOf:
        - required:
            - answers
          properties:
            answers:
              type: array
              minItems: 1
              description: At least one answer.
        - required:
            - uploads
          properties:
            uploads:
              type: array
              minItems: 1
              description: At least one upload_id.
        - required:
            - identity_document
          properties:
            identity_document:
              type: object
              description: The identity document, on an identity_document_required request.
    InfoRequest:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The information request id.
        object:
          allOf:
            - $ref: '#/components/schemas/InfoRequestObjectEnum'
          description: Always info_request.
        consultation_id:
          type: string
          format: uuid
          description: The consultation this belongs to.
        status:
          allOf:
            - $ref: '#/components/schemas/InfoRequestStatusEnum'
          description: open, answered or withdrawn.
        reason_code:
          allOf:
            - $ref: '#/components/schemas/ReasonCodeEnum'
          description: Why the doctor needs more information.
        reason_label:
          type: string
          description: Readable form of reason_code.
        question_keys:
          type: array
          items:
            type: string
          description: Question keys the doctor asked to be answered again.
        questions:
          type: array
          items:
            $ref: '#/components/schemas/InfoRequestQuestion'
          description: The questions to answer.
        documents_requested:
          type: array
          items:
            type: string
          description: >-
            Kinds of documents the doctor asked for; answer them with upload
            ids.
        requested_at:
          type: string
          format: date-time
          nullable: true
          description: When the doctor raised the request.
        answered_at:
          type: string
          format: date-time
          nullable: true
          description: When the request was answered; null while it is open.
        withdrawn_at:
          type: string
          format: date-time
          nullable: true
          description: When the request was withdrawn; null if it was not.
        answered_question_keys:
          type: array
          items:
            type: string
          description: >-
            The question keys the answer covered, in answer order; empty until
            answered. The answer values are never returned.
        answer_count:
          type: integer
          minimum: 0
          description: How many answer entries Hi Doctor accepted; 0 until answered.
        answer_document_count:
          type: integer
          minimum: 0
          description: How many files the answer attached; 0 until answered.
      required:
        - answer_count
        - answer_document_count
        - answered_at
        - answered_question_keys
        - consultation_id
        - documents_requested
        - id
        - object
        - question_keys
        - questions
        - reason_code
        - reason_label
        - requested_at
        - status
        - withdrawn_at
    PartnerError:
      type: object
      properties:
        error:
          allOf:
            - $ref: '#/components/schemas/PartnerErrorDetail'
          description: The error.
      required:
        - error
    PartnerFlagOffError:
      type: object
      description: >-
        The reduced body every route answers while the Partner API is switched
        off for the environment: no code, message or request_id.
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              enum:
                - not_found
              description: Always not_found.
          required:
            - type
          additionalProperties: false
          description: Only the error type; no code, message or request_id.
      required:
        - error
      additionalProperties: false
    InfoRequestAnswerEntry:
      type: object
      description: >-
        One entries-v1 answer: question_key plus exactly one payload, value,
        values or skip, as the question kind

        requires.
      properties:
        question_key:
          type: string
          nullable: true
          description: >-
            A key named in the information request's question_keys; any other
            key, or none, is refused with 422 unexpected_question_key. Send
            question_key, or leave it out, empty or null and send its alias key.
        value:
          description: >-
            The answer for option, confirm, upload and scalar kinds: an option
            value, a list of option values for multi kinds, true for a confirm,
            or an upload_id for an upload question.
        values:
          type: object
          additionalProperties: {}
          description: >-
            The answer for input, iief5 and likert-grid kinds: an object of
            field values, for example {"height": 172, "weight": 96}.
        skip:
          allOf:
            - $ref: '#/components/schemas/SkipEnum'
          description: >-
            true to skip an optional question (required false). A skipped entry
            carries only its locator (question_key, or on an information-request
            answer its alias key), skip and, optionally, the question's own
            step_id: value, values, option_inputs or any other member alongside
            it is refused with 422 invalid_answers.
        option_inputs:
          type: object
          additionalProperties:
            oneOf:
              - type: string
              - type: number
              - type: boolean
          description: Extra input for options that require it, keyed by option value.
        key:
          type: string
          description: >-
            Alias of question_key, accepted and normalised to question_key; used
            only when question_key is absent, empty or null, and then it must be
            a non-empty string. When question_key is set, key is ignored.
      allOf:
        - anyOf:
            - not:
                required:
                  - skip
            - properties:
                question_key:
                  description: The question key of the skipped question.
                key:
                  description: >-
                    Alias of question_key, when question_key is left out, empty
                    or null.
                step_id:
                  description: 'Optional: the skipped question''s own step_id.'
                skip:
                  description: 'true: the question is skipped.'
              additionalProperties: false
        - anyOf:
            - required:
                - question_key
              properties:
                question_key:
                  type: string
                  minLength: 1
                  pattern: \S
                  description: A non-empty question key; when set, key is ignored.
            - required:
                - key
              properties:
                key:
                  type: string
                  minLength: 1
                  pattern: \S
                  description: >-
                    A non-empty alias of question_key, used when question_key is
                    left out, empty or null.
                question_key:
                  type: string
                  nullable: true
                  enum:
                    - ''
                    - null
                  description: Left out, empty or null when the entry is located by key.
    IdentityDocumentAnswer:
      type: object
      description: >-
        An identity document in an information-request answer: only type, number
        and issuing_state; any other member is refused with 422 invalid_request,
        field identity_document, code invalid_identity_document.
      properties:
        type:
          allOf:
            - $ref: '#/components/schemas/IdentityDocumentInputTypeEnum'
          description: passport or id_card.
        number:
          type: string
          description: The document number as printed; it is normalised.
          maxLength: 50
          minLength: 1
          pattern: \S
        issuing_state:
          type: string
          description: >-
            ISO 3166-1 alpha-2 or alpha-3 code of the country that issued the
            document.
          maxLength: 3
          minLength: 1
          pattern: \S
      required:
        - issuing_state
        - number
        - type
      additionalProperties: false
    InfoRequestObjectEnum:
      enum:
        - info_request
      type: string
    InfoRequestStatusEnum:
      enum:
        - open
        - answered
        - withdrawn
      type: string
    ReasonCodeEnum:
      enum:
        - answer_unclear
        - answer_inconsistent
        - photo_quality
        - photo_missing
        - measurement_check
        - medication_history
        - medical_history
        - identity_check
        - document_missing
        - identity_document_required
        - other_clarification
      type: string
    InfoRequestQuestion:
      type: object
      properties:
        key:
          type: string
          description: The question_key to answer.
        label:
          type: string
          nullable: true
          description: >-
            The question's text in the request's locale (the locale query
            parameter, else the partner's default locale; English for an
            unsupported locale and per missing message). Display text, never a
            message key: null when no catalogue has text for it, and key still
            identifies the question.
        type:
          type: string
          description: Kind of answer expected.
      required:
        - key
        - label
        - type
    PartnerErrorDetail:
      type: object
      properties:
        type:
          allOf:
            - $ref: '#/components/schemas/PartnerErrorDetailTypeEnum'
          description: >-
            Error type, for example validation_error or rate_limited; see Errors
            in the partner guides.
        code:
          type: string
          description: A stable, machine-readable error code.
        message:
          type: string
          description: A human-readable explanation; do not parse it.
        errors:
          type: array
          items:
            $ref: '#/components/schemas/PartnerErrorItem'
          description: Field-level problems, when any.
        request_id:
          type: string
          description: Quote this identifier when you contact support.
        current:
          allOf:
            - $ref: '#/components/schemas/SchemaVersion'
          description: >-
            On 409 schema_outdated: the schema_version and schema_hash currently
            published.
        current_notice_version:
          type: string
          description: >-
            On 422 consent_notice_outdated: the patient notice version to show
            and record.
      required:
        - code
        - message
        - request_id
        - type
    SkipEnum:
      enum:
        - true
      type: boolean
    IdentityDocumentInputTypeEnum:
      enum:
        - passport
        - id_card
      type: string
    PartnerErrorDetailTypeEnum:
      enum:
        - api_error
        - authentication_error
        - conflict
        - invalid_request
        - not_found
        - permission_error
        - rate_limited
        - validation_error
      type: string
    PartnerErrorItem:
      type: object
      properties:
        field:
          type: string
          nullable: true
          description: The request field the problem refers to, or null when none.
        question_key:
          type: string
          nullable: true
          description: >-
            The questionnaire question the problem refers to, or null when the
            entry named none.
        code:
          type: string
          description: Machine-readable error code for this item.
        message:
          type: string
          description: Human-readable message. It never repeats the submitted value.
        min:
          type: number
          format: double
          description: 'On out_of_range: the lowest allowed value, when the schema sets one.'
        max:
          type: number
          format: double
          description: >-
            On out_of_range: the highest allowed value, when the schema sets
            one.
      required:
        - code
        - message
    SchemaVersion:
      type: object
      properties:
        schema_version:
          type: string
          description: The published schema_version.
        schema_hash:
          type: string
          description: A hash accepted for the published version.
      required:
        - schema_hash
        - schema_version
  securitySchemes:
    PartnerApiKey:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: >-
        Partner API key sent as Authorization: Bearer <api key>. Test keys and
        live keys are separate.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.