# API Docs

<div align="center"><img src="https://1886481076-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQElT0NzCR1Amlbjn463Z%2Fuploads%2Fgit-blob-e4d6ccf1d9bf910807d37fd02de841a0f329e33b%2Fperkins_fund_logo.png?alt=media" alt="" height="250" width="250"></div>

#### Available Tools

* [Traceix](/readme/traceix-endpoints/traceix)\
  Upload files for classification, generate CAPA/EXIF/YARA outputs, and retrieve past results by SHA-256. Includes public IPFS dataset listing and lookup.
* [OnlyVulns](/readme/onlyvulns-endpoints/onlyvulns) Coming soon...
* [Traceix Cortex Agents](/readme/traceix-endpoints/cortex-agents)\
  Agent lifecycle + operations: check-in, fetch agent configuration/metadata, run queued analyses, poll job status, and submit/retrieve endpoint-driven alerts (ownership enforced per API key).
* [AURA](/readme/pcef-public-endpoints/aura)\
  Lightweight executable triage API: upload a file for a fast verdict, view the latest scans, or search historical scans by SHA-256 (PE/ELF supported; others return `unknown`).
* [Yara Rule Playground](/readme/pcef-public-endpoints/yara)\
  Build and validate YARA rules, test them against an uploaded sample, or scan against built-in benign/malware corpora to see hits and iterate quickly.
* [Ransom Note Comparison](/readme/pcef-public-endpoints/ransom)\
  Identify likely ransomware families by ransom note similarity and search for known public decryptor links using keywords.

#### Expected API Response Output

**API BASE URL: `https://ai.perkinsfund.org`**

```json
{
  "copyright": "(c) PCEF all rights reserved", (only shown if no API key is passed)
  "error": {
    "error_message": ... (if an error)
  },
  "request_timestamp": 1743098585.390719,
  "results": {
    ... || null
  },
  "sponsor": { (if invalid or no API key provided in request)
    "link": ...,
    "title": ...
  },
  "success": true || false (if an error)
}
```

**ONLYVULNS API BASE URL: `https://api.onlyvulns.org`**

```json
{
  "error": {
    "error_id": "..." IF ERROR,
    "error_string": "..."
  },
  "metadata": {
    "note": ... (IF FREE REQUEST),
    "request_id": "...",
    "request_timestamp": unix timestamp UTC
  },
  "results": ...,
  "success": true or false
}
```

**Field descriptions**

* `error` – Contains error messages if any occurred. Will be empty dictionary on success.
* `request_timestamp` – UNIX timestamp when the request was received.
* `results` – Contains the results from the received request.
* `sponsor` – A message and link to the sponsor (only shown to users without an API key).
* `success` – A boolean indicating if the request was successfully processed.


# Traceix Endpoints


# Traceix API

Traceix provides file upload + prediction, post-processing extractors (CAPA/EXIF/YARA), antivirus scanning and hash-based AV lookup, hash-based retrieval of prior results, and public IPFS dataset browsing/search all from a single API surface.

