Stryda.

Developer Documentation

Stryda API

Run adversarial red-team datasets against any LLM endpoint and get a quantified vulnerability-resistance score — straight from your terminal, scripts, or CI pipeline.

Introduction

The Stryda API lets you test any HTTP-accessible language model against curated adversarial prompt datasets. Each request sends a batch of attack prompts to your model, evaluates whether the model resisted each attack, and returns a single resistance score (0–100) plus a per-vector breakdown mapped to OWASP LLM Top 10, MITRE ATLAS, and NIST AI RMF.

The API runs entirely on the edge. There are three dataset tiers — small, medium, and large — each returning a complete JSON result with the score and per-vector breakdown.

Base URL

https://stryda.online

Authentication

Programmatic requests authenticate with an API key passed in the X-API-Key header. Keys are created from your dashboard and shown once at creation — store them in a secrets manager.

X-API-Key: sk_stryda_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Keys are prefixed with sk_stryda_.
  • Only the SHA-256 hash is stored server-side; the raw key is never persisted.
  • Each key carries the datasets:run and datasets:read scopes.
  • Up to 5 keys per account. Revoking a key takes effect immediately.

Create and manage keys at /dashboard/api-keys.

Dataset tiers

Each tier defines how many adversarial prompts are sent and how many credits it costs.

TierPromptsCreditsPriceBest for
small502$14.40Quick smoke test / baseline
medium1505$36.00Full coverage across all 10 vectors
large50010$72.00Deep audit / compliance testing

All three tiers are available from both the browser runner and the API, and return a complete JSON result. Credits are deducted atomically before the run starts and automatically refunded if the run fails to start or crashes mid-execution.

Run a scan

POST /api/datasets/api-run

Send a tier and your model's endpoint. The API delivers the prompts to your model, evaluates the responses, and returns the scored result.

Request body

FieldTypeRequiredDescription
tierstringYessmall · medium · large
endpoint_urlstringYesHTTPS endpoint of the model under test
model_idstringNoModel identifier used for benchmark grouping
auth_configobjectNoHow to authenticate against your endpoint (see below)
evaluation_modestringNoheuristic (default) · llm_judge · hybrid
fail_thresholdintNo0–100. If the score is below this, ci_failed is true
publish_to_benchmarkboolNoDefaults true. Set false to keep the run private
pipeline_modeboolNoEnable RAG / indirect-injection testing

Example request

curl -X POST https://stryda.online/api/datasets/api-run \
  -H "X-API-Key: sk_stryda_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tier": "large",
    "endpoint_url": "https://api.openai.com/v1/chat/completions",
    "model_id": "gpt-4o",
    "evaluation_mode": "hybrid",
    "auth_config": {
      "auth_type": "openai_compatible",
      "api_key": "sk-your-provider-key"
    }
  }'

Response

{
  "run_id": "0f4c2b9a-1e7d-4a3f-8b21-9c5e7d2a1f00",
  "model_id": "gpt-4o",
  "tier": "large",
  "total_prompts": 500,
  "passed": 431,
  "failed": 69,
  "resistance_score": 86,
  "interpretation": { "label": "Low Risk", "severity": "low" },
  "vector_scores": {
    "markdown_image_exfiltration": 92,
    "lexical_concatenation": 78,
    "ast_fragmentation": 64
  },
  "credits_spent": 10,
  "ci_failed": false,
  "fail_threshold": 0,
  "execution_metrics": {
    "total_duration_ms": 48213,
    "avg_prompt_duration_ms": 96,
    "p95_prompt_duration_ms": 210,
    "rate_limited_count": 3,
    "retry_count": 3,
    "failed_count": 0
  },
  "evaluation_mode": "hybrid",
  "pipeline_mode": false
}

The resistance_score is the percentage of prompts your model resisted. Prompts that could not be evaluated (network or evaluator errors) are excluded from scoring rather than counted as passes.

Target authentication

Use auth_config to tell Stryda how to authenticate against your model endpoint. The supported auth_type values are:

  • openai_compatible — sends Authorization: Bearer <api_key> (default).
  • bearer — same Bearer scheme, explicit.
  • basic_auth — HTTP Basic using basic_username / basic_password.
  • custom_header — sends custom_header_name: custom_header_value.
  • none — no auth header.
"auth_config": {
  "auth_type": "custom_header",
  "custom_header_name": "x-api-key",
  "custom_header_value": "abc123"
}

Custom header names are validated and reserved headers (Authorization, Host, Cookie, …) cannot be overridden. Header values may not contain control characters.

Evaluation modes

Stryda decides whether a model resisted each attack using one of three modes:

  • heuristic — fast, deterministic pattern detection. No extra model calls. Default.
  • llm_judge — a judge model scores each response. Most accurate, uses the same endpoint/credentials as the target.
  • hybrid — heuristics first, then the judge confirms ambiguous cases. Balanced accuracy and speed.

In llm_judge and hybrid modes, a prompt whose verdict can't be produced is marked as an error and excluded from the score — never silently passed.

RAG pipeline testing

Set pipeline_mode: true to test indirect prompt injection through a retrieval pipeline. For each prompt, Stryda first calls your retrieval_endpoint, injects the adversarial content into the retrieved context, then sends it to your main endpoint.

{
  "tier": "large",
  "endpoint_url": "https://api.example.com/chat",
  "pipeline_mode": true,
  "retrieval_endpoint": "https://your-rag.example.com/retrieve",
  "retrieval_auth": { "type": "bearer", "token": "rag-token" }
}

CI/CD gating

Set fail_threshold to fail a build when the resistance score drops below your bar. The response field ci_failed reflects the gate.

# GitHub Actions step
- name: Stryda AI security scan
  run: |
    RESULT=$(curl -s -X POST https://stryda.online/api/datasets/api-run \
      -H "X-API-Key: ${{ secrets.STRYDA_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{"tier":"medium","endpoint_url":"'"$MODEL_URL"'","model_id":"ci-model","fail_threshold":70}')
    echo "$RESULT"
    echo "$RESULT" | grep -q '"ci_failed":false' || { echo "Resistance below threshold"; exit 1; }

Errors & rate limits

StatusMeaning
401Invalid API key or missing the datasets:run scope
402Insufficient credits (response includes credits_required)
422Invalid body: bad tier, non-HTTPS URL, blocked host, or unexpected field
429Rate limited — includes a Retry-After header
500Run failed (credits are refunded)
  • Rate limit: 10 runs per 5 minutes per account.
  • SSRF protection: private, loopback, and link-local hosts are rejected.
  • Strict bodies: unknown fields are rejected — send only documented keys.

Managing API keys

GET /api/api-keys— list your keys (metadata only)

POST /api/api-keys— create a key, returned once

DELETE /api/api-keys?id=<keyId>— revoke a key

These management endpoints use your logged-in dashboard session, not the API key itself. Manage everything visually at /dashboard/api-keys.

Need a hands-on audit instead?

The API is self-serve red-teaming. For an expert-led engagement with a written report and remediation guidance, open a case with our team.