Modei
PricingDocsBlog

Documentation

Permission Catalogs

Permission catalogs define what your gate offers, at what price, with what service-level agreement (SLA). Published as immutable, cryptographically signed snapshots. Agents can verify terms locally, trustless.

··

Building a Catalog

Use the visual catalog builder in the dashboard (Dashboard → Gates → [gate] → Catalog) or the API. Each permission entry includes:

Permission key

api:search

What the agent is allowed to do.

Pricing constraints

per_call_cents: 2

How much each call costs.

SLA constraints

uptime_bp: 9990

Your service guarantees.

catalog draft
{
  "permissions": [
    {
      "key": "api:search",
      "description": "Search the knowledge base",
      "risk_level": "low",
      "constraints": {
        "core:pricing:per_call_cents": 2,
        "core:pricing:model": "per_call",
        "core:sla:uptime_basis_points": 9990,
        "core:sla:response_time_ms": 200,
        "core:rate:max_per_minute": 60
      }
    },
    {
      "key": "api:export",
      "description": "Export data (large operations)",
      "risk_level": "medium",
      "constraints": {
        "core:pricing:per_call_cents": 50,
        "core:pricing:model": "per_call",
        "core:approval:required": true,
        "core:cost:approval_threshold": 1000,
        "core:sla:uptime_basis_points": 9990
      }
    },
    {
      "key": "api:premium",
      "description": "Premium tier with SLA guarantee",
      "risk_level": "medium",
      "constraints": {
        "core:pricing:per_call_cents": 10,
        "core:sla:uptime_basis_points": 99990,
        "core:sla:response_time_ms": 50,
        "core:platform_fee:basis_points": 250
      }
    }
  ]
}

Publishing a Catalog

Publishing is atomic and irreversible. The system:

1. Builds the catalog snapshot from the current draft
2. RFC 8785 canonicalization (deterministic JSON)
3. SHA-256 content hash
4. Ed25519 signature by the gate's signing key
5. Atomic RPC: lock gate → increment version → insert immutable row → update gates.current_catalog_version
6. Rebuild discovery index (if gate is_discoverable = true)
bash
# Via API
curl -X POST https://modei.ai/api/v1/gates/gate_my-api/catalog/publish \
  -H "Authorization: Bearer mod_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "change_summary": "Added premium tier; price reduction on api:search",
    "effective_at": "2026-03-01T00:00:00Z"
  }'

# Response:
# {
#   "version": 3,
#   "content_hash": "sha256:abc123...",
#   "published_at": "2026-02-24T14:30:00Z",
#   "catalog_signature": "base64url...",
#   "signing_key_id": "key_01HXYZ..."
# }
MCP: publish_catalog
{
  "gate_id": "gate_my-api",
  "change_summary": "Added premium tier",
  "effective_at": "2026-03-01T00:00:00Z"
}

Version History

Every published catalog version is permanently stored and accessible. The database has triggers that prevent any updates or deletes, immutability is enforced at the DB level.

bash
# List all versions
GET /api/gates/gate_my-api/catalog/versions
Authorization: Bearer mod_your_key

# Get specific version
GET /api/gates/gate_my-api/catalog/3
Authorization: Bearer mod_your_key

Breaking Change Detection

Before publishing, check the impact of your changes. The system detects:

  • Permission removals (breaking, agents will lose access)
  • Price increases (breaking, agents pay more)
  • SLA downgrades (breaking, weaker guarantees)
  • Platform fee increases (breaking)
  • Trust level raises (breaking, more restrictive)
bash
# Check impact before publishing
POST /api/gates/gate_my-api/catalog/impact
Authorization: Bearer mod_your_key

# Response:
{
  "has_breaking_changes": true,
  "changes": [
    {
      "type": "price_increase",
      "permission_key": "api:search",
      "old_value": 2,
      "new_value": 5,
      "breaking": true
    },
    {
      "type": "permission_removed",
      "permission_key": "api:legacy",
      "breaking": true
    }
  ]
}

Trustless Verification by Agents

When an agent receives a discovery result or a catalog from your gate, it can verify the catalog locally without trusting your server:

Python SDK helpers for commerce are coming soon. Use the REST API until modei.commerce ships.

To verify locally from a discovery result: fetch the full catalog at GET /api/v1/gates/{gate_id}/catalog/{catalog_version}, recompute the SHA-256 content hash and confirm it matches catalog_content_hash, then verify the Ed25519 catalog_signature against the gate's signing_key_id. If any check fails, treat the catalog as tampered and do not trust its terms.

Related