Advanced Features

Optimize performance and reduce latency with bulk submission, field filtering, idempotency, ETag caching, and API versioning.

Bulk Intent Submission

Submit up to 50 intents concurrently in a single API call. The pipeline processes all intents in parallel via asyncio.gather, and partial failures don't abort the batch — each result includes either a decision or an error.

Endpoint

POST https://api.gaas.is/v1/intents/batch

Request Body

{
  "intents": [
    { "agent": {...}, "action": {...}, "payload": {...}, ... },
    { "agent": {...}, "action": {...}, "payload": {...}, ... },
    { "agent": {...}, "action": {...}, "payload": {...}, ... }
  ]
}

Response Structure

{
  "results": [
    { "success": true, "intent_id": "int_001", "decision": {...} },
    { "success": true, "intent_id": "int_002", "decision": {...} },
    { "success": false, "intent_id": "int_003", "error": {...} }
  ],
  "total": 3,
  "succeeded": 2,
  "failed": 1
}

Python (gaas_sdk)

from gaas_sdk import GaaSClient, build_intent

async with GaaSClient("https://api.gaas.is", headers={"X-API-Key": "your_key"}) as client:
    intents = [build_intent(...) for _ in range(10)]
    response = await client.submit_intents_bulk(intents)

    # Handle partial failures
    for result in response.results:
        if result.success:
            print(f"Intent {result.intent_id}: {result.decision.verdict}")
        else:
            print(f"Intent {result.intent_id} failed: {result.error}")

TypeScript (@gaas/sdk)

import { GaaSClient, buildIntent } from '@gaas/sdk';

const client = new GaaSClient({
  baseUrl: 'https://api.gaas.is',
  headers: { 'X-API-Key': 'your_key' },
});

const intents = new Array(10).fill(null).map(() => buildIntent({...}));
const response = await client.submitIntentsBulk(intents);

response.results.forEach((result) => {
  if (result.success) {
    console.log(`Intent ${result.intentId}: ${result.decision.verdict}`);
  } else {
    console.error(`Intent ${result.intentId} failed: ${result.error}`);
  }
});

Java (com.gaas.sdk)

import com.gaas.sdk.*;

GaaSClient client = new GaaSClient("https://api.gaas.is", "your_key");
List<IntentDeclaration> intents = new ArrayList<>();
// ... populate intents ...

BulkIntentResponse response = client.submitIntentsBulk(intents);

for (IntentResult result : response.getResults()) {
  if (result.isSuccess()) {
    System.out.println("Intent " + result.getIntentId() + ": " + result.getDecision().getVerdict());
  } else {
    System.err.println("Intent " + result.getIntentId() + " failed: " + result.getError());
  }
}
Rate limiting: Bulk submissions count as a single request against the intent tier rate limit (20 requests/minute). The rate limiter does not multiply by the number of intents in the batch.

Field Filtering (Sparse Responses)

Reduce bandwidth and improve mobile performance by requesting only specific fields from the response. Works on all endpoints — no per-route configuration needed.

Usage

Append a ?fields= query parameter with comma-separated dot-notation paths:

GET https://api.gaas.is/v1/intents/{id}/decision?fields=decision.verdict,decision.risk_assessment.score

Response

{
  "decision": {
    "verdict": "APPROVE",
    "risk_assessment": {
      "score": 0.23
    }
  }
}

The response includes an X-GaaS-Fields-Filtered: true header when filtering is active. Error responses (4xx/5xx) pass through unfiltered.

Python (gaas_sdk)

response = await client.submit_intent(
    intent,
    fields="decision.verdict,decision.risk_assessment.score"
)

TypeScript (@gaas/sdk)

const response = await client.submitIntent(intent, {
  fields: 'decision.verdict,decision.risk_assessment.score',
});

Java (com.gaas.sdk)

GaaSResponse<GovernanceDecision> response = client.submitIntent(intent, "decision.verdict,decision.risk_assessment.score");
Use case: Mobile apps or slow networks where you only need the verdict and risk score, not the full reasoning chain, modifications, or audit trail.

Idempotency

Prevent duplicate processing of the same intent by including an idempotency key. GaaS supports two approaches: header-based (recommended) and body-based (legacy, backward-compatible).

Header-Based Idempotency (Recommended)

