Skanyr
API endpoint discovery from JS bundles and network activity
3 min read
Skanyr discovers hidden API endpoints by parsing JavaScript bundles and intercepting network activity. After discovery, retrieve the detected APIs and their data via dedicated data endpoints.
discover
result = client.skanyr.discover("https://example.com", artifact_id=page.artifact_id)
for ep in result.endpoints:
print(ep.method, ep.path, ep.confidence)
discover_all (auto-pagination)
for ep in client.skanyr.discover_all("https://example.com"):
print(ep.method, ep.path)
discoverStream (SSE)
for await (const event of client.skanyr.discoverStream('https://example.com')) {
console.log(event.type, event.endpoint?.path);
}
detected_apis
After running discovery, retrieve all detected API endpoints and their status across all 12 detectors.
apis = client.skanyr.detected_apis("https://example.com")
for detector in apis.detectors:
print(detector.name, detector.status, detector.record_count)
const apis = await client.skanyr.detectedApis('https://example.com');
apis.detectors.forEach(d => console.log(d.name, d.status, d.recordCount));
DetectedAPIsResponse fields
| Field | Type | Description | |-------|------|-------------| | detectors | list | Results from each of the 12 detectors | | total_records | integer | Sum of records across all detectors | | page_url | string | The discovered page URL |
DetectorResult fields
| Field | Type | Description |
|-------|------|-------------|
| name | string | Detector name (e.g. rest_api, graphql, json_ld) |
| status | string | found, empty, or error |
| confidence | float | 0.0 to 1.0 |
| record_count | integer | Number of data records extracted |
| api_type | string | rest, graphql, websocket, etc. |
api_data (paginated)
Retrieve the actual extracted data for a specific API endpoint, with pagination.
data = client.skanyr.api_data(
"https://example.com/api/v1/products",
offset=0,
limit=1000,
)
print(f"Page of {len(data.records)} records (total: {data.total_available})")
for record in data.records:
print(record)
const data = await client.skanyr.apiData('https://example.com/api/v1/products', {
offset: 0,
limit: 1000,
});
console.log(`${data.records.length} of ${data.totalAvailable} records`);
ApiDataResponse fields
| Field | Type | Description |
|-------|------|-------------|
| records | list | Extracted data records |
| total_available | integer | Total records available for this endpoint |
| offset | integer | Current offset |
| limit | integer | Page size used |
| api_type | string | rest, graphql, etc. |
| endpoint | string | The API endpoint URL |
| method | string | HTTP method used |
Data endpoints require a prior discovery run. If no cached results exist, the API returns 404. Discovery results are cached per-organization — each tenant sees only their own results.
ApiEndpoint fields
| Field | Type | Description | |-------|------|-------------| | method | string | HTTP method | | path | string | Endpoint path | | confidence | float | 0.0 to 1.0 | | source | string | js_bundle, network, or probe | | parameters | list | Detected request parameters |