def METHOD_NAME(
    self,
    method,
    endpoint="",
    params=None,
    headers=None,
    json=None,
):
    method = method.upper()
    if method not in ("GET", "POST"):
        frappe.throw(_("Invalid method {0}").format(method))
    request_args = frappe._dict(
        url=self.get_url(endpoint),
        params=params,
        headers={
            # auto-generated hash, required by some endpoints
            "requestid": self.generate_request_id(),
            **self.default_headers,
            **(headers or {}),
        },
    )
    log_headers = request_args.headers.copy()
    # Mask sensitive headers
    for header in self.SENSITIVE_HEADERS:
        if header in log_headers:
            log_headers[header] = "*****"
    log = frappe._dict(
        **self.default_log_values,
        url=request_args.url,
        data=request_args.params,
        request_headers=log_headers,
    )
    if method == "POST" and json:
        request_args.json = json
        if not request_args.params:
            log.data = json
        else:
            log.data = {
                "params": request_args.params,
                "body": json,
            }
    response_json = None
    try:
        response = requests.request(method, **request_args)
        if api_request_id := response.headers.get("x-amzn-RequestId"):
            log.request_id = api_request_id
        try:
            response_json = response.json(object_hook=frappe._dict)
        except Exception:
            pass
        # Raise special error for certain HTTP codes
        self.handle_http_code(response.status_code, response_json)
        # Raise HTTPError for other HTTP codes
        response.raise_for_status()
        # Expect all successful responses to be JSON
        if not response_json:
            frappe.throw(_("Error parsing response: {0}").format(response.content))
        else:
            self.response = response_json
        # All error responses have a success key set to false
        success_value = response_json.get("success", True)
        if isinstance(success_value, str):
            success_value = sbool(success_value)
        if not success_value and not self.handle_failed_response(response_json):
            frappe.throw(
                response_json.get("message")
                # Fallback to response body if message is not present
                or frappe.as_json(response_json, indent=4),
                title=_("API Request Failed"),
            )
        return response_json.get("result", response_json)
    except Exception as e:
        log.error = str(e)
        raise e
    finally:
        log.output = response_json
        enqueue_integration_request(**log)
        if self.sandbox_mode and not frappe.flags.ic_sandbox_message_shown:
            frappe.msgprint(
                _("GST API request was made in Sandbox Mode"),
                alert=True,
            )
            frappe.flags.ic_sandbox_message_shown = True