Include an Idempotency-Key header with a unique identifier (e.g., UUID). If the same key is submitted within the TTL window, GaaS returns the cached response without re-executing the pipeline.

POST https://api.gaas.is/v1/intents
Idempotency-Key: unique-key-123
Content-Type: application/json

{ "intent": {...} }

When a cached response is returned, the response includes an Idempotent-Replayed: true header.

Body-Based Idempotency (Legacy)

Alternatively, include an idempotency_key field in the intent payload:

{
  "intent": {
    "agent": {...},
    "action": {...},
    "payload": {...},
    "idempotency_key": "unique-key-123"
  }
}

Python (gaas_sdk)

# Header-based (recommended)
response = await client.submit_intent(
    intent,
    headers={"Idempotency-Key": "unique-key-123"}
)

# Body-based (legacy)
intent = build_intent(..., idempotency_key="unique-key-123")
response = await client.submit_intent(intent)

TypeScript (@gaas/sdk)

// Header-based (recommended)
const response = await client.submitIntent(intent, {
  headers: { 'Idempotency-Key': 'unique-key-123' },
});

// Body-based (legacy)
const intent = buildIntent({ ..., idempotencyKey: 'unique-key-123' });
const response = await client.submitIntent(intent);

Java (com.gaas.sdk)

// Header-based (recommended)
Map<String, String> headers = new HashMap<>();
headers.put("Idempotency-Key", "unique-key-123");
GaaSResponse<GovernanceDecision> response = client.submitIntent(intent, headers);

// Body-based (legacy)
IntentDeclaration intent = IntentBuilder.create()
    .idempotencyKey("unique-key-123")
    ./* ... */
    .build();
GaaSResponse<GovernanceDecision> response = client.submitIntent(intent);
TTL and cleanup: Idempotency keys expire after a configurable TTL (default: 24 hours). Expired keys are automatically purged.

ETag Caching (HTTP Conditional Requests)

Save bandwidth and reduce latency by using HTTP conditional requests. GaaS supports ETag and If-None-Match headers for 304 Not Modified responses.

How It Works

  1. Make a request to a cacheable endpoint (e.g., GET /v1/membranes/{id})
  2. GaaS returns an ETag header with a cache validator (e.g., ETag: "abc123")
  3. On subsequent requests, include If-None-Match: "abc123"
  4. If the resource hasn't changed, GaaS returns 304 Not Modified with no body
  5. If the resource has changed, GaaS returns 200 OK with the updated resource and a new ETag

Example

# First request
GET /v1/membranes/mem_abc123
# Response: 200 OK, ETag: "xyz789", { ... }

# Subsequent request (no changes)
GET /v1/membranes/mem_abc123
If-None-Match: "xyz789"
# Response: 304 Not Modified (no body)

# Subsequent request (resource changed)
GET /v1/membranes/mem_abc123
If-None-Match: "xyz789"
# Response: 200 OK, ETag: "new456", { ... }

Caching Strategy

Endpoint Type Cache-Control Example
Immutable (historical data) max-age=2592000, immutable (30 days) Audit records, decisions
Semi-stable (infrequent updates) max-age=3600, private (1 hour) Membranes, agent profiles
Volatile (real-time data) no-cache, must-revalidate Escalations, live metrics

API Versioning

All API routes are mounted under the /v1/ prefix. This allows for future backward-incompatible changes to be introduced under /v2/ while preserving existing client integrations.

Current Version

https://api.gaas.is/v1/intents
https://api.gaas.is/v1/escalations
https://api.gaas.is/v1/dashboard/...

Backward Compatibility

GaaS follows semantic versioning for the API:

The API version is included in the X-GaaS-API-Version response header on all requests.

Migration notice: When a new major version is released, the previous version will be supported for a minimum of 12 months. Deprecation notices will be included in the Deprecation and Sunset HTTP headers.


Performance Optimizations

Phase 1 performance infrastructure is live in production at api.gaas.is as of February 2026. These optimizations reduce latency and payload size without any changes to your integration.

GZip Response Compression

All API responses are automatically compressed (minimum 1 KB, compression level 6). This reduces typical payload sizes by 60–70% for list and dashboard endpoints.

Endpoint typeTypical uncompressedTypical compressed
Decision list~15 KB~4.5 KB
Audit trail~40 KB~11 KB
Dashboard metrics~8 KB~2.5 KB

Multi-Tier Caching

