Issue
The migration from the deprecated X API v1.1 media upload endpoint (/1.1/media/upload.json) to the newer v2 endpoint (/2/media/upload) resulted in consistent 400 Bad Request errors during testing. The uploader failed to initialize media uploads despite successful authentication, while the legacy v1.1 endpoint continued to work. The issue stemmed from incompatible response formats between v1.1 (flat JSON) and v2 (wrapped data object), causing parsing failures in initialization, finalization, and status polling methods.
Culprit
Hardcoded Legacy Endpoint
The system was hardcoded to use the deprecated v1.1 endpoint, which expects a flat JSON response structure (media_id_string at the root level). In contrast, v2 wraps all responses in a data object, causing parsing failures.
Incompatible Response Parsing
Three critical parsing methods in the system were hardcoded to assume the v1.1 response structure, failing when attempting to parse v2 responses:
_init_uploadexpectedmedia_id_stringat the root level._finalize_uploaddirectly accessedprocessing_infowithout unwrapping thedataobject.- Status polling methods used unwrap-free JSON access, leading to parsing errors.
Authentication Assumptions
The legacy implementation assumed compatibility with OAuth 1.0a, but the v2 endpoint may require additional authentication headers or parameters that were not included in the initial migration.
Solution
Endpoint Migration
Updated the base URL to the v2 endpoint while maintaining backward compatibility to ensure existing functionality remains intact.
Dual-Format Response Handling
Modified all parsing methods to handle both v1.1 and v2 response formats:
- Initialization: Modified to extract
media_idfrom eitherdata.get('data', {}).get('id')ordata.get('media_id_string'). - Finalization: Updated to handle both wrapped and unwrapped responses by extracting
processing_infofrom eitherresponse.json().get('data', response.json()). - Status Polling: Modified to unwrap responses or use the flat structure, ensuring compatibility with both API versions.
Authentication
Retained OAuth 1.0a for backward compatibility, with plans to evaluate Bearer token authentication for potential future optimization with the v2 endpoint.
Reversion Decision
Due to persistent 400 Bad Request errors from the v2 endpoint, the solution was reverted to continue using v1.1 for media uploads while leveraging v2 for other functionalities, such as tweet creation (POST /2/tweets). This ensures stable media uploads while allowing for future migration attempts once the v2 endpoint is fully stabilized and documented.