API Quick-Start Guide¶
Use these cURL examples to authenticate, retrieve projects and inspect their hosts, services, credentials, darknet findings, and employees.
Endpoints at a glance¶
| Method | Path | Step |
|---|---|---|
GET |
/api/user/projects |
2: List all projects → get Project IDs |
POST |
/api/project/{projectID} |
3: Get project details → list all IPs |
POST |
/api/project/{projectID}/host/{ip} |
4: Iterate IPs → get host details or service names |
POST |
/api/project/{projectID}/socialdata |
6a: Flat list of leaks |
POST |
/api/project/{projectID}/socialdatagrouped |
6b: Deduplicated leaks |
POST |
/api/project/{projectID}/intel/leakdata |
7: Retrieve darknet leak data (leaked documents) |
POST |
/api/project/{projectID}/socialdb |
8: Retrieve employee data |
1. Configure the API key¶
Create a key under Preferences → API Keys, choose the required permission and expiration date, and copy the generated value before closing the confirmation dialogue. The secret is displayed only once. If two-factor authentication is active, its current one-time password is required during creation. For the complete creation, rotation, and deletion procedure, see API Keys.
Authentication uses the X-API-Key header on every request. Store the copied value securely and set it once in your environment; the cURL examples below reference this environment variable.
# Export once in your shell
export PLATFORM_API_KEY="your-api-key-here"
# Every subsequent call uses it:
-H "X-API-Key: $PLATFORM_API_KEY"
2. List all projects → get Project IDs¶
Returns all projects the authenticated user can access. The ID field from each entry is your projectID for all subsequent calls.
Endpoint
GET /api/user/projects
curl -s -X GET \
https://platform.alphastrike.io/api/user/projects \
-H "X-API-Key: $PLATFORM_API_KEY"
[
{
"ID": "b7b7cfdc-50bb-43db-8f1e-2eb9fb7c5c91",
"Name": "Acme Corp External",
"Description": "Q1 2025 perimeter scan",
"AdminName": "alice",
"Searching": false,
"CreatedAt": "2025-01-10T08:42:00Z",
"UpdatedAt": "2025-03-22T14:11:00Z"
},
{
"ID": "a1c3e5f7-9b2d-4e6a-8c0f-1d3e5f7a9b2d",
"Name": "Internal DMZ",
"Searching": true
}
]
3. Get project details: list all IPs¶
POST to the project endpoint. The response body (a ProjectMetaDTO) includes an ips array with every host address. You can narrow results with the optional filter body parameter.
Endpoint
POST /api/project/{projectID} — body is optional
Without filter¶
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-50bb-43db-8f1e-2eb9fb7c5c91 \
-H "X-API-Key: $PLATFORM_API_KEY"
# Extract only the IPs:
curl ... | jq '.ips'
With filter: only hosts with vulnerabilities¶
Tip
The filter expression is applied to service-level fields. CVE_max counts the CVEs assigned to a service, so CVE_max>0 returns only IPs that have at least one service with a known CVE. To filter by severity, use CVE_score, the highest CVSS score of those CVEs, for example CVE_score>=7.0. Write the threshold with a decimal point: a whole number such as 7 misses services scored 10.
Matching the web interface
Assets → Services and Assets → Hosts add Deleted:false && !(SuppressedOpenport:true) to every request. It hides removed services and hidden open ports. The API does not add it. To get the same results, add it to your filter, for example Deleted:false && !(SuppressedOpenport:true) && (CVE_max>0).
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-... \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": "CVE_max>0"}' \
| jq '.ips'
{
"ID": "b7b7cfdc-50bb-43db-8f1e-2eb9fb7c5c91",
"name": "Acme Corp External",
"ips": [
"198.51.100.7",
"203.0.113.10",
"203.0.113.44"
],
"cve_score": 9.8,
"darknet_domains": ["acme.com", "acme.org"],
"hoststats": {
"vulnerable_hosts": 3,
"non_vulnerable_hosts": 0
},
"project_summary": {
"ip_count": 3,
"service_count": 18
}
}
# Output from jq '.ips':
["198.51.100.7", "203.0.113.10", "203.0.113.44"]
4. Iterate IPs: get host details or service names¶
For each IP from step 3, POST to the host endpoint. Returns a HostWithAllServicesDTO with a services map keyed by service name (e.g. "https_443", "http_80_example.com"). The request needs a JSON body: send {} to get all services, or a filter to restrict which services are returned. A request without a body is rejected with 400 Bad Request. If the filter matches no service of the host, the API answers 404 Not Found.
Endpoint
POST /api/project/{projectID}/host/{ip} — JSON body required, {} for no filter
Full host data¶
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../host/203.0.113.10 \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# Extract service names only:
curl ... | jq '[.services | keys[]]'
Filtered: vulnerable services only¶
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../host/203.0.113.10 \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": "CVE_max>0"}'
{
"ip": "203.0.113.10",
"domains": ["mail.acme.com", "smtp.acme.com"],
"whois": "ACME-CORP-NET ...",
"services": {
"https_443": {
"Protocol": "https",
"Port": "443",
"Name": "https_443",
"InspectorData": { /* CVE info, CPEs, etc. */ },
"SourceData": { /* raw scan results */ }
},
"smtp_25": { "Protocol": "smtp", "Port": "25" }
}
}
# Output from jq '[.services | keys[]]':
["https_443", "smtp_25"]
5. Get a specific service by name (optional)¶
Once you have a service name from step 4, use it to retrieve the complete service object. The OpenAPI specification does not provide a dedicated endpoint for a single service. Query the same host endpoint and select the required key from the services map with jq.
Endpoint
POST /api/project/{projectID}/host/{ip} — then extract .services["<serviceName>"]
# Fetch host, then pick the service by name
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../host/203.0.113.10 \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{}' \
| jq '.services["https_443"]'
{
"Name": "https_443",
"Protocol": "https",
"Port": "443",
"LastFound": "2025-03-21T09:15:00Z",
"CveCount": 3,
"ExploitCount": 2,
"InspectorData": {
"CVE_score": 9.8, // highest CVSS score of the assigned CVEs
"CVE_max": 3, // number of assigned CVEs, not a score
"CPE": ["cpe:2.3:a:apache:http_server:2.4.49:*:*:*:*:*:*:*"],
"Checked": false
},
"SourceData": { // raw scan document; its keys depend on the scan
"ip": "203.0.113.10",
"port": 443,
"protocol": "https",
"data": { "http": { /* raw HTTP scan result */ } },
"findings": {
"finding-abc123": { /* finding details */ }
}
},
"Matches": { // keyed by a hash of match and search term
"0d17677e5ee31774a80a0549b5a63463": {
"Match": "{\"data.http.response.body\":[\"Welcome to MATCH--- acme.com ---MATCH\"]}", // search highlight, JSON-encoded
"Searchterm": "acme.com",
"Score": 1.0
}
}
}
6. Retrieve credential leak data¶
Two endpoints expose project-level credential leaks, including emails, usernames, plain and hashed passwords, and source breach metadata. Use /socialdata for the raw record list or /socialdatagrouped for entries deduplicated by URL, email, username, and password. Both endpoints support pagination. If Darknet Anonymization is active for your account, both return anonymised values, as the web interface does.
Tip
All parameters are optional. Call either endpoint without query params and without a body, and the full set of credential leak data for the project is returned.
Tip
Paging and sorting go in the query string: pageIndex (starting at 0), pageSize, orderBy and asc. Without orderBy, records are sorted by ID. Sorting is descending by default. For ascending order, add asc without a value (&asc). Records without a date sort as the highest date: with orderBy=date they come first in descending order and last with &asc. The API only checks whether asc is present, so asc=false also sorts in ascending order. Without pageSize, all results come in one page, so only pageIndex=0 returns data. A page past the end comes back empty, as {"total": 0, "page": null}.
Tip
The filter goes in the JSON body as {"filter": "<expression>"} and uses the platform's key:value filter syntax. email:"j.doe@acme.com" matches the exact address, and email:c"acme.com" matches every address that contains acme.com. Both forms are case-sensitive and work on both endpoints. On /socialdatagrouped, a record with several addresses holds them in one string, so use c"…" to match one of them.
Tip
Inside the JSON string, escape the quotes around the value as \". A body that is not valid JSON is ignored like a missing one, and the full, unfiltered set is returned: if total is the same as without a filter, check the \" escaping. A filter query parameter is ignored.
6a: Flat list of leaks: /socialdata¶
Endpoint
POST /api/project/{projectID}/socialdata — paging and sorting via query params, filter in the JSON body
# No params → returns ALL credential leaks:
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdata \
-H "X-API-Key: $PLATFORM_API_KEY"
# With paging, sorted by date descending (add &asc for ascending):
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdata?pageIndex=0&pageSize=20&orderBy=date" \
-H "X-API-Key: $PLATFORM_API_KEY"
# Filter — key:value in the JSON body, quotes
# around the value escaped as \"
# Exact address: email:"j.doe@acme.com"
# Address contains: email:c"acme.com"
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdata \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": "email:\"j.doe@acme.com\""}'
# Filter + paging combined:
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdata?pageIndex=0&pageSize=20&orderBy=date" \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": "email:c\"acme.com\""}'
{
"total": 142,
"page": [
{
"id": "cl_8842_0", // stored ID plus its position in this page
"email": ["j.doe@acme.com"],
"username": ["jdoe"],
"password": ["Summer2023!"],
"hashed_password": ["$2y$10$Q9..."],
"passwordtype": "bcrypt",
"url": ["https://portal.acme.com/login"],
"name": ["John Doe"],
"phone": ["+1-415-555-0199"],
"ip_address": ["198.51.100.23"],
"type": "Stealer Logs",
"date": "2023-11-02T00:00:00Z",
"sourceshort": "Collection#1",
"database_name": "combo_2019",
"system_id": "625af529-f14e-4e54-a68b-82629d1281b9",
"bucket": "leaks.logs",
"leak_info": {
"Origin": "combo_2019",
"Type": "Stealer Logs",
"Bucket": "leaks.logs",
"SystemID": "625af529-f14e-4e54-a68b-82629d1281b9",
"DiscoveryDate": "2023-11-02T00:00:00Z"
}
}
]
}
6b: Deduplicated leaks: /socialdatagrouped¶
Endpoint
POST /api/project/{projectID}/socialdatagrouped — same query params (orderBy, asc, pageIndex, pageSize) and JSON body (filter) as /socialdata
Tip
Same call shape as /socialdata: paging and sorting go in the query string, the filter goes in the JSON body. The difference is the result: records are collapsed on the composite key (URL, email, username, password), so url/email/username/password become single strings (several values are joined with ,) and most other fields, type included, become arrays of all observed values.
# No params → all leaks, grouped:
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdatagrouped \
-H "X-API-Key: $PLATFORM_API_KEY"
# With filter + paging, sorted by URL (descending):
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdatagrouped?orderBy=url&pageIndex=0&pageSize=20" \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": "email:\"j.doe@acme.com\""}'
{
"total": 87,
"page": [
{
// composite primary key (single strings):
"url": "https://portal.acme.com/login",
"username": "jdoe",
"password": "Summer2023!",
"email": "j.doe@acme.com",
// aggregated values across the group (arrays):
"type": ["Stealer Logs"],
"passwordtype": ["bcrypt"],
"name": ["John Doe"],
"phone": ["+1-415-555-0199"],
"sourceshort": ["Collection#1"],
"system_id": ["625af529-..."],
"leak_info": [
{ "Origin": "combo_2019", "Type": "Stealer Logs",
"Bucket": "leaks.logs" }
],
// earliest date in the group (single value):
"leak_discovery_date": "2023-11-02T00:00:00Z"
}
]
}
Handle with care
This data contains live PII and plaintext credentials. Handle, store and transmit it according to your engagement's data-handling rules.
7. Retrieve darknet leak data (leaked documents)¶
Returns the leaked documents discovered for the project on darknet, paste, and forum sources. Each record holds the raw line where a search term matched and the metadata of its source document. As in step 6, Darknet Anonymization applies. The endpoint works in two modes:
- Without a query string, it returns every leaked document of every search term in one response. A body is ignored.
- With any query string, for example paging or sorting parameters (
pageIndex,pageSize,orderBy,asc), it returns the documents of one search term. Name it withtermin the JSON body; atermin the query string is not read. The body is then required and must be valid JSON: a request without a body, or with one that is not valid JSON, is rejected with400 Bad Request(step 6 ignores such a body instead). Without a matchingterm, the page is empty.
Endpoint
POST /api/project/{projectID}/intel/leakdata — paging and sorting via query params, term and filter in the JSON body
Tip
term is one of the project's search terms with leaked documents: a domain, a top-level domain or an email address. Take it from the domains field of a call without a query string, or from darknet_domains in the step 3 response. filter is optional and uses the same filter syntax as step 6, for example item.bucket:"leaks.logs". Sorting works as in step 6 once you set orderBy: descending by default, add &asc for ascending order. Without orderBy, the order is not defined, so set orderBy (for example item.date) when you page through the results.
# No query string → all leaked documents of all search terms:
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../intel/leakdata \
-H "X-API-Key: $PLATFORM_API_KEY"
# One domain, paged, newest first — term goes in the JSON body:
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../intel/leakdata?pageIndex=0&pageSize=20&orderBy=item.date" \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"term": "acme.com"}'
# key:value filter next to the term, quotes escaped as \"
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../intel/leakdata?pageIndex=0&pageSize=20&orderBy=item.date" \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"term": "acme.com", "filter": "item.bucket:\"leaks.logs\""}'
{
"total": 37, // matching records of the requested term (of all terms without a query string)
"domains": [ // search terms with leaked documents plus the requested term, unordered
"acme.com",
"acme.org"
],
"page": [
{
"id": "0", // position in this page, not a stable identifier
"linea": "jdoe@acme.com:Summer2023!",
"Relevant": true,
"Checked": false,
"positionline": 0,
"positionsize": 25,
"item": { // source document
"name": "combolist_2023_11.txt",
"bucket": "leaks.logs",
"date": "2023-11-02T00:00:00Z",
"systemid": "be1a6f30-375d-44f7-88f8-dcfb0640420a",
"storageid": "e3ab75a898d57cf2...",
"instore": true,
"size": 184320,
"accesslevel": 0,
"xscore": 72
}
}
]
}
Tip
To fetch the underlying file for a record, pass item.systemid and item.bucket to the corresponding leak-file endpoint. Use item.storageid as well when addressing an entry in the file tree.
Handle with care
Leaked-document lines contain raw credentials and PII. Handle, store and transmit accordingly.
8. Retrieve employee data¶
Returns the employee records shown under Intel → Employees. Each record combines the person's public profile (profile) with the credential leaks attributed to the person (findings). As in step 6, Darknet Anonymization applies.
Endpoint
POST /api/project/{projectID}/socialdb — paging and sorting via query params, filter in the JSON body
Tip
Paging and sorting work as in step 6: pageIndex (starting at 0), pageSize, orderBy and asc go in the query string. Without orderBy, records are sorted by profile.id. Sorting is descending by default; add &asc for ascending order. Records without a value in the sort field come last in both directions. Without pageSize, all records come in one page. Unlike step 6, a page past the end keeps the full count and comes back as {"total": 64, "page": null}. Only a filter that matches nothing returns "total": 0.
Tip
The filter goes in the JSON body as {"filter": "<expression>"} and uses the same filter syntax as step 6. Address a field by its path in the record, for example profile.name, profile.current_title, profile.current_employer, profile.location or profile.full_profile. Unlike step 6, a body that is not valid JSON is rejected with 400 Bad Request.
# No params → all employee records:
curl -s -X POST \
https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdb \
-H "X-API-Key: $PLATFORM_API_KEY"
# Paged, sorted by name in ascending order:
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdb?pageIndex=0&pageSize=20&orderBy=profile.name&asc" \
-H "X-API-Key: $PLATFORM_API_KEY"
# Filter — key:value in the JSON body, quotes escaped as \"
# Job title contains "Admin", profile not yet complete:
curl -s -X POST \
"https://platform.alphastrike.io/api/project/b7b7cfdc-.../socialdb?pageIndex=0&pageSize=20" \
-H "X-API-Key: $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": "profile.current_title:c\"Admin\" && profile.full_profile:false"}'
{
"total": 64,
"page": [
{
"profile": {
"id": 123456789,
"profile_id": "3c9f6a1e-5b2d-4e8f-9a7c-1d2e3f4a5b6c",
"name": "John Doe",
"current_title": "IT Administrator",
"current_employer": "Acme Corp",
"location": "San Francisco, CA, US",
"linkedin_url": "https://www.linkedin.com/in/johndoe",
"full_profile": false, // true once Employee data enrichment has completed the profile
"emails": [
{ "email": "j.doe@acme.com", "smtp_valid": "valid" }
],
"valid_emails": [ // the entries of emails with smtp_valid "valid", as in the Emails column
{ "email": "j.doe@acme.com", "smtp_valid": "valid" }
],
"phones": null,
"job_history": null
},
"findings": [ // credential leaks attributed to the person
{
"email": ["j.doe@acme.com"],
"password": ["Summer2023!"],
"type": "Stealer Logs",
"sourceshort": "Collection#1",
"date": "2023-11-02T00:00:00Z"
}
],
"origins": [ // search terms and scopes that found the person
{ "searchterm": "acme.com", "scope": "employees" }
]
}
]
}
Handle with care
Employee records are personal data and can contain plaintext credentials. Handle, store and transmit them according to your engagement's data-handling rules.
Bonus: Full bash loop: steps 3 → 4 → 5¶
Chain the steps together to enumerate all vulnerable services across every host in a project. Run the script with bash: zsh, the default shell on macOS, does not split $IPS into separate addresses.
PROJECT="b7b7cfdc-50bb-43db-8f1e-2eb9fb7c5c91"
BASE="https://platform.alphastrike.io"
HDR="X-API-Key: $PLATFORM_API_KEY"
# Step 3: get the IPs of hosts with a vulnerable service
IPS=$(curl -s -X POST "$BASE/api/project/$PROJECT" \
-H "$HDR" -H "Content-Type: application/json" \
-d '{"filter":"CVE_max>0"}' | jq -r '.ips[]')
for IP in $IPS; do
# Step 4: get the host with its vulnerable services (one request per host)
HOST=$(curl -s -X POST \
"$BASE/api/project/$PROJECT/host/$IP" \
-H "$HDR" -H "Content-Type: application/json" \
-d '{"filter":"CVE_max>0"}')
# Step 5: print each service by name
for SVC in $(printf '%s\n' "$HOST" | jq -r '.services | keys[]'); do
printf '%s\n' "$HOST" | jq --arg s "$SVC" '.services[$s]'
done
done