File attachments are quite odd at first glance - they don’t seem similar to any other part of our API because they are a multi-part upload. This is in fact standard across most APIs (I arbitrarily found Google Drive’s docs on multipart uploads as an example), but it’s possible that you might have been isolated in the past from the details of how this is done using various client-side tools - for instance, cURL makes it pretty easy (as in our examples), but cURL is doing the same thing for you that you can do manually for any multipart upload.
I’ll draw your attention to the example shown in our docs, snipping out the important parts:
Content-Type: multipart/form-data; boundary=<UNIQUE_BOUNDARY>
Body of the request:
Content-Disposition: form-data; name="file"; filename="example.txt"
So you set HTTP headers to have
Content-Type: multipart/form-data; boundary=<UNIQUE_BOUNDARY> and the size of the request content with
Then (this is where things can get confusing) in the body of the request, start with
-- and the boundary you specified in the HTTP header and a CR/LF carriage return.
Then there are header-like entries that you include for the metadata of each file. These are not HTTP headers, but are in the body of the request itself. They tell the server information about the file you’re sending.
Between these headers and the start of the file are two CR/LF carriage returns.
Next comes the bytes that constitute the file itself, then a CR/LF carriage return.
--, the boundary again, and
All of this is, confusingly, a pretty standard way to support the ability to upload files to a server. If you have experienced file uploads that behave differently, I’d wager that you were using a tool or library that abstracted those nitty-gritty details into a friendlier interface.
To that end, I think what your PHP code looks like will largely depend on what tools you’re using to do the upload - if it’s our client library, I believe this basic logic starts to be handled here
Sorry this is confusing, and good luck!