Events (Interactions) API
The Events API manages AIInteractions — the canonical data model in Noxys representing every AI interaction (prompt submission, response received, etc.).
Create Interaction
Record a single AI interaction from your application.
Endpoint: POST /api/v1/interactions
Request:
curl -X POST https://api.noxys.cloud/api/v1/interactions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"platform_id": "chatgpt",
"interaction_type": "prompt",
"content_hash": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3",
"content_metadata": {
"url": "https://chat.openai.com",
"model": "gpt-4o",
"text": "How do I reset my password?"
},
"classifications": [
{
"type": "EMAIL",
"value": "alice@acme.fr",
"score": 0.98,
"start": 24,
"end": 42
}
],
"risk_score": 0.25,
"direction": "outbound",
"source": "browser_extension",
"user_id": "00000000-0000-0000-0000-000000000010"
}'
Required Fields:
| Field | Type | Description |
|---|---|---|
platform_id | String | AI platform: chatgpt, claude, gemini, deepseek, perplexity, mistral, copilot, poe, huggingchat, grok, etc. |
content_hash | String | SHA-256 hex digest of the interaction content (raw text never stored) |
Optional Fields:
| Field | Type | Default | Description |
|---|---|---|---|
interaction_type | String | prompt | Type of interaction: prompt, completion, tool_call, embedding |
content_metadata | Object | Arbitrary metadata (URL, model name, text snippet, etc.) | |
classifications | Array | [] | Array of detected PII (see Classification schema below) |
risk_score | Float | 0.0 | Risk level 0-1 (0=safe, 1=maximum risk) |
direction | String | outbound | Data flow: outbound (user → AI) or inbound (AI → user) |
source | String | browser_extension | Where interaction came from: browser_extension, proxy, endpoint_agent, api |
user_id | UUID | null | User who triggered the interaction |
Classification Schema:
{
"type": "EMAIL",
"value": "alice@acme.fr",
"score": 0.98,
"start": 24,
"end": 42
}
| Field | Type | Description |
|---|---|---|
type | String | PII type: EMAIL, PHONE, CREDIT_CARD, IBAN, SSN, NIR, SIRET, IP_ADDRESS, API_KEY, PERSON_NAME, etc. |
value | String | The detected sensitive value (shown in logs/alerts only, never for raw content) |
score | Float | Confidence 0-1 |
start | Integer | Character offset start in original content |
end | Integer | Character offset end in original content |
Response (201 Created):
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"tenant_id": "00000000-0000-0000-0000-000000000001",
"timestamp": "2026-03-20T14:32:00Z",
"platform_id": "chatgpt",
"interaction_type": "prompt",
"content_hash": "a665a45920...",
"classifications": [
{
"type": "EMAIL",
"value": "alice@acme.fr",
"score": 0.98,
"start": 24,
"end": 42
}
],
"risk_score": 0.25,
"direction": "outbound",
"source": "browser_extension",
"user_id": "00000000-0000-0000-0000-000000000010",
"policy_decisions": [
{
"policy_id": "c8d4e2f1-aaaa-bbbb-cccc-000000000001",
"policy_name": "Block PII on ChatGPT",
"action": "block",
"matched_conditions": 2
}
]
}
Batch Create Interactions
For high-volume scenarios, send up to 500 interactions in a single request.
Endpoint: POST /api/v1/interactions/batch
Request:
curl -X POST https://api.noxys.cloud/api/v1/interactions/batch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"platform_id": "chatgpt",
"content_hash": "a665a45920...",
"risk_score": 0.25,
"user_id": "user-1"
},
{
"platform_id": "claude",
"content_hash": "b776b56a31...",
"risk_score": 0.15,
"user_id": "user-2"
},
{
"platform_id": "gemini",
"content_hash": "c887c67b42...",
"risk_score": 0.45
}
]'
Request Array: Array of interaction objects (same schema as single create)
Response (200 OK):
{
"received": 3,
"stored": 3
}
Notes:
- Invalid items are silently skipped
- Check the
storedcount to confirm all succeeded - Returns 200 even if some items fail (check individual item validity)
List Interactions
Query and paginate through interactions with optional filtering.
Endpoint: GET /api/v1/interactions
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | Integer | 1 | Page number (1-based) |
limit | Integer | 50 | Items per page (max: 500) |
platform_id | String | - | Filter by platform: chatgpt, claude, gemini, etc. |
risk_score_min | Float | - | Minimum risk score (0-1) |
risk_score_max | Float | - | Maximum risk score (0-1) |
classification_type | String | - | Filter by PII type: EMAIL, PHONE, CREDIT_CARD, etc. |
source | String | - | Filter by source: browser_extension, proxy, api, endpoint_agent |
start_date | ISO 8601 | - | Start timestamp (e.g., 2026-03-15T00:00:00Z) |
end_date | ISO 8601 | - | End timestamp |
user_id | UUID | - | Filter by user UUID |
direction | String | - | Filter by direction: outbound or inbound |
sort | String | -timestamp | Sort by field with optional - for descending: -timestamp, risk_score, platform_id |
Example — High-Risk ChatGPT Interactions:
curl "https://api.noxys.cloud/api/v1/interactions?platform_id=chatgpt&risk_score_min=0.8&limit=100" \
-H "Authorization: Bearer $TOKEN"
Example — Interactions with Email PII:
curl "https://api.noxys.cloud/api/v1/interactions?classification_type=EMAIL&sort=-timestamp&limit=50" \
-H "Authorization: Bearer $TOKEN"
Response (200 OK):
{
"data": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"platform_id": "chatgpt",
"interaction_type": "prompt",
"risk_score": 0.95,
"classifications": [
{
"type": "EMAIL",
"value": "alice@acme.fr",
"score": 0.98,
"start": 24,
"end": 42
}
],
"timestamp": "2026-03-20T14:32:00Z",
"direction": "outbound",
"source": "browser_extension",
"user_id": "00000000-0000-0000-0000-000000000010",
"policy_decisions": [
{
"policy_id": "c8d4e2f1-aaaa-bbbb-cccc-000000000001",
"policy_name": "Block PII on ChatGPT",
"action": "block",
"matched_conditions": 2
}
]
}
],
"total": 1234,
"limit": 100,
"offset": 0
}
Response Headers:
X-Total-Count: 1234
X-Page: 1
X-Per-Page: 100
X-Total-Pages: 13
Get Interaction Details
Retrieve a single interaction by ID.
Endpoint: GET /api/v1/interactions/:id
Example:
curl https://api.noxys.cloud/api/v1/interactions/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
-H "Authorization: Bearer $TOKEN"
Response (200 OK): Full interaction object (same schema as create response).
If not found (404):
{
"error": "Interaction not found"
}
Search Interactions
Search by content hash or timestamp range.
Endpoint: GET /api/v1/interactions/search
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_hash | String | Yes | SHA-256 hash to search for |
Example:
# Find interaction by content hash
curl "https://api.noxys.cloud/api/v1/interactions/search?content_hash=a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3" \
-H "Authorization: Bearer $TOKEN"
Response (200 OK):
[
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"platform_id": "chatgpt",
"content_hash": "a665a45920...",
"timestamp": "2026-03-20T14:32:00Z",
"risk_score": 0.25,
"classifications": [...]
}
]
Delete Interaction
Remove an interaction (admin only, requires GDPR right-to-be-forgotten authorization).
Endpoint: DELETE /api/v1/interactions/:id
Example:
curl -X DELETE https://api.noxys.cloud/api/v1/interactions/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
-H "Authorization: Bearer $TOKEN"
Response (204 No Content) — No response body.
Notes:
- Requires admin role
- Deletion is immutable and cannot be reversed
- Use for GDPR/CCPA right-to-be-forgotten requests
- Audit log records the deletion
Code Examples
Python: Create and List Interactions
import requests
import hashlib
import json
BASE_URL = "https://api.noxys.cloud/api/v1"
# 1. Login
response = requests.post(
f"{BASE_URL}/auth/login",
json={"email": "alice@acme.fr", "password": "demo123"}
)
token = response.json()["token"]
headers = {"Authorization": f"Bearer {token}"}
# 2. Create interaction
content = "Please contact alice@acme.fr for details"
content_hash = hashlib.sha256(content.encode()).hexdigest()
response = requests.post(
f"{BASE_URL}/interactions",
headers=headers,
json={
"platform_id": "chatgpt",
"content_hash": content_hash,
"content_metadata": {"text": content},
"risk_score": 0.8,
"classifications": [
{
"type": "EMAIL",
"value": "alice@acme.fr",
"score": 0.98,
"start": 22,
"end": 38
}
]
}
)
print("Created:", response.json()["id"])
# 3. List high-risk interactions
response = requests.get(
f"{BASE_URL}/interactions?platform_id=chatgpt&risk_score_min=0.7&limit=50",
headers=headers
)
data = response.json()
print(f"Found {data['total']} total, showing {len(data['data'])} on this page")
for interaction in data["data"]:
print(f" {interaction['id']}: {interaction['platform_id']} ({interaction['risk_score']})")
# 4. Batch create
interactions = [
{
"platform_id": "claude",
"content_hash": hashlib.sha256(b"test 1").hexdigest(),
"risk_score": 0.1
},
{
"platform_id": "gemini",
"content_hash": hashlib.sha256(b"test 2").hexdigest(),
"risk_score": 0.5
}
]
response = requests.post(
f"{BASE_URL}/interactions/batch",
headers=headers,
json=interactions
)
print(f"Batch: {response.json()['received']} received, {response.json()['stored']} stored")
JavaScript: Real-Time Interaction Logging
const BASE_URL = "https://api.noxys.cloud/api/v1";
async function logInteraction(token, platformId, contentText, riskScore) {
const crypto = require("crypto");
const contentHash = crypto.createHash("sha256")
.update(contentText)
.digest("hex");
const response = await fetch(`${BASE_URL}/interactions`, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
platform_id: platformId,
content_hash: contentHash,
content_metadata: { text: contentText },
risk_score: riskScore
})
});
if (!response.ok) {
throw new Error(`API error: ${response.statusText}`);
}
return await response.json();
}
// Usage
const token = "eyJhbGc...";
const interaction = await logInteraction(token, "chatgpt", "Contact me at test@example.com", 0.9);
console.log("Logged interaction:", interaction.id);
Go: Batch Upload with Error Handling
package main
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
)
const BaseURL = "https://api.noxys.cloud/api/v1"
type Interaction struct {
PlatformID string `json:"platform_id"`
ContentHash string `json:"content_hash"`
RiskScore float64 `json:"risk_score"`
}
func batchCreateInteractions(token string, interactions []Interaction) error {
payload, _ := json.Marshal(interactions)
req, _ := http.NewRequest("POST", BaseURL+"/interactions/batch", bytes.NewReader(payload))
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("API error: %s", string(body))
}
var result struct {
Received int `json:"received"`
Stored int `json:"stored"`
}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Batch: %d received, %d stored\n", result.Received, result.Stored)
return nil
}
func main() {
token := "eyJhbGc..."
interactions := []Interaction{
{
PlatformID: "chatgpt",
ContentHash: hashSHA256("test 1"),
RiskScore: 0.2,
},
{
PlatformID: "claude",
ContentHash: hashSHA256("test 2"),
RiskScore: 0.8,
},
}
batchCreateInteractions(token, interactions)
}
func hashSHA256(s string) string {
hash := sha256.Sum256([]byte(s))
return hex.EncodeToString(hash[:])
}
Best Practices
- Always hash content — Never send raw prompts; use SHA-256
- Include classifications — Detect and report PII types
- Batch when possible — Use
/batchfor >10 interactions/minute - Set accurate risk scores — Helps with alerting and trend analysis
- Use metadata — Store URL, model, timestamp for context
- Handle rate limits — Implement exponential backoff
- Log failures — Don't silently drop interactions; retry or alert
What's Next?
- Policies API — Create DLP rules
- Webhooks — Receive real-time alerts
- Users API — Manage team members