Subject: Compliance job data plane (upload_url / download_url) returns instant empty 404 — control plane works — pay-per-use project, client_id 33340874
Summary
On our pay-per-use project, the batch compliance control plane works (create / list / retrieve jobs all succeed), but the data plane does not: the signed upload_url and download_url returned by POST /2/compliance/jobs both return an immediate 404 with an empty body, for every job we create. This prevents us from running batch compliance at all, which is the mechanism we are required to use to honor deletions and suspensions for content we hold.
We believe this is an enrollment/provisioning gap on our project rather than expected behavior: the endpoints are documented without a tier restriction, and the same request shape from your reference client (xdevplatform/compliant-client) fails identically.
Environment
client_id: 33340874
Access: X API v2, pay-per-use
Auth: OAuth2 App-Only bearer token (the same token successfully drives filtered stream, counts, usage, and post lookup on this project)
What works (same project, same token)
POST /2/compliance/jobs → 200, returns job with signed upload_url / download_url
GET /2/compliance/jobs?type=tweets and GET /2/compliance/jobs/:id → 200
Filtered stream, /2/tweets, /2/tweets/counts/recent, /2/tweets/counts/all, /2/usage/tweets → all normal
What fails
Any request to the signed URLs. The 404 is instant (~1 ms x-response-time), with content-length: 0, which looks like the route is absent at the gateway rather than an application-level rejection.
Reproduction
# 1. Create a job — succeeds
curl -s -X POST https://api.x.com/2/compliance/jobs \
-H "Authorization: Bearer $BEARER" \
-H "Content-Type: application/json" \
-d '{"type":"tweets","name":"repro"}'
# → 200, data.upload_url = https://api.x.com/2/compliance/jobs/<id>/upload?token=<signed>
# 2. Upload IDs immediately (seconds after creation, well inside the 15-min window),
# exactly per docs and xdevplatform/compliant-client: PUT, text/plain, no auth header
curl -s -X PUT "<upload_url from step 1>" \
-H "Content-Type: text/plain" \
--data-binary @ids.txt
# → 404, empty body
# 3. The download_url 404s identically.
Evidence
#
Job ID
Type
Created (UTC)
Result
1
2092664275345223680
tweets
2026-08-26 17:23:37
upload_url PUT/POST/GET all 404, empty body
2
2092668171379769344
users
2026-08-26 17:39
upload PUT seconds after creation → 404 in 0.098 s
Sample failing response headers (job 1 upload PUT, 2026-08-26 ~17:27 UTC):
HTTP/2 404
content-length: 0
x-transaction-id: 5ab0d37b04a38ac5
x-response-time: 1
server: cloudflare envoy
x-served-by: t4_p
Variants tried, all identical 404: with and without the Authorization header, PUT/POST/GET, HTTP/2 and forced HTTP/1.1, redirects followed (-L, zero redirects observed), fresh job with upload issued within seconds of creation, both tweets and users job types.
Impact
We hold post IDs obtained through the filtered stream and are building deletion/suspension handling on batch compliance jobs, per the Developer Agreement’s requirement to keep stored content current. With the data plane unreachable, this project has no working compliance mechanism: the compliance stream is Enterprise-only, and per-ID re-lookup through /2/tweets is billed per read, which is not viable as a compliance sweep.
Request
Please provision (or repair) the compliance jobs upload/download data-plane routes for our project, or advise if batch compliance requires an enrollment step on pay-per-use that is not covered in the documentation.
Happy to run any diagnostic you need — we can reproduce this on demand within minutes.
2 posts - 2 participants
Read full topic
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | OAuth 2.0 regression / authorization rejects numeric-only state values | 0 | 9.79 | 27-08-2026 |
| 2 | X API v2 returns HTTP 500 with empty response body across multiple endpoints | 0 | 8.24 | 27-08-2026 |
| 3 | Pay-Per-Use app: OAuth 1.0a user context returns 401 on both GET and POST v2 endpoints | 0 | 10.43 | 27-08-2026 |
| 4 | POST accounts/:account_id/media_library consistently returning 503 SERVICE_UNAVAILABLE since 2026-08-27 23:03 UTC | 0 | 14.1 | 28-08-2026 |
| 5 | API authorization issue OAuth2 | 0 | 8.78 | 28-08-2026 |
| 6 | OAuth 2.0/authorize fails with 'Something went wrong' on Pay Per Use tier. Al settings verified: billing, enrollment, callback, credentials | 0 | 7.65 | 30-08-2026 |
| 7 | OAuth 2.0 PKCE authorization fails after user approval before callback | 0 | 7.24 | 28-08-2026 |
| 8 | Ads API 403 and App Manager cannot resolve JTP iOS and Android identifiers | 0 | 7.88 | 28-08-2026 |
| 9 | App Suspended (28881659) but Account in Good Standing, can still post | 0 | 8.99 | 27-08-2026 |