Question: The new square api versions 42+ have breaking changes. Im trying to upgrade to ver v42, and I am testing in a local dev environment. I keep getting the following error: *** square.core.api_error.ApiError: status_code: 400, body: {'errors': [{'category': 'INVALID_REQUEST_ERROR', 'code': 'INVALID_CONTENT_TYPE', 'detail': 'Received multiple request parts. Please only supply zero or one `parts` of type application/json.'}]} when I try to upload an approx ~800 byte jpeg [very grainy] in the development sandbox for Square Invoice API using the following code: pdf_filepath = 'local/path/to/file.jpg' idem_key = 'some-unique_key_like_square_invoice_id' f_stream = open(pdf_filepath, "rb") try: # I have tried using a stream as well, still the same error invoice_pdf = SQUARE_CLIENT.invoices.create_invoice_attachment( invoice_id=square_original_invoice.id, # this also does not work # image_file=f_stream, image_file=pdf_filepath, request={ "description": f"Invoice-{pdf_filepath}", "idempotency_key": idem_key, }, ) except ApiError as e: print(f"ERROR _attach_pdf_to_vendor_payment with errors {e}")  In the online sandbox API, I get the 400 Response error: // cache-control: no-cache // content-type: application/json // date: Wed, 30 Apr 2025 13:35:06 GMT // square-version: 2025-04-16 { "errors": [ { "code": "BAD_REQUEST", "detail": "Total size of all attachments exceeds Sandbox limit: 1000 bytes", "category": "INVALID_REQUEST_ERROR" } ] }  Once I got a 900 byte jpg to upload in the API explorer (988 byte did not pass), but the SDK still errors using the same file. Here is a successful API request upload VIA the API Explorer: content-length: 1267 content-type: multipart/form-data; boundary=----WebKitFormBoundaryUUID38 square-version: 2025-04-16 user-agent: SquareExplorerGateway/1.0 SquareProperty ApiExplorer ------WebKitFormBoundaryUUID38 Content-Disposition: form-data;name="request" { "idempotency_key": "UUID-123-456-7869" } ------WebKitFormBoundaryUUID38 Content-Disposition: form-data;name="file";filename="900b.jpeg" Content-Type: image/jpeg ����  Here is the unsuccessful API request via my django server, using the same file: content-length: 568 content-type: multipart/form-data; boundary=djangoUUID square-version: 2025-04-16 accept-encoding: gzip accept: */* user-agent: squareup/42.0.0.20250416 --djangoUUID Content-Disposition: form-data;name="request" Content-Type: application/json;charset=utf-8 { "description": "Invoice-path/to/file/900b.jpeg", "idempotency_key": "path/to/original/file/normal-invoice.pdf" } --djangoUUID Content-Disposition: form-data;name="image_file" Content-Type: image/jpeg /path/to/file/900b.jpeg --djangoUUID--  Note the successful request : Content-Disposition: form-data;name="file";filename="900b.jpeg" Content-Type: image/jpeg and the unsuccessful request: Content-Disposition: form-data;name="request" Content-Type: application/json;charset=utf-8 Content-Disposition: form-data;name="image_file" Content-Type: image/jpeg` specifically: name="image_file" vs name="file" and application/json;charset=utf-8 The headers for the unsuccessful API call are: { "date": "Sat, 03 May 2025 22:47:34 GMT", "content-type": "application/json", "transfer-encoding": "chunked", "connection": "keep-alive", "cf-ray": "ab-…-WER", "cf-cache-status": "DYNAMIC", "cache-control": "no-cache", "strict-transport-security": "max-age=631152000; includeSubDomains; preload", "x-envoy-decorator-operation": "/v2/invoices/**", "x-request-id": "58-…-80", "x-sq-dc": "aws", "x-sq-istio-migration-ingress-proxy": "sq-envoy", "x-sq-istio-migration-ingress-region": "us-west-2", "x-sq-region": "us-west-2", "vary": "Accept-Encoding", "server": "cloudflare" }  The headers from the browser network inspector: :authority explorer-gateway.squareup.com :method POST :path /v2/invoices/inv:0-Ch…wI/attachments :scheme https accept application/json accept-encoding. gzip, deflate, br, zstd accept-language. en-US,en;q=0.9 authorization Bearer AE…ju cache-control no-cache content-length 1250 content-type. multipart/form-data; boundary=----WebKitFormBoundaryCP3GAXwMvwBUTlwU origin https://developer.squareup.com pragma no-cache priority u=1, i referer https://developer.squareup.com/ sandbox-mode true sec-ch-ua "Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99" sec-ch-ua-mobile ?0 sec-ch-ua-platform "macOS" sec-fetch-dest empty sec-fetch-mode cors sec-fetch-site same-site square-version 2025-04-16 user-agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 x-square-property. ApiExplorer  Notes: Here is the test image To try and send zero parts, if I do an API call without a request parameter: invoice_pdf = SQUARE_CLIENT.invoices.create_invoice_attachment( invoice_id=self.square_original_invoice.id, image_file=pdf_filepath, )  I get a response of INVALID_REQUEST_ERROR BAD_REQUEST Bad request. If I do an API call with an empty request parameter: invoice_pdf = SQUARE_CLIENT.invoices.create_invoice_attachment( invoice_id=self.square_original_invoice.id, image_file=pdf_filepath, request={}, )  I get the same error INVALID_REQUEST_ERROR INVALID_CONTENT_TYPE Received multiple request parts. Please only supply zero or one parts of type application/json. I do remember the parameter name (file vs image_file) image being an issue with outdated docs, but the current docs show the newer parameter of image_file being correct Related Docs https://developer.squareup.com/docs/invoices-api/attachments This worked fine in the old pre 42 API, with minor syntax change, and I know the limit is now imposed to have a 1000 byte limit for the attachment, but why can't I upload attachments in the sandbox now? Square's internal developer forum link : https://developer.squareup.com/forums/t/new-api-for-invoice-attachments-error-received-multiple-request-parts-please-only-supply-zero-or-one-parts-of-type-application-json/22126

Answer: Docs should read something like this: Uploads a file and attaches it to an invoice. This endpoint accepts HTTP multipart/form-data file uploads with a JSON request part and a image_file part. The image_file part must INCLUDE a readable stream in the form of a file (or bytes) [supported formats: GIF, JPEG, PNG, TIFF, BMP, or PDF.], and optionally filename, content_type, headers. See core.File for additional details related to the image_file Final working code: f_stream = open(attachment_filepath, "rb") mime_type, encoding = mimetypes.guess_type(attachment_filepath) invoice_pdf = SQUARE_CLIENT.invoices.create_invoice_attachment( invoice_id=self.square_original_invoice.id, image_file=( attachment_filepath, attachment_filepath, #can also be f_stream mime_type, ), request={ "idempotency_key": idem_key, "description": f"Invoice-{attachment_filepath}", }, )