MIR Policy — Enterprise API Reference

MIR Policy is a hosted service that uses participation history to help organizations make informed decisions. It does not require implementing MIR Protocol claims or signature verification.

Base URL

https://mirregistry.com/policy

Authentication

All requests require your API key in the x-api-key header:

x-api-key: your-api-key-here

Endpoints

POST /policy/evaluate

Evaluate whether an actor can perform an action. Returns allow/deny/step_up decision with reasons.

{
  "actor_id": "user-123",
  "action": "checkout.complete",
  "context": {
    "amount_usd": 500,
    "is_first_order": true
  }
}

Response:

{
  "decision": "step_up",
  "reasons": ["high_value_first_order"],
  "actor_tier": 1,
  "action_config": { ... }
}

POST /policy/evaluate/bulk

Evaluate up to 50 policy decisions in a single request. Each evaluation is processed independently — partial failures don’t fail the batch.

{
  "evaluations": [
    { "actor": { "id": "user-abc", "type": "human" }, "action": "data.export_pii" },
    { "actor": { "id": "user-xyz", "type": "human" }, "action": "finance.approve_payment" },
    { "actor": { "id": "svc-bot", "type": "service" }, "action": "credential.rotate" }
  ]
}

Response:

{
  "summary": { "total": 3, "allow": 1, "deny": 0, "step_up": 1, "limit": 1, "errors": 0 },
  "results": [
    { "index": 0, "status": "evaluated", "decision": "step_up", ... },
    { "index": 1, "status": "evaluated", "decision": "allow", ... },
    { "index": 2, "status": "evaluated", "decision": "limit", ... }
  ]
}

Supports ?debug=true or x-policy-debug: true header for debug output on all items.

GET /policy/health

Health check endpoint. Returns API status.

curl https://mirregistry.com/policy/health \
  -H "x-api-key: your-api-key"

GET /policy/actions

List all configured actions and their policies.

GET /policy/actions/:action

Get configuration for a specific action.

Actor Tiers

MIR Policy assigns tiers based on cross-platform participation history:

TierDescriptionTypical Treatment
0No MIR historyRequire verification, constrain access
1≥10 events, ≥1 partner, ≥14 daysStandard flow, may step-up for high-risk
2≥50 events, ≥2 partners, ≥30 daysReduced friction
3≥200 events, ≥3 partners, ≥90 daysLowest friction, informed by policy

Decisions

DecisionMeaningYour Action
allowAction permittedProceed normally
denyAction blockedShow error, suggest alternatives
step_upNeeds verificationRequest additional auth (2FA, ID, etc.)
limitAllowed with restrictionsApply limits from response

Default Actions

Common actions pre-configured for most use cases:

ActionRequired TierFail Behavior
checkout.complete1step_up
payout.request2deny
data.export_pii2step_up
message.send0limit
review.post1step_up

Custom Actions: Contact us to configure custom actions and policies for your organization's specific needs.

Pricing

MIR pricing reflects infrastructure capacity, data retention responsibility, and operational guarantees — not user access or feature tiers.

Contact us for pricing details and to discuss your organization's requirements.

Integration Example

// Before processing a high-value action
const response = await fetch('https://mirregistry.com/policy/evaluate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.MIR_API_KEY
  },
  body: JSON.stringify({
    actor_id: user.id,
    action: 'checkout.complete',
    context: { amount_usd: cart.total }
  })
});

const { decision, reasons } = await response.json();

if (decision === 'allow') {
  await processCheckout();
} else if (decision === 'step_up') {
  await requireTwoFactor();
} else {
  throw new Error('Action not permitted');
}

Agent Management API

Register and manage AI agents and service accounts programmatically. Agents get scoped permissions, event-type allowlists, and independent API keys — no portal access required.

All agent endpoints require partner authentication (x-api-key header) and an Enterprise plan. Requires OWNER or ADMIN membership role.

Authentication Modes

Agents authenticate in one of two ways:

ModeHeaderDescription
Agent keyx-api-key: mir_agent_<key>Agent uses its own API key (recommended)
Partner key + headerx-api-key: mir_<key> + x-mir-agent-id: <id>Partner key with agent external ID header

Permissions

PermissionDescription
events:writeSubmit events
events:readRead events
claims:writeSubmit claims
claims:readRead claims
users:resolveResolve user handle to ID (minimal fields)
users:readFull user read (rare, sensitive)
policy:readAccess policy evaluation
webhooks:manageConfigure webhooks
audit:readAccess audit logs

Presets

Presets are predefined permission bundles. Use a preset or specify permissions explicitly.

PresetPermissionsDescription
event_emitterevents:writeSubmit events (restrict to allowed event types)
verifierusers:resolve, claims:writeResolve users, submit claims
reconcilerevents:read, events:writeRead and retry events (idempotent workflows)
adminAll permissionsFull API access — blocked for AI_AGENT type

AI Agent Guardrails: Agents with type AI_AGENT automatically enforce idempotency, cap bulk operations at 25 items, block the admin preset, and require at least one allowed event type or pattern.

