Overview
- Unified endpoint
POST /api/v1/searchreturns a single JSON document per request. Behavior matches what you get when you run the same query and type in the app workspace (sources that fail upstream may be omitted or partial, same as the UI). - Every call is authorized as your user, then passes through
POST /api/searchfor dailysearch_limit, blacklist checks, and IntelX daily counters on eligible plans. - Scripts and servers should send an API key. The account must have API access so Bearer or
x-osintx-api-keyare accepted. A normal browser session can call the route with cookies only; external clients cannot rely on cookies alone for automation. - API requests consume credits. Cost per request: EUR 0.50.
- Additional v1 endpoints are available for feature parity with the dashboard:
POST /api/v1/ai-analyzerandPOST /api/v1/image-geolocation. - Optional sanity check:
GET /api/auth/meaccepts the same Bearer key and returns plan fields, useful when debugging 403s.
API keys
Keys are opaque strings prefixed with ox_live_. Each account holds at most one active key; rotating generates a new secret and invalidates the previous one immediately.
Issue or rotate via POST /api/auth/api-key while logged in with a session cookie (typical flow: in-app settings). That route does not accept Bearer keys, so keep key creation in the browser or your own backend that holds the user session.
Authentication
Provide exactly one of the following for programmatic access:
Authorization: Bearer ox_live_…x-osintx-api-key: ox_live_…- Session cookies from a logged-in browser (same origin). Bearer-style keys still require
api_accesson the profile.
API key access is Enterprise-only.
Unified search
The handler fans out to the same internal routes the dashboard uses (breach hubs, Oathnet, OsintCat, IntelX, Discord-specific tools, etc.). Timeouts follow each upstream; the route may take up to roughly two minutes under load.
For the external API, Bearer key access is Enterprise-only. Inside the dashboard session, plan gates still apply per search type (same behavior as the app UI).
Image geolocation
Pro and Enterprise only. Upload one image with multipart form-data to run visual geolocation (architecture, signage, vegetation, road markings, and similar clues).
Daily cap (UTC): n/a for your signed-in plan (free). Pro = 15/day, Enterprise = 15/day.
Success response includes normalized fields like bestGuess, confidence, latitude, longitude, and alternatives.
AI Analyzer
Enterprise only. Sends structured results to the server-side AI route: when AI_ANALYZER_API_BASE and AI_ANALYZER_API_KEY are set, it uses that OpenAI-compatible /v1/chat/completions gateway (with model fallbacks); otherwise it falls back to OpenRouter if OPENROUTER_API_KEY is configured. Authenticate with a session cookie or with Bearer ox_live_… / x-osintx-api-key where api_access is enabled.
Your signed-in plan in this browser: free — upgrade to Enterprise to use this endpoint.
Request body
querystringrequiredSame search query string as in the dashboard (used in the prompt header).
searchTypestringrequiredSearch mode label (e.g. username, email, discord).
resultsContextstringoptionalJSON or text export for the first analysis. Required when `messages` is absent or empty; ignored in follow-up mode when `messages` is non-empty.
messagesarrayoptionalFollow-up chat: non-empty array of user/assistant turns (same as in-app). When set, the route uses chat mode and does not require `resultsContext`.
HTTP 403 with AI Analyzer is available on Enterprise plans only. when the authenticated user is not on an Enterprise plan.
Request body
All fields are sent in the JSON object body of the POST.
querystringrequiredSearch term (username, email, Discord snowflake, IP, phone digits, IntelX UUID, wallet, FiveM identifier like steam:/license:/xbl:, etc.).
typestringrequiredOne of the search modes listed below. Unknown types are rejected like in the app.
wildcardbooleanoptionalWhen true, forwarded to breach.vip-backed paths where supported (same as dashboard toggle).
minecraftTypestringoptionalOnly used when type is minecraft. One of: username, ip, password, email, uuid. Defaults to username.
Responses
On success, HTTP 200 with ok: true. The quota object echoes the same counters you would see after a dashboard search (including IntelX-specific fields when relevant). The data object is type-dependent: usernames return grouped breach and social payloads; emails emphasize stealer and holehe channels; Discord IDs hit panel APIs; and so on. Treat unknown keys as forward-compatible.
Example success shape
{
"ok": true,
"query": "example",
"type": "username",
"quota": {
"searches_today": 3,
"search_limit": 50
},
"data": { }
}Example result: /api/v1/search
{
"ok": true,
"query": "target_user",
"type": "username",
"quota": {
"searches_today": 7,
"search_limit": 50,
"searches_remaining": 43
},
"data": {
"leakRecords": [
{
"email": "target@example.com",
"username": "target_user",
"source": "ExampleLeak.txt"
}
],
"socialProfiles": [
{
"platform": "discord",
"handle": "target_user",
"id": "793548887089913886"
}
],
"minecraftProfile": {
"username": "target_user",
"uuid": "d8d5a9237b2043d8883b1150148d6955",
"avatar": "https://mc-heads.net/avatar/d8d5a9237b2043d8883b1150148d6955/96"
}
}
}Example result: /api/v1/ai-analyzer
{
"content": "## Summary for username `target_user`\n\nMain matches suggest one likely alias cluster.\n\n| Platform | Handle | Notes |\n|---|---|---|\n| Discord | target_user | Appears in multiple datasets |\n| Minecraft | target_user | UUID resolved |\n\nNext pivots: check reused email domains and timeline overlap."
}Example result: /api/v1/image-geolocation
{
"result": {
"bestGuess": "Prague, Czech Republic",
"city": "Prague",
"region": "Prague",
"country": "Czech Republic",
"latitude": 50.087,
"longitude": 14.421,
"confidence": 72,
"evidence": [
"Central European road signs and lane markings",
"Architecture style matches Prague historic core"
],
"alternatives": [
{
"location": "Brno, Czech Republic",
"confidence": 38,
"reason": "Similar signage and urban layout"
}
],
"caution": "Estimate may be wrong if the image location is non-native or staged.",
"notEnoughEvidence": false
},
"image_geolocation_today": 4,
"image_geolocation_daily_limit": 15
}Example error: insufficient credits (402)
{
"error": "No credits left. Please buy more credits in Pricing."
}Errors return JSON with an error string when applicable; status codes follow the table in the Errors section.
Search types
usernameSocials, leak indices, Snusbase, FiveM, optional IntelX side-load when the query looks like a UUID.
emailLeak corpora, Oathnet stealer context, Holehe registration hints.
discordDiscord snowflake ID: panels + FiveM bridge data (FiveM bridge endpoints require an active FiveM API Addon or Enterprise).
fivemFiveM identifier search (supports steam:, license:, license2:, xbox:, xbl:, fivem:, live:). In external v1 API, Bearer access is Enterprise-only.
minecraftMinecraft breach lookup (OsintCat-backed). Use minecraftType for username/ip/password/email/uuid in /api/v1/search.
ipCrypto and network pivot via OSINT lookup, Oathnet host signals, Wentyn.
phoneNormalize to digits where possible; OsintCat phone endpoints.
cryptoWallet or chain-oriented probe via /api/osint/lookup.
breachesAlias-weighted leak-oriented bundle.
passwordCredential and hash oriented leak scan.
intelxIntelX storage UUID; returns intelx text payload plus raw when present.
image-geolocationImage upload geolocation endpoint is separate: POST /api/v1/image-geolocation (Pro/Enterprise only).
gamesInformational branch tied to game-adjacent IDs (e.g. FiveM via Discord context).
mod:<id>Community module slot: same leak and username style bundle as the dashboard module runner.
Plans & limits
Allowed search types mirror the product matrix: Free covers IP, domain, phone, password, crypto, VIN, and Discord ID. Higher tiers unlock username, email, breach-heavy modes, IntelX, FiveM (Basic+ or FiveM API Addon), games, and mod:* (community modules start at Basic). Exact numbers for daily searches and IntelX caps are enforced server-side and exposed through quota on each response. Image geolocation is a separate endpoint and has a dedicated daily cap (Pro 15/day, Enterprise 15/day). The AI Analyzer API (POST /api/v1/ai-analyzer) is Enterprise-only (same auth as above). API v1 requests consume credits (EUR 0.50 per request).
Tier inferred in this session: free
HTTP status codes
Server-side scripts calling https://www… through Cloudflare sometimes receive HTML (for example HTTP 429) instead of JSON. Point automation at a direct app host (OSINTX_API_BASE is best). For this app’s own nested server fetches, set OSINTX_API_BASE or rely on http://127.0.0.1:$PORT when the public hostname is www.* and PORT is set (override with OSINTX_SSR_FETCH_VIA_LOOPBACK=off). Status probes also respect OSINTX_STATUS_PROBE_ORIGIN; on Vercel, VERCEL_URL is used for built-in probes. For uptime checks prefer GET /api/v1/ping instead of POST /api/v1/search.
Examples
cURL (Bearer)
curl -sS -X POST "https://osintx.io/api/v1/search" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"someuser","type":"username","wildcard":false}'cURL (custom header)
curl -sS -X POST "https://osintx.io/api/v1/search" \
-H "x-osintx-api-key: YOUR_OX_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"breach@example.com","type":"email"}'cURL (Minecraft + minecraftType)
curl -sS -X POST "https://osintx.io/api/v1/search" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"xColop8","type":"minecraft","minecraftType":"username"}'cURL (FiveM identifier)
curl -sS -X POST "https://osintx.io/api/v1/search" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"license:abcd1234","type":"fivem"}'cURL (who am I)
Quick check that your key and plan resolve correctly.
curl -sS "https://osintx.io/api/auth/me" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY"cURL (AI Analyzer, Enterprise)
Replace resultsContext with a real JSON export from your pipeline.
curl -sS -X POST "https://osintx.io/api/v1/ai-analyzer" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"someuser","searchType":"username","resultsContext":"{\\\"note\\\":\\\"paste real export JSON here\\\"}"}'cURL (AI Analyzer follow-up chat)
Use messages for second-step / follow-up analysis.
curl -sS -X POST "https://osintx.io/api/v1/ai-analyzer" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY" \
-H "Content-Type: application/json" \
-d '{
"query":"target_user",
"searchType":"username",
"messages":[
{"role":"user","content":"Summarize the strongest links first."},
{"role":"assistant","content":"I found 3 likely linked aliases."},
{"role":"user","content":"Now focus only on Discord-related evidence."}
]
}'cURL (image geolocation)
Multipart upload. Field name must be image.
curl -sS -X POST "https://osintx.io/api/v1/image-geolocation" \
-H "Authorization: Bearer YOUR_OX_LIVE_KEY" \
-F "image=@/absolute/path/photo.jpg"cURL (liveness, no auth)
Prefer this for uptime monitors — avoids heavy search work and is less likely to hit edge rate limits.
curl -sS "https://osintx.io/api/v1/ping"Node / fetch
const res = await fetch("https://osintx.io/api/v1/search", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.OSINTX_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: "793548887089913886",
type: "discord",
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data?.error ?? res.statusText);
console.log(data.data);Python
import os, requests
url = "https://osintx.io/api/v1/search"
headers = {
"Authorization": f"Bearer {os.environ['OSINTX_API_KEY']}",
"Content-Type": "application/json",
}
r = requests.post(url, headers=headers, json={
"query": "1.1.1.1",
"type": "ip",
}, timeout=120)
r.raise_for_status()
print(r.json())