Frequently accessed resources (agent profiles, governance membranes) are cached at two layers:

Cache performance is exposed via Prometheus metrics: gaas_cache_hits_total, gaas_cache_misses_total, and gaas_cache_operation_duration_seconds.

Read Replicas

Read-heavy operations (decision history, audit exports, dashboard queries) are automatically routed to a read replica when one is configured. The primary database handles all writes. Configure via environment variables:

GAAS_DATABASE_REPLICA_URL=postgres://replica-host:5432/gaas
GAAS_READ_REPLICA_ENABLED=true

If the replica is unavailable, GaaS falls back to the primary automatically — no downtime, no configuration changes required.

Pipeline Latency Optimizations

The governance pipeline includes several built-in optimizations that reduce end-to-end latency without any changes to your integration:

Performance targets: p95 latency <500 ms, payload size −70% with GZip, cache hit rate >90% after warm-up, primary DB load −70% with read replicas active.

Natural Language Policy Authoring

Author governance policies in plain English. GaaS uses an LLM to generate a sandboxed Python policy function from your description, validates it against 5 canonical intents, and stages it as a draft for review.

Endpoints

Sandbox

Generated policies run in a restricted execution environment. AST validation allows 42 node types, 15 safe built-in functions (len, bool, int, float, str, min, max, etc.), and 19 safe methods. Blocked: import, eval, exec, open, __import__, and all dunder attributes. The __builtins__ dict is empty at runtime.

Smoke Testing

Every generated policy is automatically tested against 5 canonical intents covering low-risk approve, high-risk transaction, PHI access, PII communication, and control actions. All 5 must execute without exceptions before the draft is accepted.


Governance Proof Tokens

Every decision carries a governance_proof_token — an ECDSA P-256 signed artefact that binds the verdict, policies evaluated, risk score, and audit hash into a tamper-evident object. The signed payload is SHA-256("{token_id}:{decision_id}:{audit_hash}").


DLT Temporal Anchoring

Audit records can be anchored to a distributed ledger for independent temporal verification. Anchoring is fire-and-forget — it never blocks the governance pipeline.


Multi-Party Co-Signing

Configure how audit records are cryptographically signed. Three modes are available, configured per-organization in the governance membrane's signing_config:

ModeDescription
gaas_onlyDefault. GaaS signs with ECDSA P-256 or RSA 2048.
segregatedCustomer's KMS endpoint signs the record. SSRF-protected: blocks non-HTTPS, private IPs, loopback, link-local, metadata endpoints. 5s timeout.
cosignedBoth GaaS and customer sign (dual signatures). Combines both strategies.

Signing failures never block decisions — the record receives an unsigned_reason instead. The signing_metadata field is excluded from audit hash computation (signatures derive from the hash).


Policy Epoch Tracking

Every audit record is stamped with policy_epoch (integer) and epoch_stale (boolean), identifying exactly which version of your policy configuration was active when the decision was made.


Behavioral Velocity Signals

GaaS automatically computes per-agent behavioral signals from recent observation history (10-minute sliding window). These signals run as a virtual connector — no external HTTP calls, no additional latency.


Feature Flags

Runtime feature toggles that can be enabled per-organization or globally, with optional percentage-based rollouts using deterministic hashing. Bootstrap defaults from environment variables (GAAS_FEATURE_{NAME}).

Endpoints

Flag names are 1–128 characters. Rollout percentage (0–100) determines what fraction of requests see the flag enabled. InMemory and Postgres-backed stores are available.


Decision Appeal System

When a decision is blocked, org admins receive an email with appeal action buttons. Appeal tokens are HMAC-SHA256 signed and expire after 72 hours.

Endpoints

Token format: hex_signature:unix_timestamp. The HMAC payload is decision_id:timestamp_str, signed with the SESSION_SECRET environment variable. Old tokens without a : separator are rejected. All user-controlled values in HTML pages are escaped via html_escape() to prevent XSS.


Geographic Access Control

Optional middleware that logs or blocks requests based on the originating country. Uses MaxMind GeoLite2 for IP-to-country resolution. Disabled by default — enable via environment variables.

In log mode, the country ISO code is logged with each request and stored in request state for downstream access. In block mode, requests from listed countries receive HTTP 403 with a geo_blocked error code. If the GeoIP database or geoip2 library is unavailable, the middleware passes requests through silently (graceful degradation).


Related Pages