Fulcrum API Overview
Comprehensive reference for Fulcrum's gRPC-first API architecture
Version: 2.0.0 Last Updated: January 6, 2026 Status: Production
Table of Contents
- API Design Philosophy
- Authentication
- Service Catalog
- Rate Limiting
- Error Handling
- Quick Start Examples
- Protocol Buffers Reference
- Best Practices
API Design Philosophy
Fulcrum follows a gRPC-first architecture with an HTTP/REST gateway for broader compatibility. This approach delivers:
Why gRPC-First?
| Characteristic | Benefit |
|---|---|
| Binary Protocol (Protobuf) | 10x smaller payloads vs JSON, critical for high-volume event streaming |
| Strongly Typed Contracts | Compile-time safety, auto-generated SDKs, self-documenting |
| Bidirectional Streaming | Real-time event subscriptions for Mission Tape UI |
| HTTP/2 Multiplexing | Multiple concurrent requests over single connection |
| Native Code Generation | First-class Go, Python, TypeScript SDKs from single source |
API Architecture
+------------------+
| Client Apps |
| (Dashboard, SDK) |
+--------+---------+
|
+------------------+------------------+
| |
+-------v-------+ +-------v-------+
| gRPC API | | REST Gateway |
| :50051 (TLS) | | :8080 (HTTP) |
+-------+-------+ +-------+-------+
| |
| Protocol Buffers | JSON
| |
+-------v------------------------------------v-------+
| Fulcrum Service Layer |
| +----------+ +----------+ +----------+ +--------+ |
| | Policy | | Cost | | Event | | Brain | |
| | Engine | | Engine | | Store | | (LLM) | |
| +----------+ +----------+ +----------+ +--------+ |
+---------------------------------------------------+
Endpoint Conventions
| Protocol | Endpoint | Use Case |
|---|---|---|
| gRPC | grpc://localhost:50051 |
SDKs, service-to-service, high-performance |
| gRPC-Web | https://api.fulcrum.dev/grpc |
Browser clients with gRPC-Web proxy |
| REST | https://api.fulcrum.dev/v1/* |
Legacy systems, webhooks, debugging |
Versioning Strategy
Fulcrum uses package-level versioning in Protocol Buffers:
- v1: Stable, production-ready, breaking changes avoided
- Beta features: Marked with
(beta)suffix in method names - Deprecation: Minimum 6-month notice before removal
Authentication
Fulcrum uses API key authentication with tenant context for multi-tenant isolation.
Authentication Flow
+--------+ +------------+ +-----------+
| Client | | Fulcrum | | Tenant |
| | | Gateway | | Store |
+---+----+ +-----+------+ +-----+-----+
| | |
| 1. Request with | |
| x-api-key | |
+------------------->| |
| | |
| | 2. SHA256 hash key |
| | 3. Lookup hash |
| +--------------------->|
| | |
| | 4. Return tenant_id |
| | + scopes |
| |<---------------------+
| | |
| | 5. Inject context |
| | into request |
| | |
| 6. Response | |
|<-------------------+ |
API Key Management
Create and manage API keys via the TenantService:
service TenantService {
// Create a new API key for the authenticated tenant
rpc CreateApiKey(CreateApiKeyRequest) returns (CreateApiKeyResponse);
// List all API keys for the tenant
rpc ListApiKeys(ListApiKeysRequest) returns (ListApiKeysResponse);
// Revoke an API key by ID
rpc RevokeApiKey(RevokeApiKeyRequest) returns (RevokeApiKeyResponse);
}
Authentication Headers
gRPC
// Go
md := metadata.Pairs("x-api-key", "flcm_live_xxxxxxxxxxxx")
ctx := metadata.NewOutgoingContext(context.Background(), md)
# Python
metadata = [("x-api-key", "flcm_live_xxxxxxxxxxxx")]
response = stub.EvaluatePolicy(request, metadata=metadata)
// TypeScript
const metadata = new grpc.Metadata();
metadata.add('x-api-key', 'flcm_live_xxxxxxxxxxxx');
REST
API Key Format
| Prefix | Environment | Example |
|---|---|---|
flcm_live_ |
Production | flcm_live_abc123def456... |
flcm_test_ |
Sandbox/Testing | flcm_test_xyz789abc012... |
flcm_dev_ |
Development | flcm_dev_dev123local... |
Scopes
API keys can be scoped to limit access:
| Scope | Description |
|---|---|
* |
Full administrative access |
policies:read |
Read policies |
policies:write |
Create/update/delete policies |
envelopes:read |
Read execution envelopes |
envelopes:write |
Create/update envelopes |
costs:read |
View cost data |
budgets:write |
Manage budgets |
events:read |
Query event store |
brain:evaluate |
Use cognitive services |
Tenant Context
Every authenticated request automatically receives tenant context:
// Server-side: Extract tenant from authenticated context
tenantID, ok := middleware.GetTenantID(ctx)
if !ok {
return status.Error(codes.Unauthenticated, "tenant context required")
}
PostgreSQL Row-Level Security (RLS) enforces tenant isolation at the database level:
-- All queries automatically filtered by tenant
SET fulcrum.current_tenant = 'tenant-uuid';
SELECT * FROM policies; -- Only returns tenant's policies
Service Catalog
Fulcrum exposes nine gRPC services organized into three functional domains:
Core Governance Services
PolicyService
Package: fulcrum.policy.v1
Purpose: Policy management and real-time evaluation
Latency Target: <10ms P99
service PolicyService {
// Policy CRUD
rpc CreatePolicy(CreatePolicyRequest) returns (CreatePolicyResponse);
rpc GetPolicy(GetPolicyRequest) returns (GetPolicyResponse);
rpc UpdatePolicy(UpdatePolicyRequest) returns (UpdatePolicyResponse);
rpc DeletePolicy(DeletePolicyRequest) returns (DeletePolicyResponse);
rpc ListPolicies(ListPoliciesRequest) returns (ListPoliciesResponse);
// Evaluation (critical path)
rpc EvaluatePolicy(EvaluatePolicyRequest) returns (EvaluatePolicyResponse);
rpc EvaluatePolicies(EvaluatePoliciesRequest) returns (EvaluatePoliciesResponse);
rpc GetEvaluationHistory(GetEvaluationHistoryRequest) returns (GetEvaluationHistoryResponse);
// Approval Workflow
rpc ListApprovals(ListApprovalsRequest) returns (ListApprovalsResponse);
rpc UpdateApproval(UpdateApprovalRequest) returns (UpdateApprovalResponse);
}
Key Concepts: - Policy Rules: Define conditions and actions (ALLOW, DENY, WARN, REQUIRE_APPROVAL) - Enforcement Levels: AUDIT (log only), WARN, BLOCK, TERMINATE - Condition Types: Field match, regex, semantic (LLM-based), statistical spike - Execution Phases: PRE_EXECUTION, PRE_LLM_CALL, POST_LLM_CALL, PRE_TOOL_CALL, POST_TOOL_CALL, POST_EXECUTION
CostService
Package: fulcrum.cost.v1
Purpose: Budget management and cost tracking
Latency Target: <5ms P99
service CostService {
// Budget CRUD
rpc CreateBudget(CreateBudgetRequest) returns (CreateBudgetResponse);
rpc GetBudget(GetBudgetRequest) returns (GetBudgetResponse);
rpc UpdateBudget(UpdateBudgetRequest) returns (UpdateBudgetResponse);
rpc DeleteBudget(DeleteBudgetRequest) returns (DeleteBudgetResponse);
rpc ListBudgets(ListBudgetsRequest) returns (ListBudgetsResponse);
// Cost Analytics
rpc GetCostSummary(GetCostSummaryRequest) returns (GetCostSummaryResponse);
rpc GetSpendSummary(GetSpendSummaryRequest) returns (GetSpendSummaryResponse);
rpc GetBudgetStatus(GetBudgetStatusRequest) returns (GetBudgetStatusResponse);
// Prediction
rpc PredictCost(PredictCostRequest) returns (PredictCostResponse);
}
Key Concepts: - Budget Periods: Hourly, daily, weekly, monthly, quarterly, yearly, custom - Notification Thresholds: Configurable alerts at percentage milestones (e.g., 80%, 95%) - Budget Status: OK, WARNING, CRITICAL, EXCEEDED, SUSPENDED - Spend Aggregation: By model, by day/week/month, by workflow
EnvelopeService
Package: fulcrum.envelope.v1
Purpose: Execution envelope lifecycle management
Latency Target: <5ms P99
service EnvelopeService {
// Lifecycle management
rpc CreateEnvelope(CreateEnvelopeRequest) returns (CreateEnvelopeResponse);
rpc GetEnvelope(GetEnvelopeRequest) returns (GetEnvelopeResponse);
rpc UpdateEnvelopeStatus(UpdateEnvelopeStatusRequest) returns (UpdateEnvelopeStatusResponse);
}
Key Concepts: - Execution Envelope (EEV): Core abstraction wrapping all agent executions - Status Lifecycle: PENDING -> AUTHORIZED -> RUNNING -> COMPLETED/FAILED/TERMINATED - Framework Support: LangGraph, Microsoft Semantic Kernel, CrewAI, AutoGen, Custom
Cognitive Services (Brain)
SemanticJudgeService
Package: fulcrum.brain.v1
Purpose: LLM-based intent evaluation and risk classification
Latency Target: <50ms P99
service SemanticJudgeService {
// Evaluate policy conditions using LLM semantic analysis
rpc EvaluateCondition(EvaluateConditionRequest) returns (EvaluateConditionResponse);
// Classify risk level of agent actions
rpc ClassifyRisk(ClassifyRiskRequest) returns (ClassifyRiskResponse);
// Derive intent from pattern signatures
rpc DeriveIntent(DeriveIntentRequest) returns (DeriveIntentResponse);
}
Key Concepts: - Local LLM Inference: Uses Ollama (llama3.2) for privacy-preserving evaluation - Fallback Mode: Deterministic evaluation if LLM fails - Risk Levels: LOW, MEDIUM, HIGH, CRITICAL - Confidence Scoring: 0.0-1.0 confidence threshold for semantic matches
OracleService
Package: fulcrum.brain.v1
Purpose: Predictive cost modeling (unique differentiator)
Latency Target: <20ms P99
service OracleService {
// Predict budget overrun probability
rpc PredictBudgetOverrun(PredictOverrunRequest) returns (PredictOverrunResponse);
// Get/rebuild prediction models
rpc GetPredictionModel(GetPredictionModelRequest) returns (GetPredictionModelResponse);
rpc ListPredictionModels(ListPredictionModelsRequest) returns (ListPredictionModelsResponse);
}
Key Concepts: - Statistical Models: Built from historical execution data - Overrun Probability: 0.0-1.0 probability of exceeding budget - Recommended Actions: NONE, WARN, REDUCE_RATE, REQUEST_QUOTA, HALT - Model Metrics: avg_cost_per_run, std_dev, runs_per_hour, sample_size
ImmuneSystemService
Package: fulcrum.brain.v1
Purpose: Automated policy generation from incident patterns
Latency Target: <100ms P99
service ImmuneSystemService {
// Report incidents for learning
rpc ReportIncident(ReportIncidentRequest) returns (ReportIncidentResponse);
// Pattern detection
rpc GetAttackPatterns(GetAttackPatternsRequest) returns (GetAttackPatternsResponse);
// Auto-generated policy management
rpc GetPendingPolicies(GetPendingPoliciesRequest) returns (GetPendingPoliciesResponse);
rpc ReviewGeneratedPolicy(ReviewGeneratedPolicyRequest) returns (ReviewGeneratedPolicyResponse);
// Incident history
rpc ListIncidents(ListIncidentsRequest) returns (ListIncidentsResponse);
}
Key Concepts: - Incident Categories: Budget overrun, policy violation, security breach, rate limit exceeded, anomaly detected - Attack Patterns: Automatically detected from incident correlation - Generated Policies: Human-in-the-loop review before activation - Auto-Activation: High-confidence policies can activate without approval
Infrastructure Services
CheckpointService
Package: fulcrum.checkpoint.v1
Purpose: Execution state persistence and recovery
Latency Target: <10ms P99
service CheckpointService {
// Checkpoint CRUD
rpc SaveCheckpoint(SaveCheckpointRequest) returns (SaveCheckpointResponse);
rpc GetCheckpoint(GetCheckpointRequest) returns (GetCheckpointResponse);
rpc ListCheckpoints(ListCheckpointsRequest) returns (ListCheckpointsResponse);
rpc DeleteCheckpoint(DeleteCheckpointRequest) returns (DeleteCheckpointResponse);
// Version management
rpc ListCheckpointVersions(ListCheckpointVersionsRequest) returns (ListCheckpointVersionsResponse);
rpc GetCheckpointVersion(GetCheckpointVersionRequest) returns (GetCheckpointVersionResponse);
// Query and context
rpc QueryCheckpoints(QueryCheckpointsRequest) returns (QueryCheckpointsResponse);
rpc GetExecutionContext(GetExecutionContextRequest) returns (GetExecutionContextResponse);
rpc UpdateExecutionContext(UpdateExecutionContextRequest) returns (UpdateExecutionContextResponse);
}
Key Concepts: - Checkpoint Types: Manual, auto, pre-terminate, error, milestone - Version Chains: Parent-child relationships for version history - Context Scopes: Execution, workflow, tenant-wide - Merge Strategies: Last-write-wins, fail-on-conflict, recursive merge
EventStoreService
Package: fulcrum.eventstore.v1
Purpose: Event persistence and real-time streaming
Latency Target: <5ms P99 (publish), <50ms P99 (query)
service EventStoreService {
// Publishing
rpc PublishEvent(PublishEventRequest) returns (PublishEventResponse);
rpc PublishEventBatch(PublishEventBatchRequest) returns (PublishEventBatchResponse);
// Querying
rpc QueryEvents(QueryEventsRequest) returns (QueryEventsResponse);
rpc GetExecutionEvents(GetExecutionEventsRequest) returns (GetExecutionEventsResponse);
// Real-time streaming
rpc StreamEvents(StreamEventsRequest) returns (stream StreamEventsResponse);
// Statistics
rpc GetEventStoreStats(GetEventStoreStatsRequest) returns (GetEventStoreStatsResponse);
}
Key Concepts: - Event Types: Execution lifecycle, LLM calls, tool invocations, checkpoints, budget, policy - NATS JetStream: Durable event streaming with replay capability - TimescaleDB: High-resolution time-series storage - Retention Policies: Configurable per event type and tenant
TenantService
Package: fulcrum.tenant.v1
Purpose: Tenant and API key management
Latency Target: <10ms P99
service TenantService {
rpc CreateApiKey(CreateApiKeyRequest) returns (CreateApiKeyResponse);
rpc ListApiKeys(ListApiKeysRequest) returns (ListApiKeysResponse);
rpc RevokeApiKey(RevokeApiKeyRequest) returns (RevokeApiKeyResponse);
}
Service Summary Matrix
| Service | Package | Primary Use | Latency P99 |
|---|---|---|---|
| PolicyService | policy.v1 |
Policy evaluation | <10ms |
| CostService | cost.v1 |
Budget management | <5ms |
| EnvelopeService | envelope.v1 |
Execution lifecycle | <5ms |
| SemanticJudgeService | brain.v1 |
LLM-based evaluation | <50ms |
| OracleService | brain.v1 |
Cost prediction | <20ms |
| ImmuneSystemService | brain.v1 |
Auto-policy generation | <100ms |
| CheckpointService | checkpoint.v1 |
State persistence | <10ms |
| EventStoreService | eventstore.v1 |
Event streaming | <5ms |
| TenantService | tenant.v1 |
API key management | <10ms |
Rate Limiting
Fulcrum implements tenant-aware rate limiting using Redis-backed token buckets.
Default Limits
| Tier | Requests/Second | Burst Capacity |
|---|---|---|
| Developer (Free) | 10 | 20 |
| Pro | 100 | 200 |
| Team | 500 | 1,000 |
| Enterprise | Custom | Custom |
Rate Limit Headers
Rate Limit Response
When limits are exceeded:
gRPC:
REST:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60
{
"code": 8,
"message": "rate limit exceeded",
"details": []
}
Rate Limit Implementation
// From internal/middleware/ratelimit.go
type RateLimitInterceptor struct {
limiter *ratelimit.Limiter
defaultRate float64 // 10.0 requests per second
defaultCapacity int // Burst of 20
}
Fail-Open Policy
Rate limiting fails open to prevent governance from blocking critical paths:
allowed, err := i.limiter.Allow(ctx, key, rate, capacity, 1)
if err != nil {
// Fail open: allow request on Redis failure
return handler(ctx, req)
}
Error Handling
Fulcrum uses standard gRPC status codes with structured error details.
gRPC Status Codes
| Code | Name | HTTP | Description |
|---|---|---|---|
| 0 | OK | 200 | Success |
| 3 | INVALID_ARGUMENT | 400 | Invalid request parameters |
| 5 | NOT_FOUND | 404 | Resource not found |
| 7 | PERMISSION_DENIED | 403 | Insufficient permissions |
| 8 | RESOURCE_EXHAUSTED | 429 | Rate limit exceeded |
| 13 | INTERNAL | 500 | Internal server error |
| 14 | UNAVAILABLE | 503 | Service temporarily unavailable |
| 16 | UNAUTHENTICATED | 401 | Invalid or missing authentication |
Error Response Structure
gRPC:
REST (JSON):
{
"code": 7,
"message": "policy evaluation denied action",
"details": [
{
"@type": "type.googleapis.com/fulcrum.policy.v1.EvaluationResult",
"policy_id": "pol_abc123",
"decision": "DENY",
"matched_rules": [
{
"rule_id": "rule_xyz",
"rule_name": "block_sensitive_data",
"matched_conditions": ["content_filter"]
}
],
"message": "PII detected in output"
}
]
}
Domain-Specific Errors
Policy Errors
// Policy violation returns PERMISSION_DENIED with EvaluationResult details
message EvaluationResult {
string policy_id = 1;
EvaluationDecision decision = 2;
repeated RuleMatch matched_rules = 3;
string message = 5;
}
Budget Errors
// Budget exceeded returns RESOURCE_EXHAUSTED with BudgetStatus details
message BudgetStatus {
string budget_id = 1;
BudgetStatusType status = 2; // EXCEEDED
float cost_usage_percent = 4;
BudgetLimits remaining = 7;
}
Authentication Errors
// From internal/middleware/auth.go
if len(keys) == 0 {
return nil, status.Error(codes.Unauthenticated, "x-api-key is required")
}
if errors.Is(err, tenant.ErrTenantNotFound) {
return nil, status.Error(codes.Unauthenticated, "invalid api key")
}
Error Handling Best Practices
- Always check status codes: Don't assume success
- Parse error details: Extract domain-specific context
- Implement retry logic: For UNAVAILABLE and rate limit errors
- Log error details: Include trace_id for debugging
- Configure failure modes: FAIL_OPEN vs FAIL_CLOSED per use case
Quick Start Examples
Go
package main
import (
"context"
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
policyv1 "github.com/fulcrum-io/fulcrum/pkg/policy/v1"
envelopev1 "github.com/fulcrum-io/fulcrum/pkg/envelope/v1"
)
func main() {
// Connect to Fulcrum
conn, err := grpc.Dial(
"localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
defer conn.Close()
// Create clients
envelopeClient := envelopev1.NewEnvelopeServiceClient(conn)
policyClient := policyv1.NewPolicyServiceClient(conn)
// Add authentication
ctx := metadata.NewOutgoingContext(
context.Background(),
metadata.Pairs("x-api-key", "flcm_live_xxxxxxxxxxxx"),
)
// Create execution envelope
envelope, err := envelopeClient.CreateEnvelope(ctx, &envelopev1.CreateEnvelopeRequest{
TenantId: "tenant-123",
AdapterType: "custom",
Metadata: map[string]string{
"workflow": "customer-support",
"user_id": "user-456",
},
})
if err != nil {
log.Fatalf("failed to create envelope: %v", err)
}
log.Printf("Created envelope: %s", envelope.Envelope.EnvelopeId)
// Evaluate policy before action
evalResult, err := policyClient.EvaluatePolicies(ctx, &policyv1.EvaluatePoliciesRequest{
Context: &policyv1.EvaluationContext{
TenantId: "tenant-123",
EnvelopeId: envelope.Envelope.EnvelopeId,
Phase: policyv1.ExecutionPhase_EXECUTION_PHASE_PRE_TOOL_CALL,
ToolNames: []string{"send_email"},
InputText: "Send report to user@example.com",
},
StopOnDeny: true,
})
if err != nil {
log.Fatalf("policy evaluation failed: %v", err)
}
switch evalResult.FinalDecision {
case policyv1.EvaluationDecision_EVALUATION_DECISION_ALLOW:
log.Println("Action allowed - proceeding")
// Execute the action
case policyv1.EvaluationDecision_EVALUATION_DECISION_DENY:
log.Printf("Action denied: %s", evalResult.Results[0].Message)
case policyv1.EvaluationDecision_EVALUATION_DECISION_REQUIRE_APPROVAL:
log.Println("Action requires human approval")
}
}
Python
from fulcrum import FulcrumClient, FailureMode
from fulcrum.exceptions import PolicyViolationError, BudgetExceededError
# Initialize client
client = FulcrumClient(
host="localhost:50051",
api_key="flcm_live_xxxxxxxxxxxx",
on_failure=FailureMode.FAIL_OPEN,
timeout_ms=500,
)
# Alternative: Initialize from environment variables
# client = FulcrumClient.from_env()
def run_governed_agent(user_query: str) -> str:
"""Execute an agent action with Fulcrum governance."""
# Create governance envelope
with client.envelope(
workflow_id="customer-support-bot",
metadata={"source": "api", "priority": "normal"}
) as env:
# Pre-execution policy check
if not env.guard("process_query", input_text=user_query):
return "Query blocked by policy"
# Simulate agent processing
response = process_with_llm(user_query)
# Check tool usage before execution
if needs_email(response):
if env.guard("send_email", input_text=response):
send_email(response)
env.log("email_sent", {"status": "success"})
else:
env.log("email_blocked", {"reason": "policy"})
# Get cost summary
cost = env.get_cost()
print(f"Execution cost: ${cost.total_usd:.4f}")
return response
# Error handling example
try:
result = run_governed_agent("Summarize sales report")
print(f"Result: {result}")
except PolicyViolationError as e:
print(f"Policy violation: {e.policy_id} - {e.message}")
except BudgetExceededError as e:
print(f"Budget exceeded: ${e.current_spend:.2f} of ${e.budget_limit:.2f}")
except Exception as e:
print(f"Error: {e}")
TypeScript
import { FulcrumClient, FailureMode } from '@fulcrum-governance/sdk';
import { PolicyViolationError, BudgetExceededError } from '@fulcrum-governance/sdk/errors';
// Initialize client
const client = new FulcrumClient({
host: 'localhost:50051',
apiKey: 'flcm_live_xxxxxxxxxxxx',
onFailure: FailureMode.FAIL_OPEN,
timeoutMs: 500,
});
// Alternative: Initialize from environment
// const client = FulcrumClient.fromEnv();
async function runGovernedAgent(userQuery: string): Promise<string> {
// Create governance envelope
const envelope = client.envelope({
workflowId: 'customer-support-bot',
metadata: { source: 'api', priority: 'normal' },
});
try {
// Pre-execution policy check
if (!await envelope.guard('process_query', userQuery)) {
return 'Query blocked by policy';
}
// Simulate agent processing
const response = await processWithLLM(userQuery);
// Check tool usage before execution
if (needsEmail(response)) {
if (await envelope.guard('send_email', response)) {
await sendEmail(response);
envelope.log('email_sent', { status: 'success' });
} else {
envelope.log('email_blocked', { reason: 'policy' });
}
}
// Get cost summary
const cost = await envelope.getCost();
console.log(`Execution cost: $${cost.totalUsd.toFixed(4)}`);
// Complete envelope
await envelope.complete({ result: response });
return response;
} catch (error) {
if (error instanceof PolicyViolationError) {
console.error(`Policy violation: ${error.policyId} - ${error.message}`);
throw error;
}
if (error instanceof BudgetExceededError) {
console.error(`Budget exceeded: $${error.currentSpend} of $${error.budgetLimit}`);
throw error;
}
throw error;
}
}
// Usage
runGovernedAgent('Summarize sales report')
.then(result => console.log(`Result: ${result}`))
.catch(err => console.error(`Error: ${err.message}`));
cURL (REST)
# Health check
curl http://localhost:8080/healthz
# Create envelope
curl -X POST http://localhost:8080/v1/envelopes \
-H "X-Api-Key: flcm_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "tenant-123",
"adapter_type": "custom",
"metadata": {
"workflow": "customer-support"
}
}'
# Evaluate policies
curl -X POST http://localhost:8080/v1/policies/batch-evaluate \
-H "X-Api-Key: flcm_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"context": {
"tenant_id": "tenant-123",
"envelope_id": "env-abc123",
"phase": "EXECUTION_PHASE_PRE_TOOL_CALL",
"tool_names": ["send_email"],
"input_text": "Send report to user@example.com"
},
"stop_on_deny": true
}'
# List policies
curl http://localhost:8080/v1/policies?tenant_id=tenant-123 \
-H "X-Api-Key: flcm_live_xxxxxxxxxxxx"
# Get budget status
curl http://localhost:8080/v1/budgets/budget-xyz/status \
-H "X-Api-Key: flcm_live_xxxxxxxxxxxx"
# Predict cost
curl -X POST http://localhost:8080/v1/costs/predict \
-H "X-Api-Key: flcm_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "tenant-123",
"workflow_id": "customer-support",
"model_ids": ["gpt-4", "claude-3-opus"],
"use_historical_data": true,
"lookback_days": 7
}'
Protocol Buffers Reference
File Locations
proto/fulcrum/
├── brain/v1/
│ └── brain_service.proto # Cognitive services (SemanticJudge, Oracle, ImmuneSystem)
├── checkpoint/v1/
│ └── checkpoint_service.proto # State persistence
├── cost/v1/
│ └── cost_service.proto # Budget and cost management
├── envelope/v1/
│ ├── envelope.proto # Core envelope types
│ └── envelope_service.proto # Envelope lifecycle
├── events/v1/
│ └── events.proto # Normalized event schema
├── eventstore/v1/
│ └── eventstore.proto # Event persistence and streaming
├── policy/v1/
│ └── policy_service.proto # Policy management and evaluation
├── tenant/v1/
│ └── tenant_service.proto # Tenant and API key management
└── bridge/v1/
└── bridge.proto # Python-Go bridge (LangGraph)
Code Generation
# Install buf CLI
brew install bufbuild/buf/buf
# Generate code for all languages
buf generate
# Lint proto files
buf lint
# Check for breaking changes
buf breaking --against '.git#branch=main'
Go Package Mapping
| Proto Package | Go Import Path |
|---|---|
fulcrum.policy.v1 |
github.com/fulcrum-io/fulcrum/pkg/policy/v1 |
fulcrum.cost.v1 |
github.com/fulcrum-io/fulcrum/pkg/cost/v1 |
fulcrum.envelope.v1 |
github.com/fulcrum-io/fulcrum/pkg/envelope/v1 |
fulcrum.brain.v1 |
github.com/fulcrum-io/fulcrum/pkg/brain/v1 |
fulcrum.checkpoint.v1 |
github.com/fulcrum-io/fulcrum/pkg/checkpoint/v1 |
fulcrum.eventstore.v1 |
github.com/fulcrum-io/fulcrum/pkg/eventstore/v1 |
fulcrum.events.v1 |
github.com/fulcrum-io/fulcrum/pkg/events/v1 |
fulcrum.tenant.v1 |
github.com/fulcrum-io/fulcrum/pkg/tenant/v1 |
Best Practices
1. Fail-Safe Configuration
Choose the appropriate failure mode for your use case:
| Mode | Behavior | Use Case |
|---|---|---|
FAIL_OPEN |
Allow on error | Non-critical governance, monitoring |
FAIL_CLOSED |
Block on error | High-security, compliance-critical |
# Production: fail-closed for security
client = FulcrumClient(
host="fulcrum.internal:50051",
api_key=os.environ["FULCRUM_API_KEY"],
on_failure=FailureMode.FAIL_CLOSED,
timeout_ms=200, # Low timeout for fast fail
)
2. Timeout Tuning
// Critical path: low timeout, fail-open
const criticalClient = new FulcrumClient({
host: 'fulcrum.internal:50051',
timeoutMs: 100, // 100ms timeout
onFailure: 'FAIL_OPEN',
});
// Background processing: higher timeout, fail-closed
const batchClient = new FulcrumClient({
host: 'fulcrum.internal:50051',
timeoutMs: 5000, // 5s timeout
onFailure: 'FAIL_CLOSED',
});
3. Connection Management
// Reuse connections - don't create per-request
var (
conn *grpc.ClientConn
client policyv1.PolicyServiceClient
)
func init() {
var err error
conn, err = grpc.Dial(
"fulcrum.internal:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 10 * time.Second,
Timeout: 3 * time.Second,
PermitWithoutStream: true,
}),
)
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
client = policyv1.NewPolicyServiceClient(conn)
}
4. Batch Operations
# Prefer batch evaluation over multiple single calls
result = client.evaluate_policies(
context={
"tenant_id": tenant_id,
"tool_names": ["tool1", "tool2", "tool3"],
},
stop_on_deny=True, # Short-circuit on first deny
)
5. Event Logging
// Log business events for audit trail
envelope.log('customer_action', {
action: 'refund_requested',
amount: 150.00,
currency: 'USD',
customer_id: 'cust_123',
agent_decision: 'approved',
});
6. Checkpoint Strategy
# Checkpoint at expensive operations
with client.envelope(workflow_id="long-running-analysis") as env:
for i, chunk in enumerate(large_dataset):
process(chunk)
# Checkpoint every 100 items
if i % 100 == 0:
env.checkpoint()
env.log("progress", {"processed": i})
7. Distributed Tracing
// Propagate trace context
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
)
func createEnvelopeWithTrace(ctx context.Context) {
// Extract trace context
carrier := propagation.MapCarrier{}
otel.GetTextMapPropagator().Inject(ctx, carrier)
// Pass to Fulcrum
envelope, _ := envelopeClient.CreateEnvelope(ctx, &envelopev1.CreateEnvelopeRequest{
TenantId: "tenant-123",
Metadata: carrier, // trace_id, span_id, etc.
})
}
Related Documentation
- Quick Start: Get up and running in minutes.
- Policy Authoring: Learn how to write governance policies.
- Deployment Guide: Run Fulcrum in production.
- System Overview: Understand the architecture.gn
Support
- Documentation: docs.fulcrum.dev
- Email: support@fulcrum.dev
- Enterprise: Contact your account representative
Last Updated: January 6, 2026 Fulcrum Version: 2.0.0