Quickstart
This page takes you from zero to a working Vysion query. By the end you will have made an authenticated request, understood the response, narrowed a search with filters, and retrieved a full document.
Before you begin
Section titled “Before you begin”You need:
- A Vysion API key. If you do not have one yet, contact us with your use case and organization details. See Authentication for the full process.
- A way to send HTTPS requests. The examples use
curland the official Python client. Any HTTP client works.
Every request goes to the same base URL and carries the same two headers:
| Setting | Value |
|---|---|
| Base URL | https://api.vysion.ai/api/v2 |
| Authentication header | x-api-key: YOUR_API_KEY |
| Response format header | Accept: application/json |
All endpoints in the current API are read-only GET requests.
Make your first request
Section titled “Make your first request”-
Store your API key in an environment variable
Keeping the key out of your commands and source code stops it from ending up in shell history or a repository.
Terminal window export VYSION_API_KEY="your_api_key_here"Terminal window $env:VYSION_API_KEY = "your_api_key_here" -
Install a client
curlships with most systems, so there is nothing to install for the shell examples. For Python, install the official library:Terminal window pip install vysion -
Search for documents
Search the darknet document index for a keyword.
page_size=3keeps the first response short.Terminal window curl "https://api.vysion.ai/api/v2/document/search?q=lockbit&page_size=3" \--header 'Accept: application/json' \--header "x-api-key: $VYSION_API_KEY"import osfrom vysion import clientc = client.Client(api_key=os.environ["VYSION_API_KEY"])result = c.search("lockbit")for hit in result.hits:print(hit) -
Check the result
A successful call returns HTTP
200and a JSON body with adataobject. If you get401instead, the key is missing or wrong: jump to Troubleshooting.
Understand the response
Section titled “Understand the response”Search endpoints wrap their results in the same envelope: a total count and a list of hits. This is a shortened document hit:
{ "data": { "total": 1, "hits": [ { "page": { "id": "123456789101112131415161", "url": { "url": "site.onion/content/darknet", "domainName": "site.onion", "network": "tor" }, "pageTitle": "Сайты даркнет", "language": "ru", "detectionDate": "2024-12-10T09:49:40", "chunk": true }, "tag": [], "email": [], "telegram": [{ "value": "https://t.me/someone" }], "bitcoin_address": [] } ] }}| Field | What it tells you |
|---|---|
data.total |
Number of documents that match the query, across all pages |
data.hits |
The documents on the current page |
page.id |
Unique document ID. Use it to fetch the document or its full HTML later |
page.url |
Where the page was found, including its network (tor, i2p or clearnet) |
page.pageTitle, page.language |
Title and detected language of the page |
page.detectionDate |
When Vysion detected the page |
page.chunk |
true when the hit carries only a fragment of the HTML |
email, telegram, bitcoin_address, … |
Entities extracted from the page, one list per type |
The complete object definitions are in Schemas.
Refine your search
Section titled “Refine your search”A single keyword is rarely enough. The document search accepts query operators and filters that you can combine.
Query operators
Section titled “Query operators”| Operator | Meaning | Example |
|---|---|---|
+ |
AND | lockbit +negotiation |
| |
OR | lockbit | blackcat |
- |
Exclude a term | ransomware -lockbit |
"…" |
Exact phrase | "initial access" |
* |
Prefix match | ransom* |
( ) |
Precedence | (lockbit | blackcat) +leak |
~N |
Fuzziness after a word, slop after a phrase | lockbit~1 |
Filters and pagination
Section titled “Filters and pagination”| Parameter | Use it to |
|---|---|
gte, lte |
Limit results to a date range. Accepts a Unix timestamp, YYYY-MM-DD or YYYY-MM-DDThh:mm:ss |
network |
Keep only tor, i2p or clearnet results |
language |
Keep only one language code |
include_tag, exclude_tag |
Keep or drop documents with a given tag |
page, page_size |
Walk through the results. The default page size is 10 |
This request looks for an exact phrase on Tor during the first quarter of 2025. Let curl URL-encode the query so that quotes and spaces survive the trip:
curl --get "https://api.vysion.ai/api/v2/document/search" \ --data-urlencode 'q="initial access" +vpn' \ --data-urlencode 'network=tor' \ --data-urlencode 'gte=2025-01-01' \ --data-urlencode 'lte=2025-03-31' \ --data-urlencode 'page=1' \ --header 'Accept: application/json' \ --header "x-api-key: $VYSION_API_KEY"To read every result, keep increasing page until you have collected data.total hits. Pace the requests as described in Rate Limiting.
Retrieve a full document
Section titled “Retrieve a full document”Search hits contain a fragment of the page. Once you have a page.id, you can fetch the document itself or its complete HTML:
# Document metadata and extracted entitiescurl "https://api.vysion.ai/api/v2/document/62bdc0968e4892b70411895c" \ --header 'Accept: application/json' \ --header "x-api-key: $VYSION_API_KEY"
# Complete HTML of the same documentcurl "https://api.vysion.ai/api/v2/html/62bdc0968e4892b70411895c" \ --header "x-api-key: $VYSION_API_KEY"import osfrom vysion import client
c = client.Client(api_key=os.environ["VYSION_API_KEY"])document = c.get_document("62bdc0968e4892b70411895c")print(document)You can also pivot from an indicator you already hold. The Documents API finds pages by URL, tag, email address, phone number or cryptocurrency wallet.
Explore the rest of the API
Section titled “Explore the rest of the API”Documents are one of several datasets. They all share the base URL, the authentication header and the pagination style you have just used.
| Dataset | Start with | Reference |
|---|---|---|
| Darknet documents | GET /document/search?q=… |
Documents, Document HTML |
| Leaks | GET /leak/search?q=… |
Leaks |
| Ransomware victims | GET /victim/search?q=… |
Ransomware Victims |
| Ransomware statistics | GET /stats/countries |
Ransomware Stats, Ransomware Histograms |
| Telegram and Discord | GET /im/search?q=… |
Instant Messaging |
| Daily feeds | GET /feed/ransomware?batch=YYYY-MM-DD |
Feeds |
Each reference page lists the parameters, example requests and response fields for its endpoints.
Handle errors and rate limits
Section titled “Handle errors and rate limits”Plan for two things before you move a script into production.
Errors. Failed requests return a standard HTTP status code and a JSON body that describes the problem:
{ "error": { "code": 400, "message": "Detailed error description" }}The codes you are most likely to meet are 400 (invalid request), 401 (missing or invalid API key), 404 (resource not found) and 429 (rate limit exceeded). The full list is in Error Codes.
Rate limits. Limits apply per API key and vary by endpoint category. Responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers so that your client can slow down before it is rejected. When you receive a 429, wait and retry with a backoff. Rate Limiting covers the current limits and retry patterns.
Choose how to integrate
Section titled “Choose how to integrate”Calling the REST API directly is one option. If you already work in one of these tools, start from its guide instead.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause | What to do |
|---|---|---|
401 Unauthorized |
The x-api-key header is missing, misspelled or carries the wrong key |
Print the variable (echo $VYSION_API_KEY) and check the header name. See Authentication |
400 Bad Request |
A parameter is malformed, often an unencoded query or a wrong date format | URL-encode the query and use one of the accepted date formats |
406 Not Acceptable |
The request asked for a format other than JSON | Send Accept: application/json |
429 Too Many Requests |
You exceeded the rate limit for that endpoint category | Wait, then retry with backoff. See Rate Limiting |
200 with "total": 0 |
The query is valid but nothing matches | Remove filters one at a time, widen the date range or try a prefix search such as ransom* |
If a request still fails, contact us with the endpoint, the parameters you sent and the response you received. Leave your API key out of the message.
Next steps
Section titled “Next steps”- Read Authentication for key handling best practices.
- Browse the Documents API to see every search and lookup endpoint.
- Subscribe to the Feeds if you need daily indicators instead of ad hoc searches.