{
  "slug": "api-enumeration",
  "title": "API Enumeration & Documentation Discovery",
  "phase": "Enumeration",
  "description": "Discover and map REST, GraphQL, and WebSocket APIs — find undocumented endpoints, authentication schemes, rate limits, and data schemas.",
  "difficulty": "medium",
  "tags": [
    "enumeration",
    "api",
    "graphql",
    "rest",
    "documentation"
  ],
  "tools": [
    "Postman",
    "graphql-voyager",
    "ffuf",
    "nuclei",
    "Burp Suite"
  ],
  "steps": [
    {
      "id": "apienum-01",
      "title": "Discover Swagger and OpenAPI documentation",
      "description": "Probe common paths for exposed API documentation files that reveal every endpoint, parameter, and data model.",
      "commands": [
        "ffuf -u https://target.com/FUZZ -w /usr/share/seclists/Discovery/Web-Content/api/api-docs.txt -mc 200 -o api-docs-fuzz.json",
        "curl -sk https://target.com/swagger.json | jq '.paths | keys'",
        "curl -sk https://target.com/api-docs",
        "curl -sk https://target.com/openapi.json | jq '.paths | keys'",
        "nuclei -u https://target.com -t exposures/apis/ -o api-docs-found.txt"
      ],
      "notes": "Check for documentation at /swagger.json, /swagger-ui.html, /api-docs, /openapi.json, /v2/api-docs, and /v3/api-docs. Even when the UI is disabled, the JSON spec is often still served."
    },
    {
      "id": "apienum-02",
      "title": "Scan for GraphQL introspection",
      "description": "Test for enabled GraphQL introspection to extract the full API schema including types, queries, mutations, and field definitions.",
      "commands": [
        "curl -sk -X POST https://target.com/graphql -H 'Content-Type: application/json' -d '{\"query\":\"{__schema{types{name,fields{name,args{name,type{name}}}}}}}\"}'",
        "curl -sk -X POST https://target.com/api/graphql -H 'Content-Type: application/json' -d '{\"query\":\"query{__schema{queryType{fields{name description}}}}\"}'",
        "nuclei -u https://target.com -t technologies/graphql-detect.yaml -o graphql-found.txt"
      ],
      "notes": "If introspection is disabled, try field suggestion attacks — send partial queries and observe error messages that leak field names."
    },
    {
      "id": "apienum-03",
      "title": "Discover WADL and WSDL service descriptions",
      "description": "Check for SOAP and legacy REST service descriptions that expose operations, data types, and endpoint bindings.",
      "commands": [
        "curl -sk https://target.com/application.wadl",
        "curl -sk 'https://target.com/ws/service?wsdl'",
        "ffuf -u 'https://target.com/FUZZ' -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt -mc 200 -o wadl-wsdl.json",
        "curl -sk https://target.com/services/ | grep -iE '(wsdl|wadl|asmx|svc)'"
      ],
      "notes": "WSDL files are common in enterprise environments running Java and .NET backends. They fully describe the service contract — treat them as complete API documentation."
    },
    {
      "id": "apienum-04",
      "title": "Enumerate API versioning and deprecated endpoints",
      "description": "Map all API versions to find deprecated endpoints that may lack current security controls.",
      "commands": [
        "ffuf -u 'https://target.com/api/FUZZ/users' -w <(seq 1 20 | sed 's/^/v/') -mc 200,301,403 -o api-versions.json",
        "curl -sk https://target.com/api/v1/users -o /dev/null -w '%{http_code}'",
        "curl -sk https://target.com/api/v2/users -o /dev/null -w '%{http_code}'",
        "curl -sk -H 'Accept: application/vnd.target.v1+json' https://target.com/api/users"
      ],
      "notes": "Deprecated API versions often lack rate limiting, input validation, and authorisation checks that were added in newer versions. Always test the oldest available version."
    },
    {
      "id": "apienum-05",
      "title": "Test rate limiting and throttling",
      "description": "Determine rate limit thresholds on API endpoints to identify brute-force opportunities and denial of service risks.",
      "commands": [
        "for i in $(seq 1 100); do curl -sk -o /dev/null -w '%{http_code} ' https://target.com/api/users; done",
        "ffuf -u https://target.com/api/login -X POST -d 'user=admin&pass=FUZZ' -w /usr/share/wordlists/rockyou.txt -mc 200 -rate 10",
        "curl -sk -I https://target.com/api/users | grep -iE '(x-rate|x-ratelimit|retry-after)'"
      ],
      "notes": "Check for rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After). Test whether limits are per-IP, per-user, or per-session — each has different bypass strategies."
    },
    {
      "id": "apienum-06",
      "title": "Identify authentication schemes",
      "description": "Map authentication mechanisms across all API endpoints to find inconsistencies and bypass opportunities.",
      "commands": [
        "curl -sk -I https://target.com/api/users | grep -iE '(www-authenticate|authorization|x-api-key)'",
        "curl -sk https://target.com/api/users -H 'Authorization: Bearer invalid' -o /dev/null -w '%{http_code}'",
        "curl -sk https://target.com/api/users -o /dev/null -w '%{http_code}'",
        "nuclei -u https://target.com -t misconfiguration/unauthenticated-api.yaml -o unauth-api.txt"
      ],
      "notes": "Compare responses between authenticated and unauthenticated requests. Test for authentication bypass by removing the Authorization header, using an expired token, or swapping between authentication methods."
    },
    {
      "id": "apienum-07",
      "title": "Discover Postman collections and API artefacts",
      "description": "Search for publicly exposed Postman collections, Insomnia exports, and other API testing artefacts that reveal full endpoint inventories.",
      "commands": [
        "curl -sk https://target.com/postman_collection.json",
        "curl -sk https://target.com/.postman/collection.json",
        "gau target.com | grep -iE '(postman|insomnia|collection\\.json|workspace)'",
        "nuclei -u https://target.com -t exposures/apis/postman-collection.yaml"
      ],
      "notes": "Public Postman workspaces are searchable at postman.com. Search for the target's domain name to find collections shared by their developers."
    }
  ],
  "references": [
    "https://www.postman.com/",
    "https://github.com/graphql-kit/graphql-voyager",
    "https://github.com/ffuf/ffuf",
    "https://owasp.org/API-Security/editions/2023/en/0x11-t10/",
    "https://portswigger.net/web-security/api-testing"
  ],
  "version": "1.0.0",
  "updatedAt": "2026-06-17"
}