Code Examples
Every example below sends the same request: POST https://api.inkog.io/v1/scan with a JSON body of files[] entries, each carrying a repository-relative path and the file content. See the Scan endpoint for the full contract and response fields.
Set INKOG_API_KEY in your environment before running any example. Get a key from Dashboard → API Keys at app.inkog.io .
cURL
Uses jq to embed the file content safely:
# Scan one file. The API never reads your disk: send file contents in the JSON body.
curl -X POST https://api.inkog.io/v1/scan \
-H "Authorization: Bearer $INKOG_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile code ./src/agent.py \
'{files: [{path: "src/agent.py", content: $code}], policy: "balanced", output: "detailed"}')"Python
import os
from pathlib import Path
import requests
API_URL = "https://api.inkog.io/v1/scan"
def scan(paths: list[str], api_key: str, policy: str = "balanced") -> dict:
"""Scan source files for AI agent security risks."""
files = [{"path": p, "content": Path(p).read_text()} for p in paths]
response = requests.post(
API_URL,
headers={"Authorization": f"Bearer {api_key}"},
json={"files": files, "policy": policy, "output": "detailed"},
timeout=120,
)
response.raise_for_status()
return response.json()
result = scan(["src/agent.py", "src/tools.py"], os.environ["INKOG_API_KEY"])
print(f"Risk score: {result['risk_score']}/100")
print(f"Findings: {result['summary']['total']}")
for finding in result["findings"]:
print(f" [{finding['severity']}] {finding['file']}:{finding['line']} {finding['pattern_id']}")JavaScript (Node.js 18+)
import { readFile } from 'node:fs/promises';
const API_URL = 'https://api.inkog.io/v1/scan';
async function scan(paths, apiKey, policy = 'balanced') {
const files = await Promise.all(
paths.map(async (path) => ({ path, content: await readFile(path, 'utf8') })),
);
const response = await fetch(API_URL, {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ files, policy, output: 'detailed' }),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`Scan failed: ${error}`);
}
return response.json();
}
const result = await scan(['src/agent.ts', 'src/tools.ts'], process.env.INKOG_API_KEY);
console.log(`Risk score: ${result.risk_score}/100`);
console.log(`Findings: ${result.summary.total}`);
for (const f of result.findings) {
console.log(` [${f.severity}] ${f.file}:${f.line} ${f.pattern_id}`);
}Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
const apiURL = "https://api.inkog.io/v1/scan"
type FileInput struct {
Path string `json:"path"`
Content string `json:"content"`
}
type ScanRequest struct {
Files []FileInput `json:"files"`
Policy string `json:"policy,omitempty"`
Output string `json:"output,omitempty"`
}
type Finding struct {
PatternID string `json:"pattern_id"`
Severity string `json:"severity"`
File string `json:"file"`
Line int `json:"line"`
Message string `json:"message"`
}
type ScanResponse struct {
Success bool `json:"success"`
RiskScore int `json:"risk_score"`
Summary struct{ Total int `json:"total"` } `json:"summary"`
Findings []Finding `json:"findings"`
}
func scan(paths []string, apiKey string) (*ScanResponse, error) {
req := ScanRequest{Policy: "balanced", Output: "detailed"}
for _, p := range paths {
content, err := os.ReadFile(p)
if err != nil {
return nil, err
}
req.Files = append(req.Files, FileInput{Path: p, Content: string(content)})
}
body, _ := json.Marshal(req)
httpReq, err := http.NewRequest("POST", apiURL, bytes.NewReader(body))
if err != nil {
return nil, err
}
httpReq.Header.Set("Authorization", "Bearer "+apiKey)
httpReq.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("scan failed: HTTP %d", resp.StatusCode)
}
var result ScanResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
result, err := scan([]string{"src/agent.go"}, os.Getenv("INKOG_API_KEY"))
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
}
fmt.Printf("Risk score: %d/100\n", result.RiskScore)
fmt.Printf("Findings: %d\n", result.Summary.Total)
for _, f := range result.Findings {
fmt.Printf(" [%s] %s:%d %s\n", f.Severity, f.File, f.Line, f.PatternID)
}
}Scanning a whole repository
The API takes file contents, so a directory scan is a loop over files plus one request. The CLI does this for you and also applies .gitignore, skips vendored code, and redacts secrets before upload:
npx -y @inkog-io/cli scan .CI/CD Integration
For GitHub Actions, GitLab CI, and other pipelines, see CI/CD Integration.
Last updated on