Authentication

All API requests require an API key passed via the X-API-Key header.

X-API-Key: your_api_key_here

Request an API key from the Get API Key page. Free tier keys are provisioned within 24 hours.

The GET /health endpoint does not require authentication.

Base URL

All endpoints are served from:

https://api.starksentinel.com

Health Check

GET /health

Returns the current status of the SENTINEL API. No authentication required.

Example Request

curl https://api.starksentinel.com/health

Example Response

{
  "status": "healthy",
  "version": "1.1.0",
  "timestamp": "2026-04-02T12:00:00.000Z"
}

Response Fields

FieldTypeDescription
statusstringService status. "healthy" when operational.
versionstringCurrent API version.
timestampstringISO 8601 server timestamp.

Generate Proof

POST /v1/prove

Generates a STARK proof attesting that a set of behavioral observations stays within defined EWMA control limits. The proof is zero-knowledge: raw observations are used to compute the EWMA in-memory, then discarded. Only public inputs (observation count, final EWMA, control limits, pass/fail) are included in the proof envelope.

Request Body

FieldTypeRequiredDescription
observationsnumber[]YesArray of behavioral metric values (integers). Minimum 1 observation.
baseline_meannumberYesExpected baseline mean for the EWMA calculation.
uclnumberYesUpper Control Limit. EWMA must stay below this value to pass.
lclnumberYesLower Control Limit. EWMA must stay above this value to pass.

Example Request

# Generate a STARK proof for 8 behavioral observations
curl -X POST https://api.starksentinel.com/v1/prove \
  -H "X-API-Key: $SENTINEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "observations": [95, 98, 92, 97, 100, 94, 96, 99],
    "baseline_mean": 96,
    "ucl": 110,
    "lcl": 80
  }'

Example Response

{
  "public_inputs": {
    "num_observations": 8,
    "baseline_mean": 96,
    "final_ewma": 95,
    "ucl": 110,
    "lcl": 80,
    "within_limits": true
  },
  "proof_bytes": "base64-encoded-stark-proof...",
  "metadata": {
    "generation_time_ms": 9,
    "proof_size_bytes": 6761,
    "security_level": 96
  }
}

Response Fields

FieldTypeDescription
public_inputs.num_observationsnumberCount of observations included in the proof.
public_inputs.baseline_meannumberThe baseline mean used for EWMA seeding.
public_inputs.final_ewmanumberFinal EWMA value after processing all observations.
public_inputs.uclnumberUpper Control Limit used in the proof.
public_inputs.lclnumberLower Control Limit used in the proof.
public_inputs.within_limitsbooleantrue if EWMA stayed within [lcl, ucl] for all observations.
proof_bytesstringBase64-encoded STARK proof. Pass this to /v1/verify.
metadata.generation_time_msnumberTime to generate the proof in milliseconds.
metadata.proof_size_bytesnumberSize of the proof in bytes.
metadata.security_levelnumberSecurity level in bits (96-bit).

Privacy Guarantee

Individual observation values are never included in the response. The proof attests to the statistical properties (EWMA within control limits) without revealing the underlying data. This is the Prove-Don't-Share architecture.

Verify Proof

POST /v1/verify

Verifies a previously generated STARK proof. Verification confirms that the proof was correctly generated and that the public inputs are authentic. Verification is always free and does not count against your monthly proof limit.

Request Body

FieldTypeRequiredDescription
proof_bytesstringYesBase64-encoded STARK proof from the /v1/prove response.
public_inputsobjectYesThe public_inputs object from the prove response.

Example Request

# Verify a previously generated proof
curl -X POST https://api.starksentinel.com/v1/verify \
  -H "X-API-Key: $SENTINEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "proof_bytes": "base64-encoded-stark-proof...",
    "public_inputs": {
      "num_observations": 8,
      "baseline_mean": 96,
      "final_ewma": 95,
      "ucl": 110,
      "lcl": 80,
      "within_limits": true
    }
  }'

Example Response

{
  "valid": true,
  "public_inputs": {
    "num_observations": 8,
    "baseline_mean": 96,
    "final_ewma": 95,
    "ucl": 110,
    "lcl": 80,
    "within_limits": true
  },
  "metadata": {
    "verification_time_ms": 2
  }
}

Response Fields

FieldTypeDescription
validbooleantrue if the proof is cryptographically valid.
public_inputsobjectEcho of the public inputs verified against the proof.
metadata.verification_time_msnumberTime to verify the proof in milliseconds.

Client-Side Verification

For zero-trust verification, use the open-source WASM verifier. It runs entirely client-side — no network calls, no trust in SENTINEL required. See the Quickstart Guide for setup instructions.

Error Codes

SENTINEL uses standard HTTP status codes. Error responses include a JSON body with a message field.

CodeMeaningCommon Cause
400Bad RequestMissing or invalid fields in the request body. Check that observations is a non-empty array and ucl > lcl.
401UnauthorizedMissing or invalid X-API-Key header.
429Too Many RequestsMonthly proof limit exceeded for your tier. Upgrade your plan or wait for the next billing cycle.
500Internal Server ErrorUnexpected server error. Retry with exponential backoff. If persistent, contact support.

Error Response Format

{
  "error": "Bad Request",
  "message": "observations must be a non-empty array of numbers"
}

Rate Limits

Rate limits are based on your plan tier and apply to proof generation only. Verification calls and health checks are unlimited.

TierProofs per MonthRequests per Second
Free1005
Pro5,00050
EnterpriseUnlimitedCustom

When you exceed your monthly limit, subsequent /v1/prove calls return 429 Too Many Requests. Rate limit headers are included in every response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 2026-05-01T00:00:00Z