OsintX.IOOsintX.IOv2.0.0

OsintX.IO Developer API

Search API reference

One HTTP endpoint runs the same pipeline as the in-app workspace: breach corpora, social signals, Discord tooling, IP and crypto OSINT, IntelX where your plan allows it, and community modules. Rate limits and feature gates always match your subscription, identical to the dashboard.

POST /api/v1/searchPOST /api/v1/image-geolocationPOST /api/v1/ai-analyzerCredits billed per requestMax 120s (platform)
Sign in to see your live plan and IntelX cap in this panel. The documentation is readable without an account.

Overview

  • Unified endpoint POST /api/v1/search returns 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/search for daily search_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-key are 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-analyzer and POST /api/v1/image-geolocation.
  • Optional sanity check: GET /api/auth/me accepts 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_access on the profile.

API key access is Enterprise-only.

Unified search

POST https://osintx.io/api/v1/searchJSON body, UTF-8, Content-Type application/json

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).

POST https://osintx.io/api/v1/image-geolocationmultipart/form-data · field name: image

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.

POST https://osintx.io/api/v1/ai-analyzerJSON body · returns { content: string } on success

Your signed-in plan in this browser: free — upgrade to Enterprise to use this endpoint.

Request body

querystringrequired

Same search query string as in the dashboard (used in the prompt header).

searchTypestringrequired

Search mode label (e.g. username, email, discord).

resultsContextstringoptional

JSON or text export for the first analysis. Required when `messages` is absent or empty; ignored in follow-up mode when `messages` is non-empty.

messagesarrayoptional

Follow-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.

querystringrequired

Search term (username, email, Discord snowflake, IP, phone digits, IntelX UUID, wallet, FiveM identifier like steam:/license:/xbl:, etc.).

typestringrequired

One of the search modes listed below. Unknown types are rejected like in the app.

wildcardbooleanoptional

When true, forwarded to breach.vip-backed paths where supported (same as dashboard toggle).

minecraftTypestringoptional

Only 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

username

Socials, leak indices, Snusbase, FiveM, optional IntelX side-load when the query looks like a UUID.

email

Leak corpora, Oathnet stealer context, Holehe registration hints.

discord

Discord snowflake ID: panels + FiveM bridge data (FiveM bridge endpoints require an active FiveM API Addon or Enterprise).

fivem

FiveM identifier search (supports steam:, license:, license2:, xbox:, xbl:, fivem:, live:). In external v1 API, Bearer access is Enterprise-only.

minecraft

Minecraft breach lookup (OsintCat-backed). Use minecraftType for username/ip/password/email/uuid in /api/v1/search.

ip

Crypto and network pivot via OSINT lookup, Oathnet host signals, Wentyn.

phone

Normalize to digits where possible; OsintCat phone endpoints.

crypto

Wallet or chain-oriented probe via /api/osint/lookup.

breaches

Alias-weighted leak-oriented bundle.

password

Credential and hash oriented leak scan.

intelx

IntelX storage UUID; returns intelx text payload plus raw when present.

image-geolocation

Image upload geolocation endpoint is separate: POST /api/v1/image-geolocation (Pro/Enterprise only).

games

Informational 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

401Missing or invalid session / API key.
402Not enough credits for this request.
403Plan gate, blacklist, API access disabled for external keys, or Enterprise-only routes (e.g. AI Analyzer) when the account is not Enterprise.
429Daily search budget exhausted, IntelX daily cap hit, or image-geolocation daily cap hit; body usually includes counters.
503IntelX upstream unavailable for IntelX-specific queries.

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())