GET /activitystreams
Returns ActivityStreams 2.0 / ActivityPub objects with spec violations. Default omits the required @context. Use ?mode= to isolate other violations: a type outside the AS2 vocabulary, a non-URI actor, or an object whose shape doesn't match its activity type. Consumed by Mastodon, Misskey, and other Fediverse servers during federation.
mode
context-missing (default; @context absent; ActivityPub §3.1 requires it; servers reject or fail to expand JSON-LD terms), type-not-vocabulary (`type` is "ChaosPost", not in AS2; servers that validate type drop the activity, those that forward propagate the invalid object), actor-not-uri (`actor` is a bare string; ActivityPub §4.1 requires a dereferenceable URI; key verification fetches fail), object-shape-variance (Like activity with `object` as a bare string instead of a URI or embedded object; servers that dereference get a parse error).
control Compare against the well-formed counterpart: not.catastrophic.io/activitystreams side-by-side
build a request:
expect: An ActivityStreams 2.0 object served as application/activity+json with one spec violation. The `note` field in the body explains what is wrong.
curl -si 'https://chaos.catastrophic.io/activitystreams?mode=context-missing' | grep -E '^(HTTP|content-type|x-chaos)'
import urllib.request, json
resp = urllib.request.urlopen("https://chaos.catastrophic.io/activitystreams?mode=context-missing")
print("Content-Type:", resp.headers.get("Content-Type"))
print("X-Chaos-Activitystreams-Mode:", resp.headers.get("X-Chaos-Activitystreams-Mode"))
body = json.loads(resp.read())
print("@context present:", "@context" in body)
print("type:", body.get("type"))
print("actor:", body.get("actor"))
print("note:", body.get("note"))
const res = await fetch("https://chaos.catastrophic.io/activitystreams?mode=context-missing");
const body = await res.json();
console.log("Content-Type:", res.headers.get("content-type"));
console.log("X-Chaos-Activitystreams-Mode:", res.headers.get("x-chaos-activitystreams-mode"));
console.log("@context present:", "@context" in body);
console.log("type:", body.type);
console.log("actor:", body.actor);
console.log("note:", body.note);
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
resp, _ := http.Get("https://chaos.catastrophic.io/activitystreams?mode=context-missing")
defer resp.Body.Close()
raw, _ := io.ReadAll(resp.Body)
var body map[string]any
json.Unmarshal(raw, &body)
fmt.Println("Content-Type:", resp.Header.Get("Content-Type"))
fmt.Println("X-Chaos-Activitystreams-Mode:", resp.Header.Get("X-Chaos-Activitystreams-Mode"))
_, hasCtx := body["@context"]
fmt.Println("@context present:", hasCtx)
fmt.Printf("type: %v\n", body["type"])
fmt.Printf("actor: %v\n", body["actor"])
}
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
fn main() -> Result<(), Box> {
let resp = reqwest::blocking::get("https://chaos.catastrophic.io/activitystreams?mode=context-missing")?;
println!("Content-Type: {:?}", resp.headers().get("content-type"));
println!("X-Chaos-Activitystreams-Mode: {:?}", resp.headers().get("x-chaos-activitystreams-mode"));
let body: serde_json::Value = resp.json()?;
println!("@context present: {}", body.get("@context").is_some());
println!("type: {:?}", body.get("type"));
println!("actor: {:?}", body.get("actor"));
Ok(())
}
import java.net.URI;
import java.net.http.*;
public class ActivityStreamsChaos {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://chaos.catastrophic.io/activitystreams?mode=context-missing")).build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("Content-Type: " +
resp.headers().firstValue("Content-Type").orElse(""));
System.out.println("X-Chaos-Activitystreams-Mode: " +
resp.headers().firstValue("X-Chaos-Activitystreams-Mode").orElse(""));
System.out.println("Body: " + resp.body());
}
}
using var client = new HttpClient();
var resp = await client.GetAsync("https://chaos.catastrophic.io/activitystreams?mode=context-missing");
Console.WriteLine($"Content-Type: {resp.Content.Headers.ContentType}");
Console.WriteLine($"X-Chaos-Activitystreams-Mode: " +
$"{resp.Headers.GetValues("X-Chaos-Activitystreams-Mode").FirstOrDefault()}");
var body = await resp.Content.ReadAsStringAsync();
Console.WriteLine($"Body: {body}");
require "net/http"
require "json"
uri = URI("https://chaos.catastrophic.io/activitystreams?mode=context-missing")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
res = http.get(uri.request_uri)
puts "Content-Type: #{res['Content-Type']}"
puts "X-Chaos-Activitystreams-Mode: #{res['X-Chaos-Activitystreams-Mode']}"
body = JSON.parse(res.body)
puts "@context present: #{body.key?('@context')}"
puts "type: #{body['type']}"
puts "actor: #{body['actor']}"
end
$r = Invoke-RestMethod -Uri 'https://chaos.catastrophic.io/activitystreams?mode=context-missing' -ResponseHeadersVariable h
"Content-Type: $($h['Content-Type'])"
"X-Chaos-Activitystreams-Mode: $($h['X-Chaos-Activitystreams-Mode'])"
"@context present: $($r.PSObject.Properties['@context'] -ne $null)"
"type: $($r.type)"
"actor: $($r.actor)"
headers
body