Request bin
A request bin is a URL that records everything sent to it. Point a webhook sender, a gateway's HTTP logging plugin, a mirroring policy or a callback at it, then inspect what arrived.
| Route | Purpose |
|---|---|
POST /bin | Create a bin (201) and get its URLs |
GET /bin | List the bins owned by your session |
ANY /bin/{id} and ANY /bin/{id}/{*path} | Capture a request (except DELETE /bin/{id}, which deletes the bin) |
GET /bin/{id}/requests | Captured requests, newest first (?limit=, default 50) |
GET /bin/{id}/requests/{n} | One request by sequence number |
GET /bin/{id}/requests/stream | Live feed (Server-Sent Events) |
Creating a bin
The optional JSON body configures what the bin answers: status, headers
(name to value), body (a string, or JSON which is serialised and labelled
application/json) and delay_ms (capped by the instance delay limit). Without a
body the bin answers 200 with {"ok": true, "bin": ..., "id": ..., "seq": n}.
Every capture response carries X-Rustybin-Bin-Seq.
The bin belongs to the creating session (X-Rustybin-Session, else the client IP),
which is what GET /bin lists; anyone who knows the id can send to it, read it or
delete it.
POST {{base_url}}/bin
X-Rustybin-Session: docs-bin
Content-Type: application/json
{"status": 202, "headers": {"X-Bin": "demo"}, "body": {"accepted": true}, "delay_ms": 100}
HTTP 201
[Captures]
bin_id: jsonpath "$.id"
[Asserts]
jsonpath "$.url" == "{{base_url}}/bin/{{bin_id}}"
jsonpath "$.requests_url" endsWith "/requests"
jsonpath "$.stream_url" endsWith "/requests/stream"
jsonpath "$.response.status" == 202
jsonpath "$.limits.max_requests" == 100
Capturing and inspecting
Each capture records the method, the path below the bin (path) and the full path,
query, headers, client IP, timestamp and the body (up to 64 KiB, as text or
body_base64). The inspection routes are never captured themselves.
# Point a webhook (or a gateway's logging plugin) at any sub path of the bin.
POST {{base_url}}/bin/{{bin_id}}/hooks/orders?attempt=1
Content-Type: application/json
X-Gateway-Consumer: alice
{"event": "order.created"}
HTTP 202
[Asserts]
header "X-Bin" == "demo"
header "X-Rustybin-Bin-Seq" == "1"
jsonpath "$.accepted" == true
duration >= 100
GET {{base_url}}/bin/{{bin_id}}/requests
HTTP 200
[Asserts]
jsonpath "$.count" == 1
jsonpath "$.requests[0].method" == "POST"
jsonpath "$.requests[0].path" == "/hooks/orders"
jsonpath "$.requests[0].query" == "attempt=1"
jsonpath "$.requests[0].body" == "{\"event\": \"order.created\"}"
jsonpath "$.requests[0].headers[?(@.name == 'x-gateway-consumer')].value" nth 0 == "alice"
GET {{base_url}}/bin/{{bin_id}}/requests/1
HTTP 200
[Asserts]
jsonpath "$.seq" == 1
jsonpath "$.full_path" == "/bin/{{bin_id}}/hooks/orders"
GET {{base_url}}/bin
X-Rustybin-Session: docs-bin
HTTP 200
[Asserts]
jsonpath "$.bins[*].id" contains "{{bin_id}}"
POST {{base_url}}/bin
HTTP 201
[Captures]
plain_bin: jsonpath "$.id"
PUT {{base_url}}/bin/{{plain_bin}}
`anything at all`
HTTP 200
[Asserts]
jsonpath "$.ok" == true
jsonpath "$.seq" == 1
The live feed sends one request event per capture with the sequence number as
event id; Last-Event-ID replays the stored requests after that number. It ends
when the bin expires or is deleted (the example stops reading after two seconds):
curl -sN --max-time 2 "$BASE/bin/$bin/requests/stream"
To capture a DELETE, send it to a sub path: DELETE /bin/{id} deletes the bin.
DELETE {{base_url}}/bin/{{bin_id}}
HTTP 200
GET {{base_url}}/bin/{{bin_id}}/requests
HTTP 404
Limits
| Normal | Public mode | |
|---|---|---|
| Bins | 200 | 100 (10 per session) |
| Requests kept per bin | 100 | 50 |
| Stored bytes per bin | 1 MiB | 256 KiB |
| Lifetime | 24 hours | 1 hour |
| Captured body | 64 KiB | 64 KiB |
The oldest requests are evicted first when a bin is full.