POST /v1/agents

Create a new agent. Returns the agent record and a plaintext API key (shown once).

Request:

{
  "name": "Checkout Bot",
  "type": "AI_AGENT",
  "preset": "event_emitter",
  "allowedEventTypes": ["transaction.completed", "transaction.refunded"],
  "allowedEventPatterns": ["review.*"],
  "rateLimitPerMinute": 100
}
FieldTypeRequiredDescription
namestringYesAgent name (max 100 chars)
typestringYesAI_AGENT or SERVICE_ACCOUNT
descriptionstringNoOptional description
presetstringNoPermission preset (see above)
permissionsstring[]NoExplicit permission list (alternative to preset)
allowedEventTypesstring[]AI_AGENT: YesEvent types this agent can submit
allowedEventPatternsstring[]NoTrailing wildcard patterns (e.g., transaction.*)
rateLimitPerMinutenumberNoPer-agent rate limit (1–10,000). Null inherits partner limit
maxBulkItemsnumberNoMax items per bulk request
agentExternalIdstringNoYour ID for header-mode auth (max 100 chars)
generateKeybooleanNoGenerate API key (default: true)

Response (201):

{
  "id": "agent_abc123",
  "name": "Checkout Bot",
  "type": "AI_AGENT",
  "status": "ACTIVE",
  "preset": "event_emitter",
  "permissions": ["events:write"],
  "allowedEventTypes": ["transaction.completed", "transaction.refunded"],
  "allowedEventPatterns": ["review.*"],
  "requireIdempotency": true,
  "maxBulkItems": 25,
  "rateLimitPerMinute": 100,
  "agentExternalId": null,
  "createdAt": "2026-02-22T12:00:00Z",
  "apiKey": "mir_agent_aBcDeFgHiJkLmNoPqRsT...",
  "message": "Save this API key now. It cannot be retrieved again."
}

GET /v1/agents

List all agents for your organization.

Query ParamTypeDescription
includeRevokedbooleanInclude permanently revoked agents (default: false)

Response:

{
  "agents": [
    {
      "id": "agent_abc123",
      "name": "Checkout Bot",
      "type": "AI_AGENT",
      "status": "ACTIVE",
      "permissions": ["events:write"],
      "authMode": "agent_key",
      "lastUsedAt": "2026-02-22T11:45:00Z"
    }
  ]
}

GET /v1/agents/me

Self-info for the currently authenticated agent. Use this from agent code to verify permissions and configuration. Requires an agent API key.

GET /v1/agents/:id

Get full details for a specific agent.

PATCH /v1/agents/:id

Update an agent's name, description, permissions, allowed event types, patterns, or rate limits.

{
  "permissions": ["events:write", "events:read"],
  "allowedEventTypes": ["transaction.completed"],
  "rateLimitPerMinute": 200
}

POST /v1/agents/:id/suspend

Temporarily suspend an agent. The agent's key is preserved and can be reactivated.

{ "reason": "Investigating anomalous activity" }

POST /v1/agents/:id/reactivate

Reactivate a suspended agent. No request body required.

POST /v1/agents/:id/revoke

Permanently revoke an agent. The API key hash is deleted and cannot be recovered.

{ "reason": "Agent decommissioned" }

POST /v1/agents/:id/key/rotate

Generate a new API key. The old key is invalidated immediately.

Response:

{
  "apiKey": "mir_agent_xYzAbCdEfGhIjKlMnO...",
  "message": "New API key generated. Your old key has been invalidated. Save this key now — it cannot be retrieved again."
}

Agent Genealogy

Agents can spawn subordinate agents, and MIR tracks the full lineage. MIR records the genealogy — your enterprise decides what to do about it. Use the lineage data to automate policy evaluations, set alerts, or feed your existing SIEM.

POST /v1/agents/:id/spawn

Spawn a child agent from an existing parent. The child inherits the parent's enterprise context automatically. Spawn guardrails ensure the child can never escalate beyond the parent's permissions, rate limits, or event-type restrictions.

Request body: Same as POST /v1/agents (name, type, preset, permissions, allowedEventTypes, etc.).

