http.placeholder.com
HTTP test endpoints
An endpoint for every HTTP behaviour your client has to handle: echo the request, return any status code, redirect, ask for credentials, set cookies, answer conditional requests, stall, trickle, stream and serve byte ranges. httpbin-compatible where it makes sense, and safe to point at from anywhere.
curl 'https://http.placeholder.com/get?foo=bar'
curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' https://http.placeholder.com/post
curl -i https://http.placeholder.com/status/503
curl -L https://http.placeholder.com/redirect/3
The index at https://http.placeholder.com/ lists every endpoint, with an example and the limits, as JSON.
Inspect the request
| Endpoint | Methods | Returns |
|---|---|---|
/get | GET | Query args, headers, origin IP and url |
/post, /put, /patch, /delete | that method | The same plus the body: data, form, files, json |
/anything[/any/path] | any | Echo of any method and path, always JSON |
/headers, /ip, /user-agent | GET | Just that part |
/uuid | GET | A random UUID4 |
https://http.placeholder.com/get?foo=bar{"args": {"foo": "bar"}, "headers": {…}, "origin": "…", "url": "…"}https://http.placeholder.com/anything/a/b?x=1any method, any pathhttps://http.placeholder.com/headerswhat your client actually sent
Status codes
https://http.placeholder.com/status/404any code from 200 to 599, with a small JSON bodyhttps://http.placeholder.com/status/418I'm a teapothttps://http.placeholder.com/status/200,500one of them at randomhttps://http.placeholder.com/status/200:0.9,500:0.1?seed=42weighted: 90% success;seedmakes the pick repeatable
Accepts GET, POST, PUT, PATCH and DELETE. Redirect codes come with Location, 401 and 407 with an auth challenge, 429 and 503 with Retry-After: 1; 204, 205 and 304 have no body. Up to 20 codes per list.
Redirects
https://http.placeholder.com/redirect/3three hops, then/get(1 to 20;?absolute=truefor absolute URLs)https://http.placeholder.com/relative-redirect/3relativeLocationheadershttps://http.placeholder.com/absolute-redirect/3absoluteLocationheadershttps://http.placeholder.com/redirect-to?url=/get&status_code=307a chosen target and code (301, 302, 303, 307, 308)
/redirect-to only goes to relative paths or http.placeholder.com itself. It is not an open redirect: other hosts are a 400.
Auth and cookies
https://http.placeholder.com/basic-auth/user/passwdBasic auth with the credentials in the URL; 401 with a challenge until you send themhttps://http.placeholder.com/hidden-basic-auth/user/passwdthe same, but 404 instead of 401https://http.placeholder.com/bearerneedsAuthorization: Bearer <anything>, echoes the tokenhttps://http.placeholder.com/cookiesthe cookies you senthttps://http.placeholder.com/cookies/set?flavour=oatsets cookies, then redirects to/cookies(also/cookies/set/flavour/oat)https://http.placeholder.com/cookies/delete?flavourexpires them
curl -u user:passwd https://http.placeholder.com/basic-auth/user/passwd
curl -H 'Authorization: Bearer test-token' https://http.placeholder.com/bearer
Cookies are host-only, at most 5 per request, values up to 128 characters; names starting with __Host-, __Secure- or cf are refused.
Caching
https://http.placeholder.com/cache304 when you sendIf-Modified-SinceorIf-None-Matchhttps://http.placeholder.com/cache/60Cache-Control: public, max-age=60(0 to 86400)https://http.placeholder.com/etag/abc123ETag;If-None-Matchgives 304, a failingIf-Match412
Slow, streamed and partial responses
https://http.placeholder.com/delay/2waits 2 s, then echoes (up to 10 s; GET and body methods)https://http.placeholder.com/drip?duration=3&numbytes=3030 bytes trickled over 3 s; alsocode=anddelay=https://http.placeholder.com/sse?count=5&interval=1server-sent events, then anendeventhttps://http.placeholder.com/stream/55 lines of NDJSONhttps://http.placeholder.com/bytes/1024?seed=1random bytes; the same with the same seedhttps://http.placeholder.com/stream-bytes/4096?chunk_size=512random bytes, chunkedhttps://http.placeholder.com/range/10241024 bytes that answer aRangeheader with 206 or 416
curl -H 'Range: bytes=0-99' -i https://http.placeholder.com/range/1024
curl -N 'https://http.placeholder.com/sse?count=5&interval=1'
Formats and encodings
https://http.placeholder.com/gzipgzip-encoded JSON (also/deflate,/brotli)https://http.placeholder.com/jsona sample JSON document (also/xml,/html)https://http.placeholder.com/encoding/utf8UTF-8 sample texthttps://http.placeholder.com/robots.txta robots.txt that disallows everything but the index, including/denyhttps://http.placeholder.com/response-headers?X-Test=1&Server-Timing=db;dur=53headers of your choice, from an allowlist
/response-headers adds up to 10 headers: X- headers and a few harmless standard ones (ETag, Last-Modified, Retry-After, Server-Timing, Content-Language, Warning, Allow, Accept-Ranges). Never Content-Type, Location, Set-Cookie or security headers.
Limits
| What | Limit |
|---|---|
| Request body echoed | 1 MB, 100 fields, JSON nesting 64 |
/delay | 10 s |
| Redirect hops | 20 |
/bytes, /stream-bytes | 10 MB |
/stream | 100 lines |
/range | 100 KB |
/drip | 10 KB over at most 10 s |
/sse | 100 events, interval up to 5 s, 60 s in total |
Out-of-range values are a 400 with a JSON error, never silently clamped. Errors look like {"error": "…", "status": 400}. When the server is saturated with slow requests it answers 503 with Retry-After: 5.
Safe by design
- Echo output is always JSON. No HTML and no content type is ever taken from your request, so the host can't be used to serve someone else's page.
- Responses are
Cache-Control: no-store, except/cache,/cache/{n}and/etag/{etag}. - CORS is open (
Access-Control-Allow-Origin: *, all headers exposed, no credentials), and preflight works for every path. - Nothing is stored and request contents are not logged. Every response has
X-Placeholder: http.placeholder.com.