* [AI Prediction Upload](#ai-prediction-upload)
* [Check Upload Status](#check-upload-status)
* [CAPA Extraction](#capa-extraction)
* [EXIF Extraction](#exif-extraction)
* [YARA Rules](#yara-rule-creation)
* [Search CAPA by Hash](#search-capa-by-hash)
* [Search EXIF by Hash](#search-exif-by-hash)
* [Search YARA by Hash](#search-yara-by-hash)
* [AV File Scan](#av-file-scan)
* [AV Scan Status](#av-scan-status)
* [AV Hash Lookup](#av-hash-lookup)
* [List Public IPFS Datasets](#list-public-ipfs-datasets)
* [Get Public IPFS Dataset](#get-public-ipfs-dataset)
* [Search IPFS Dataset by Hash](#search-ipfs-dataset-by-hash)
* [SDKs](https://github.com/Perkins-Fund/Traceix-SDK)

### API BASE URL: `https://ai.perkinsfund.org`

***

### AI Prediction Upload

Endpoint: `/api/traceix/v1/upload`

Request type: POST

Data type: File

Headers: `X-Api-Key: API KEY`

#### Example request

```bash
curl -H "x-api-key: YOUR_API_KEY" \
     -F "file=@/path/to/file.exe" \
     https://ai.perkinsfund.org/api/traceix/v1/upload
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "request_timestamp": 1764610085.25132,
  "results": {
    "class": "safe",
    "time_taken": 0.46030490286648273,
  },
  "sponsor": {
    "link": "https://example.com/",
    "title": "Sponsor text"
  },
  "copyright": "(c) PCEF all rights reserved"
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "MESSAGE"
  },
  "results": {},
  "request_timestamp": 1764610085.25132
}
```

***

### Check Upload Status

Endpoint: `/api/v1/traceix/status`

Request type: POST

Data type: JSON

Headers: `X-Api-Key: API KEY`

**NOTE: A valid `uuid` from a prior upload is required.**

#### Example request

```bash
curl -X POST -H "x-api-key: YOUR_API_KEY" \
     -H "content-type: application/json" \
     --data '{"uuid": "YOUR_UUID_HERE"}' \
     https://ai.perkinsfund.org/api/v1/traceix/status
```

#### Expected outputs

Success:

**NOTE:** When the status is completed, related classification and metadata can be retrieved using the hash search and extraction endpoints below.

```json
{
  "success": true,
  "error": {},
  "results": {
    "uuid": "YOUR_UUID_HERE",
    "status": "queued"  // or "processing", "completed", "error"
  },
  "request_timestamp": 1764610085.25132
}
```

Unsuccessful (missing UUID, invalid UUID, etc.):

```json
{
  "success": false,
  "error": {
    "error_message": "You did not provide a UUID required by the endpoint"
  },
  "results": {}
}
```

***

### CAPA Extraction

Endpoint: `/api/traceix/v1/capa`

Request type: POST

Data type: File

Headers: `X-Api-Key: API KEY`

#### Example request

```bash
curl -H "x-api-key: YOUR_API_KEY" \
     -F "file=@/path/to/file.exe" \
     https://ai.perkinsfund.org/api/traceix/v1/capa
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "results": {
    "sha256": "FILE_SHA256",
    "capabilities": [
      {
        "name": "persistence via registry run key",
        "attack_id": "T1060",
      }
    ]
  }
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "MESSAGE"
  },
  "results": {}
}
```

***

### EXIF Extraction

Endpoint: `/api/traceix/v1/exif`

Request type: POST

Data type: File

Headers: `X-Api-Key: API KEY`

#### Example request

```bash
curl -H "x-api-key: YOUR_API_KEY" \
     -F "file=@/path/to/file.exe" \
     https://ai.perkinsfund.org/api/traceix/v1/exif
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "results": {
    "sha256": "FILE_SHA256",
    "metadata": {
      ...
    }
  }
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "MESSAGE"
  },
  "results": {}
}
```

***

### Yara Rule Creation

Endpoint: `/api/v1/traceix/ioc`

Request type: POST

Data type: File

Headers: `X-Api-Key: API KEY`

**NOTE: This endpoint requires a file upload (`multipart/form-data`).**

#### Example request

```bash
curl -H "x-api-key: YOUR_API_KEY" \
     -F "file=@/path/to/file.exe" \
     https://ai.perkinsfund.org/api/v1/traceix/ioc
```

#### Expected outputs

Success:

```json
{
  "data": {
    "yara_rule": "rule TraceixRuleGenerator_... { ... }"
  },
  "error": {},
  "success": true
}
```

Unsuccessful (JSON body instead of file):

```json
{
  "data": {},
  "error": {
    "msg": "This endpoint requires a file"
  },
  "success": false
}
```

### Search CAPA by Hash

Endpoint: `/api/traceix/v1/capa/search`

Request type: POST

Data type: JSON

Headers: `X-Api-Key: API KEY`

**NOTE: Uses the file SHA256 hash to retrieve previously extracted CAPA data.**

#### Example request

```bash
curl -X POST -H "x-api-key: YOUR_API_KEY" \
     -H "content-type: application/json" \
     --data '{"sha256": "FILE_SHA256"}' \
     https://ai.perkinsfund.org/api/traceix/v1/capa/search
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "results": {
    "sha256": "FILE_SHA256",
    "capabilities": [
      {
        "name": "persistence via registry run key",
        "attack_id": "T1060"
      }
    ]
  }
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "No matching record for provided SHA256"
  },
  "results": {}
}
```

***

### Search EXIF by Hash

Endpoint: `/api/traceix/v1/exif/search`

Request type: POST

Data type: JSON

Headers: `X-Api-Key: API KEY`

**NOTE: Uses the file SHA256 hash to retrieve previously extracted EXIF/metadata.**

#### Example request

```bash
curl -X POST -H "x-api-key: YOUR_API_KEY" \
     -H "content-type: application/json" \
     --data '{"sha256": "FILE_SHA256"}' \
     https://ai.perkinsfund.org/api/traceix/v1/exif/search
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "results": {
    "sha256": "FILE_SHA256",
    "metadata": {
      ...
    }
  }
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "No matching record for provided SHA256"
  },
  "results": {}
}
```

***

### Search YARA by Hash

Endpoint: `/api/v1/traceix/ioc/hash`

Request type: POST

Data type: JSON

Headers: `X-Api-Key: API KEY`

**NOTE: Uses the file SHA256 hash to retrieve a previously generated YARA rule.**

#### Example request

```bash
curl -X POST -H "x-api-key: YOUR_API_KEY" \
     -H "content-type: application/json" \
     --data '{"sha256":"FILE_SHA256"}' \
     https://ai.perkinsfund.org/api/v1/traceix/ioc/hash
```

#### Expected outputs

Success:

```json
{
  "data": {
    "rule": "rule TraceixRuleGenerator_... { ... }"
  },
  "error": {},
  "success": true
}
```

Unsuccessful (no rule for hash / bad hash):

```json
{
  "data": {},
  "error": {
    "msg": "No Yara rule from provided sha hash"
  },
  "success": false
}
```

***

### AV File Scan

Endpoint: `/api/v1/traceix/av/scan`

Request type: POST

Data type: File (`multipart/form-data`)

Headers: `X-Api-Key: API KEY`

**NOTE: Submitting a file returns one or more asynchronous scan jobs. Use the returned `uuid` values with the AV status endpoint below.**

#### Example request

```bash
curl -H "x-api-key: YOUR_API_KEY" \
     -F "file=@/path/to/file" \
     https://ai.perkinsfund.org/api/v1/traceix/av/scan
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "request_timestamp": 1774623901.183456,
  "results": [
    {
      "engine": "ENGINE_NAME",
      "status": "PENDING",
      "uuid": "UUID"
    },
    ...
  ]
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "MESSAGE"
  },
  "results": null
}
```

***

### AV Scan Status

Endpoint: `/api/v1/traceix/av/status`

Request type: POST

Data type: JSON

Headers: `X-Api-Key: API KEY`

**NOTE: Requires a valid `uuid` returned from `/api/v1/traceix/av/scan`.**

#### Example request

```bash
curl -X POST -H "x-api-key: YOUR_API_KEY" \
     --data '{"uuid":"SCAN_UUID"}' \
     https://ai.perkinsfund.org/api/v1/traceix/av/status
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "request_timestamp": 1774624038.659553,
  "results": {
    "engine": "ENGINE_NAME",
    "engine_type": "ENGINE_TYPE",
    "verdict": "VERDICT"
  }
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "MESSAGE"
  },
  "results": null
}
```

***

### AV Hash Lookup

Endpoint: `/api/v1/traceix/av/lookup`

Request type: POST

Data type: JSON

Headers: `X-Api-Key: API KEY`

**NOTE: Uses a file SHA256 hash to retrieve prior antivirus / reputation results when available.**

#### Example request

```bash
curl -X POST -H "x-api-key: YOUR_API_KEY" \
     --data '{"sha256":"FILE_SHA256"}' \
     https://ai.perkinsfund.org/api/v1/traceix/av/lookup
```

#### Expected outputs

Success:

```json
{
  "success": true,
  "error": {},
  "request_timestamp": 1774623825.928707,
  "results": [
    {
      "engine": "ENGINE_NAME",
      "engine_type": "ENGINE_TYPE",
      "file_hash": "FILE_SHA256",
      "verdict": "Safe" || "Malicious" || "Unknown" || "Failed"
    },
    ...
  ]
}
```

Unsuccessful:

```json
{
  "success": false,
  "error": {
    "error_message": "Invalid API key provided"
  },
  "request_timestamp": 1774623769.575932,
  "results": null
}
```

***

### List Public IPFS Datasets

Endpoint: `/api/traceix/v1/ipfs/listall`

Request type: POST

Data type: JSON (no body required)

Headers: *(API key not required, but accepted)*

#### Example request

```bash
curl -X POST \
     https://ai.perkinsfund.org/api/traceix/v1/ipfs/listall
```

#### Expected outputs

Success:

```json
{
  "copyright": "(c) PCEF all rights reserved",
  "error": {},
  "request_timestamp": 1762267116.2708333,
  "results": [
    { "cid": "...", "sha256": "..." },
    ...
  ],
  "sponsor": {
    "link": "...",
    "title": "..."
  },
  "success": true
}
```

Unsuccessful:

```json
{
  "copyright": "(c) PCEF all rights reserved",
  "error": {
    "error_message": "MESSAGE"
  },
  "request_timestamp": 1762267116.2708333,
  "results": [],
  "success": false
}
```

***

### Get Public IPFS Dataset

Endpoint: `/api/traceix/v1/ipfs/search`

Request type: POST

Data type: JSON

Headers: *(API key not required, but accepted)*

**NOTE: Requires the dataset `cid`.**

#### Example request

```bash
curl -X POST -H "content-type: application/json" \
     --data '{"cid": "bafybeigdyr..."}' \
     https://ai.perkinsfund.org/api/traceix/v1/ipfs/search
```

#### Expected outputs

Success:

```json
{
  "copyright": "(c) PCEF all rights reserved",
  "error": {},
  "request_timestamp": 1762267143.519864,
  "results": {
    "decrypted_training_data": {
      ...
    },
    "metadata": {
      "model_information": {
        "model_accuracy": "91.64%",
        "model_version": "o1"
      },
      "payment_transaction": {
        "amount_paid": "...",
        "payment_tx": "...",
        "payment_tx_url": "https://solscan.io/tx/...",
        "thrt_price_at_payment": "..."
      },
      "upload_information": {
        "file_sha_hash": "...",
        "license": "CC BY 4.0",
        "upload_timestamp": "..."
      }
    },
    "model_classification_info": {
      "date_classified_on": "...",
      "identified_class": "...",
      "verdict_seconds": "..."
    }
  },
  "sponsor": {
    "link": "...",
    "title": "..."
  },
  "success": true
}
```

Unsuccessful:

```json
{
  "copyright": "(c) PCEF all rights reserved",
  "error": { "error_message": "Invalid CID provided" },
  "request_timestamp": 1762267194.2231338,
  "results": null,
  "sponsor": {
    "link": "...",
    "title": "..."
  },
  "success": false
}
```

***

### Search IPFS Dataset by Hash

Endpoint: `/api/traceix/v1/ipfs/find`

Request type: POST

Data type: JSON

Headers: *(API key not required, but accepted)*

**NOTE: Uses `sha_hash` to locate which public dataset a file appears in.**

#### Example request

```bash
curl -X POST -H "content-type: application/json" \
     --data '{"sha_hash": "FILE_SHA256"}' \
     https://ai.perkinsfund.org/api/traceix/v1/ipfs/find
```

#### Expected outputs

Success:

```json
{
  "data": {
    "file_data": {
      "file_size": "2251",
      "sha_hash": "10b740b968f59cb9d8a4167f72b1773f5e69269b1430a917a6e3e762d1a7526c"
    },
    "metadata": {
      "cid": "...",
      "rid": "..."
    }
  },
  "success": true
}
```

Unsuccessful:

```json
{
  "data": {},
  "success": false
}
```


# Cortex Agents API

Cortex Agents are lightweight "remote triage workers" that let your client check in, fetch its configuration, submit files for analysis, poll for results, and emit alerts — all under a consistent response envelope and strict ownership enforcement per API key.

* [Common Response Envelope](#common-response-envelope)
* [Agent Check-in](#agent-check-in)
* [Get Agent Metadata](#get-agent-metadata)
* [Run Agent](#run-agent)
* [Check Agent Run Status](#check-agent-run-status)
* [Submit Agent Alert](#submit-agent-alert)
* [Get Agent Alerts](#get-agent-alerts)
* [SDKs](#sdks)

### API Base URL

`https://ai.perkinsfund.org`

***

## Common Response Envelope

All endpoints return this top-level structure:

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241023.740849,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": {},
  "success": true
}
```

On failure:

```json
{
  "error": {
    "error_message": "..."
  },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241028.700035,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

### Authentication

All endpoints require:

* `X-Api-Key: YOUR_API_KEY`

### Ownership rule (important)

Where an endpoint accepts `agent_uuid`, the `agent_uuid` **must belong to the authenticated user (API key owner)**. Otherwise, the request fails (e.g., “Invalid agent UUID” / “Agent does not exist”).

***

## Agent Check-in

Endpoint: `/api/traceix/agent/checkin` Request type: `POST` Content type: JSON

Headers:

* `X-Api-Key: YOUR_API_KEY`
* `content-type: application/json`

Body:

* `agent_uuid`: string

### Example request

```bash
curl -X POST \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  --data '{"agent_uuid":"AGENT_UUID"}' \
  https://ai.perkinsfund.org/api/traceix/agent/checkin
```

### Expected outputs

Success:

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768240753.374693,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": { "ok": true },
  "success": true
}
```

Failure (invalid agent UUID):

```json
{
  "error": { "error_message": "Invalid agent UUID" },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768240797.701423,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

***

## Get Agent Metadata

Endpoint: `/api/traceix/agent/metadata` Request type: `POST` Content type: JSON

Headers:

* `X-Api-Key: YOUR_API_KEY`
* `content-type: application/json`

Body:

* `agent_uuid`: string

### Example request

```bash
curl -X POST \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  --data '{"agent_uuid":"AGENT_UUID"}' \
  https://ai.perkinsfund.org/api/traceix/agent/metadata
```

### Expected outputs

Success:

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241023.740849,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": {
    "agent_config": {
      "accepted_file_type": "windows",
      "agent_features": ["classification", "exif"],
      "agent_uuid": "agnt-...",
      "max_file_size": 3145728,
      "requested_delivery_style": "raw"
    },
    "agent_metadata": {
      "agent_created_at": "2026-01-12T16:27:11.903000+00:00",
      "agent_name": "Traceix Windows Fast Triage",
      "agent_stats": { "processed_files": 1 },
      "agent_tags": ["triage", "windows", "soc"]
    }
  },
  "success": true
}
```

Failure (not owned / not accessible / doesn’t exist):

```json
{
  "error": { "error_message": "Agent does not exist" },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241028.700035,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

***

## Run Agent

Endpoint: `/api/traceix/agent/run` Request type: `POST` Content type: `multipart/form-data`

Headers:

* `X-Api-Key: YOUR_API_KEY`
* `X-Agent-Id: AGENT_UUID`

Body:

* `file`: the file to submit (multipart form)

> **NOTE:** This endpoint queues an analysis job and returns a `uuid` you will poll using `/api/traceix/agent/status`.

### Example request

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-agent-id: AGENT_UUID" \
  -F "file=@/path/to/file.exe" \
  https://ai.perkinsfund.org/api/traceix/agent/run
```

### Expected outputs

Success (queued):

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241074.539515,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": {
    "status": "PENDING",
    "uuid": "67fa2864-5c58-4533-b626-3da9dd48bb76"
  },
  "success": true
}
```

Failure (agent does not exist / not accessible):

```json
{
  "error": { "error_message": "Agent does not exist" },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241082.298161,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

***

## Check Agent Run Status

Endpoint: `/api/traceix/agent/status` Request type: `POST` Content type: JSON

Headers:

* `X-Api-Key: YOUR_API_KEY`
* `content-type: application/json`

Body:

* `uuid`: string (the job UUID returned from `/api/traceix/agent/run`)
* `agent_uuid`: string (the agent UUID used to launch the job)

> **NOTE:** You must provide **both** `uuid` and `agent_uuid`.

### Example request

```bash
curl -X POST \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  --data '{"uuid":"RUN_UUID","agent_uuid":"AGENT_UUID"}' \
  https://ai.perkinsfund.org/api/traceix/agent/status
```

### Expected outputs

Success can return **either** a pending status **or** completed results.

Success (pending):

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241148.871836,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": {
    "status": "PENDING",
    "uuid": "67fa2864-5c58-4533-b626-3da9dd48bb76"
  },
  "success": true
}
```

Success (completed example):

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241143.9729,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": {
    "classification": "safe",
    "exif": {
      "FileDescription": "Windows Calculator"
    }
  },
  "success": true
}
```

Failure example:

```json
{
  "error": { "error_message": "Invalid agent UUID" },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241401.4666727,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

***

## Submit Agent Alert

Endpoint: `/api/traceix/agent/alert` Request type: `POST` Content type: JSON

Headers:

* `X-Api-Key: YOUR_API_KEY`
* `content-type: application/json`

Body (required):

* `agent_uuid`: string
* `client_id`: string
* `classification`: string (example: `safe`, `malicious`, etc.)
* `file_path`: string
* `sha256_hash`: string

Body (optional / nullable):

* `capa`: array or null
* `exif`: object or null
* `yara`: string or null

### Example request

```bash
curl -X POST \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  --data '{
    "agent_uuid":"AGENT_UUID",
    "client_id":"test_id",
    "classification":"safe",
    "file_path":"C:\\Windows\\System32\\calc.exe",
    "sha256_hash":"ed369187681a62247e38d930320f1cd771756d0b7b67072d8ec655ef99e14aeb"
  }' \
  https://ai.perkinsfund.org/api/traceix/agent/alert
```

### Expected outputs

Success:

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768240926.097389,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": { "ok": true },
  "success": true
}
```

Failure (invalid agent UUID):

```json
{
  "error": { "error_message": "Invalid agent UUID" },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768240895.260689,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

***

## Get Agent Alerts

Endpoint: `/api/traceix/agent/alerts/get` Request type: `POST` Content type: JSON

Headers:

* `X-Api-Key: YOUR_API_KEY`
* `content-type: application/json`

Body:

* `agent_uuid`: string

### Example request

```bash
curl -X POST \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  --data '{"agent_uuid":"AGENT_UUID"}' \
  https://ai.perkinsfund.org/api/traceix/agent/alerts/get
```

### Expected outputs

Success (example shape):

```json
{
  "error": {},
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768240989.672061,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": [
    {
      "agent_uuid": "agnt-...",
      "alert_id": "alrt_...",
      "alert_timestamp": "2026-01-12T18:02:06.062701+00:00",
      "classification": "safe",
      "client_id": "test_id",
      "event_id": "evt_...",
      "file_path": "C:\\Windows\\System32\\calc.exe",
      "sha256_hash": "ed36...",
      "is_reviewed": false,
      "last_check_in": null,
      "capabilities": null,
      "exif_data": null,
      "yara_rule": null
    }
  ],
  "success": true
}
```

Failure (invalid agent UUID):

```json
{
  "error": { "error_message": "Invalid agent UUID" },
  "request_metadata": {
    "request_id": "req_...",
    "request_timestamp": 1768241001.276291,
    "schema_version": "traceix.agent_output.v1"
  },
  "results": null,
  "success": false
}
```

***

## SDKs

* GitHub: `https://github.com/Perkins-Fund/Traceix-SDK`
* More languages: coming soon…


# OnlyVulns Endpoints


# OnlyVulns API


# PCEF Public Endpoints


# AURA API

AURA is a lightweight malware triage API that classifies uploaded executable files and lets you look up recent or specific scan results by SHA-256. Currently supports Windows PE and Linux ELF; other formats return `unknown`.

* [File Prediction](#file-prediction-endpoint)
* [Latest Scans](#latest-scans-endpoint)
* [Search Scans](#search-scans-endpoint)

### API BASE URL: `https://ai.perkinsfund.org`

***

### File Prediction Endpoint

Endpoint: `/api/predict`

Request type: POST

Data type: File

Headers (optional): X-Api-Key: API KEY

**NOTE: The AI currently only classifies ELF and Windows PE executable file formats. Others will be "unknown".**

#### Example request

```bash
curl -F"filename=@/path/to/file" https://ai.perkinsfund.org/api/predict
```

#### Expected outputs

Success:

```json
{
  ...,
    "results": {
    "class": "safe",
    "created_at": 1743103981.5979574,
    "file_hash": "ed369187681a62247e38d930320f1cd771756d0b7b67072d8ec655ef99e14aeb",
    "time_taken": 0.37021786579862237
  },
  ...
}
```

Unsuccessful:

```json
{
  ...,
  {
   "error": {
      "error_message": "The message"
   }, 
   ...
}
```

***

### Latest Scans Endpoint

Endpoint: `/api/latest`

Request type: POST

Data type:

Headers (optional): X-Api-Key: API KEY

**NOTE: This POST request does not take any parameters, it will return the last 50 scans**

#### Example request

```bash
curl -X POST https://ai.perkinsfund.org/api/latest
```

#### Expected outputs

Success:

```json
{
  ...,
  [
    {
      "class": "unknown",
      "created_at": 1743103290.500192,
      "error": {},
      "file_hash": "008632ed4a903dbc95d7a0d042d77df9bf651f10a26a8d4557eb9d2533193ad1",
      "time_taken": 0.0004930980503559113
    },
    {
      "class": "unknown",
      "created_at": 1743099196.4861066,
      "error": {},
      "file_hash": "f5f5ac913edc3fa09bc71ff99d6b84fa63c5987f9713fdb1d55f590ac283b263",
      "time_taken": 0.000505556003190577
    }
  ],
  ...
}
```

Unsuccessful:

```json
{
  ...,
  {
    "error_message": {"error_message": "..."},
    "results": []
  },
  ...
}
```

***

### Search Scans Endpoint

Endpoint: `/api/search`

Request type: POST

Data type: JSON

Headers (required): X-Api-Key: API KEY

**NOTE: This endpoint requires an API key. You can get an API key here: <https://perkinsfund.org/login>**

#### Example request

```bash
curl -XPOST -H "x-api-key: USER KEY" \
  -H "content-type: application/json" \
  --data '{"sha256":"USER SHA256 HASH"}' \
  https://ai.perkinsfund.org/api/search
```

#### Expected outputs

Success:

```json
{
  ...,
  "results": {
    "class": "safe",
    "created_at": 1742832170.874544,
    "error": {},
    "file_hash": "975d2ab9067a1b21a46ce9d87e6ab589636d128fcba4f49e53392815ebc72d77",
    "time_taken": 0.7284463751129806
  },
  ...
}
```

Unsuccessful:

```json
{
  ...,
  "error": {
    "error_message": "SHA256 hash did not pass heuristics check, is it a hash?" OR "invalid API key supplied"
  },
  ...
}
```


# YARA Playground

A small YARA utility API for iterating fast: validate/compile rules, test them against a file you upload, or run them against a built-in benign/malware sample set to see what they hit.

* [Build Yara Rule](#building-yara-rules-endpoint)
* [Test Yara Rule](#testing-yara-rules-endpoint)
* [Scan with Yara Rule](#scanning-yara-rules-endpoint)

### API BASE URL: `https://ai.perkinsfund.org`

***

### Building Yara Rules Endpoint

Endpoint: `/api/yara/build`

Request type: POST

Data type: JSON

Headers (optional): X-Api-Key: `API KEY`

**NOTE: Compiles the provided Yara rule and returns whether the rule is valid or not.**

#### Example request

```bash
curl -X POST -H "Content-Type: application/json" \
   -d '{"rule": "rule dummy { condition: true }"}' \
   https://ai.perkinsfund.org/api/yara/build
```

#### Expected outputs

Success:

```json
{
  ...,
   "results": {
    "success": "YARA rule compiled successfully"
  },
  ...
}
```

Unsuccessful:

```json
{
  ...,
  "error": {
    "error_message": "YARA rule syntax error: line 1: syntax error, unexpected identifier, expecting  <condition>"
  },
   ...
}
```

***

### Testing Yara Rules Endpoint

Endpoint: `/api/yara/test`

Request type: POST

Data type: multipart/form-data

Headers (optional): X-Api-Key: `API KEY`

**NOTE: Tests a Yara rule against a provided uploaded file.**

#### Example request

```bash
curl -F "yara_rule=@rule.yar" \
  -F "test_file=@sample.exe" \
  https://ai.perkinsfund.org/api/yara/test
```

#### Expected outputs

Success:

```json
{
  ...,
  "results": [
    {
      "matched_strings": [],
      "rule": "test"
    }
  ],
  ...
}
```

Unsuccessful:

```json
{
  ...,
  "error": {
    "error_message": "YARA rule syntax error: line 2: syntax error, unexpected identifier, expecting <condition>" OR "No matches found using YARA rule"
  }
   ...
}
```

***

### Scanning Yara Rules Endpoint

Endpoint: `/api/yara/scan`

Request type: POST

Data type: JSON

Headers (optional): X-Api-Key: `API KEY`

Headers (required): X-File-Type: benign or malware

**NOTE: Runs the provided Yara rule against built-in files of the specific type specified in the X-File-Type header.**

#### Example request

```bash
curl -X POST -H "Content-Type: application/json" \
  -H "x-file-type: benign" \
  -d '{"rule": "rule dummy { condition: true }"}' \
  https://ai.perkinsfund.org/api/yara/scan
```

#### Expected outputs

Success:

```json
{
  ...,
  "results": [
    "4c2765686236234db7693c622373c44cda172536f0066820fed70a1ca86519dd",
    "6312581860b1873dedeb8c2cd916fb27baa061f62b0cde44167f4cefebe0628a",
    "862588b2f549abd71bc219dab6e3627ec792cefd2ee6ff0857ccc4fd2e552cc6",
    "8109d3330a58d934fc0bf989b06ca612a317e2085f6477a8b8f8296b452d1ed0",
    "a4940a198a5d2ef2d68e3d643058ed1ee123ce3f8ef6e9e923360d80f81b684d",
    "52f95f4a253c431221852fa0e0fb9ab94752fdee597750949460c74242887b09",
    "d1b807df597b47d162d7235d8389e366d24a2cc2e379f48bebbe7855f420e660",
    ... 
  ],  
  ...
}
```

Unsuccessful:

```json
{
  ...,
  "error": {
    "error_message": "YARA rule syntax error: line 2: syntax error, unexpected identifier, expecting <condition>" OR "No matches found for YARA rule in 50 samples"
  }
   ...
}
```


# Ransom Note Comparison

Upload a ransom note to identify likely ransomware families by similarity, or search by a keyword to find known public decryptor links when they exist.

* [Compare Notes](#compare-notes)
* [Search for Decryptors](#search-decryptors)

### API BASE URL: `https://ai.perkinsfund.org`

***

### Compare Notes

Endpoint: `/api/tool/ransomnotes`

Request type: POST

Data type: File

Headers (optional): X-Api-Key: API KEY

**NOTE: It is possible to get more than one item per list**

#### Example request

```bash
curl -F"file=@FILENAME" https://ai.perkinsfund.org/api/tool/ransomnotes
```

#### Expected outputs

Success:

```json
{
  ...
  "results": [
    [
      "8base",
      "91%"
    ]
  ],
  ...
}
```

Unsuccessful:

```json
{
  ...
  "error": {
    "error_message": "MESSAGE"
  },
  ...
}
```

***

### Search Decryptors

Endpoint: `/api/tool/ransomnotes/links`

Request type: POST

Data type: JSON

Headers (optional): X-Api-Key: API KEY

**NOTE: It is possible to get more than one item per list**

#### Example request

```bash
curl -XPOST -H "content-type: application/json" --data '{"search_term": "akira"}' https://ai.perkinsfund.org/api/tool/ransomnotes/links
```

#### Expected outputs

Success:

```json
{
  ...
  "results": [
    "https://files.avast.com/files/decryptor/avast_decryptor_akira64.exe"
  ],
  ...
}
```

Unsuccessful:

```json
{
  ...
  "error": {
    "error_message": "No search term specified?"
  },
  ...
}
```