Automatic fields:

  • parentAgentId — set from URL parameter
  • rootAgentId — inherited from parent (or parent's ID if parent is root)
  • spawnDepth — parent depth + 1
  • membershipSourceSPAWNED

Response (201):

{
  "id": "ag_child_01",
  "name": "build-worker",
  "type": "AI_AGENT",
  "status": "ACTIVE",
  "parentAgentId": "ag_parent_01",
  "rootAgentId": "ag_parent_01",
  "spawnDepth": 1,
  "membershipSource": "SPAWNED",
  "permissions": ["events:write"],
  "apiKey": "mir_agent_...",
  "message": "Save this API key now. It cannot be retrieved again."
}

Errors:

  • 400 — Max spawn depth exceeded
  • 400 — Child permissions exceed parent (privilege escalation blocked)
  • 400 — Human approval required at this depth
  • 403 — Agent spawning not enabled for this enterprise

GET /v1/agents/:id/lineage

Returns the full ancestry chain from root orchestrator to self, plus direct children.

{
  "agent": { "id": "ag_003", "name": "test-runner", "spawnDepth": 2 },
  "ancestors": [
    { "id": "ag_001", "name": "orchestrator", "spawnDepth": 0, "relation": "root", "status": "ACTIVE" },
    { "id": "ag_002", "name": "build-worker", "spawnDepth": 1, "relation": "parent", "status": "ACTIVE" }
  ],
  "children": []
}

GET /v1/agents/tree

Full agent genealogy tree for the enterprise.

ParamTypeDescription
rootAgentIdstringFilter to a specific spawn tree
includeRevokedbooleanInclude revoked agents (default: false)

POST /v1/agents/:id/revoke-descendants

Kill switch — revoke an agent and recursively revoke ALL descendants. API keys are nullified permanently.

// Request
{ "reason": "Compromised pipeline" }

// Response
{ "revoked": 5, "agents": ["ag_001", "ag_002", "ag_003", "ag_004", "ag_005"] }

Enterprise Spawn Policy

Control spawn behavior through your enterprise settings:

SettingTypeDefaultDescription
agentSpawnEnabledbooleanfalseWhether agents can spawn children
agentMaxSpawnDepthint3Maximum depth of spawn tree
agentRequireApprovalAtDepthintnullDepth at which human approval is required

Spawn Guardrails

ConstraintRule
PermissionsChild cannot have permissions beyond parent's set
Event typesChild inherits parent's restrictions (can narrow, not widen)
Rate limitsChild rate limit cannot exceed parent's
Bulk itemsChild maxBulkItems cannot exceed parent's
API keySpawned agents always get their own key (never shared)
IdempotencyAI_AGENT children always enforce idempotency

MIR records, you decide. MIR tracks agent lineage as a neutral record of what happened — who spawned whom, what actions were taken, how identities relate over time. MIR does not enforce policy or send alerts. Your enterprise is responsible for automating evaluations, setting thresholds, and integrating with your security stack.

Enforce Agent Auth

Once your agents are configured, enforce agent-only API access across your organization. When enabled, all API calls must include agent context — partner key alone is rejected.

PATCH /portal/api/settings
{ "enforceAgentAuth": true }

Requires OWNER role.

Integration Example

// Register an agent programmatically
const response = await fetch('https://mir.events/v1/agents', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.MIR_PARTNER_KEY
  },
  body: JSON.stringify({
    name: 'Checkout Bot',
    type: 'AI_AGENT',
    preset: 'event_emitter',
    allowedEventTypes: ['transaction.completed']
  })
});

const { apiKey } = await response.json();
// Store apiKey securely — it is shown only once

// Agent submits events with its own key
await fetch('https://mir.events/v1/events', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': apiKey,
    'Idempotency-Key': 'txn-abc-123'
  },
  body: JSON.stringify({
    type: 'transaction.completed',
    userId: 'user-456',
    data: { amount: 99.99, currency: 'USD' }
  })
});

Member Management API

Import and manage organization members programmatically. Members are auto-linked when they sign up with a matching email.

POST /enterprise/api/members/import

Bulk import member email addresses. Users with existing MIR accounts are auto-linked immediately. Others are linked when they sign up.

Request:

{
  "members": [
    "alice@company.com",
    "bob@company.com"
  ],
  "analysts": [
    "data-team@company.com"
  ],
  "admins": [
    "admin@company.com"
  ]
}
FieldRole AssignedDescription
members or emailsMEMBERStandard organization members
analystsANALYSTCan view reports and analytics
adminsADMINCan manage team and settings

Response:

{
  "message": "Import completed",
  "results": {
    "imported": 4,
    "alreadyImported": 0,
    "autoLinked": 1,
    "invalid": 0,
    "byRole": { "members": 2, "analysts": 1, "admins": 1 },
    "errors": []
  }
}

Maximum 500 emails per request. Requires OWNER or ADMIN role.

GET /enterprise/api/members/invites

List all imported email invites and their status.

Response:

{
  "invites": [
    {
      "id": "inv_abc123",
      "email": "alice@company.com",
      "status": "CLAIMED",
      "createdAt": "2025-01-06T12:00:00Z",
      "claimedAt": "2025-01-06T14:30:00Z",
      "importSource": "api"
    },
    {
      "id": "inv_def456",
      "email": "bob@company.com",
      "status": "PENDING",
      "createdAt": "2025-01-06T12:00:00Z",
      "claimedAt": null,
      "importSource": "api"
    }
  ]
}
StatusDescription
PENDINGAwaiting user signup/verification
CLAIMEDUser signed up and was auto-linked
REMOVEDRemoved by admin

Auto-Linking: When a user verifies their email address, they are automatically added as a member to any organization that imported their email. No additional action required.

Support