We just added Twitter native video into SnapStream (more on this here). For posterity, we documented our experiences and suggestions for improvement (feedback from Jason Baumeister):
The documentation is spread out.
The link above contains very little in the way of actual details (note it doesn't even say what the JSON returned by INIT or FINALIZE is or even mention what the calls return/do in error cases), because they want you to go here:
but while that has more details in some areas it has less details in others (and still no error case documentation).
The examples are all given using the twurl tool, which has shortcuts like '--file-field "media"' so then you get to work backwards from the examples through the documentation to try and figure out what they actually want. If the examples were the raw multipart requests, the spec would be much easier to directly implement. Having to get their tool running and trace the headers that way is extremely roundabout for a simple example for someone to build off of.
The error messages during this process are vague. A poorly crafted multipart request gets things like a "media not found" error.
If twitter doesn't like the video you upload, the upload itself looks to work fine, but you get a "The validation of media ids failed." error when you try to actually post a tweet with the media id linked. If the FINALIZE command could actually validate the file and return an error message (and that error message actually indicated what the problem was) things would be a lot cleaner.
I believe they require MOOV before MDAT (aka MP4 FastStart) files, but the listed video specs don't indicate this (or I have had a file be flagged as invalid for another reason I can't track down).
Documentation for the multipart uploads says the Content-Type header is required on the multipart boundary with the file data, but in practice it seems to be completely optional?
Here's some simple C# code on GitHub that uses the Twitter REST API to upload a native video:
(There are probably a few more things noted in comments in the github commit)