{
  "openapi": "3.0.4",
  "info": {
    "title": "Chainlink ACE Coordinator API",
    "version": "0.1.0",
    "description": "The Coordinator API is the control plane for ACE. Use it to create and manage all ACE resources for your organization."
  },
  "servers": [
    {
      "url": "https://ace.api.chain.link/v1",
      "description": "Production"
    }
  ],
  "components": {
    "schemas": {
      "ActionValidatorResponse": {
        "type": "object",
        "required": ["chain_selector", "validator_address"],
        "properties": {
          "chain_selector": {
            "type": "string",
            "description": "Chain selector identifying the network"
          },
          "validator_address": {
            "type": "string",
            "description": "Deployed CertifiedActionDONValidator contract address on this chain"
          }
        }
      },
      "AnyPolicyImplementationResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/PolicyImplementation"
          },
          {
            "$ref": "#/components/schemas/OffchainPolicyImplementation"
          }
        ]
      },
      "AnyPolicyResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/Policy"
          },
          {
            "$ref": "#/components/schemas/OffchainPolicyResponse"
          }
        ],
        "discriminator": {
          "propertyName": "policy_kind",
          "mapping": {
            "onchain": "#/components/schemas/Policy",
            "offchain": "#/components/schemas/OffchainPolicyResponse"
          }
        }
      },
      "ApiErrorResponse": {
        "type": "object",
        "required": ["error", "message"],
        "properties": {
          "message": {
            "type": "string",
            "description": "Message of the response"
          },
          "error": {
            "type": "string",
            "description": "Error type",
            "enum": ["Already exists", "Internal error", "Not found", "Bad request", "Unauthorized", "Forbidden"]
          }
        }
      },
      "ApplyOnchainPolicy": {
        "type": "object",
        "required": ["chain_selector", "current_policy_config_version"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "current_policy_config_version": {
            "type": "string",
            "format": "uint64",
            "description": "Current policy config version on chain"
          }
        }
      },
      "ChainSelector": {
        "type": "string",
        "format": "uint64",
        "description": "Chain selector"
      },
      "ConfigureDataValidatorChains": {
        "type": "object",
        "required": ["chain_selector", "current_config_version"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "current_config_version": {
            "type": "string",
            "format": "uint64",
            "description": "Expected current config version on-chain (optimistic concurrency)"
          }
        }
      },
      "ContractConfigSchema": {
        "type": "object",
        "additionalProperties": {},
        "description": "JSON Schema draft-07 document defining configurable parameters for an on-chain contract\nimplementation.\n"
      },
      "CreateAnyPolicyRequest": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/CreatePolicyRequest"
          },
          {
            "$ref": "#/components/schemas/CreateOffchainPolicyRequest"
          }
        ],
        "description": "Create an onchain or offchain policy. `policy_kind` is optional and defaults to `\"onchain\"` if omitted. Set `policy_kind` to `\"offchain\"` to create an offchain policy.\n"
      },
      "CreateCredentialInput": {
        "type": "object",
        "required": ["credential_type_id"],
        "properties": {
          "credential_type_id": {
            "$ref": "#/components/schemas/Id"
          },
          "credential_data": {
            "description": "Required when the credential type is linked to a data schema (JSON object or array per data schema)"
          },
          "external_unique_id": {
            "type": "string",
            "description": "External unique identifier for the credential"
          },
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration timestamp of the credential"
          }
        }
      },
      "CreateCredentialRegistryInput": {
        "type": "object",
        "required": ["name", "chain_selector", "description"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the credential registry"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress",
            "description": "Optional address. If not provided, the registry will be deployed and status will be creation_pending"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "description": {
            "type": "string",
            "description": "Description of the credential registry"
          }
        }
      },
      "CreateDataValidatorRequest": {
        "type": "object",
        "required": ["name", "data_validator_implementation_id"],
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "data_validator_implementation_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_data_validators": {
            "type": "array",
            "description": "On-chain deployments; each chain_selector may appear at most once",
            "items": {
              "$ref": "#/components/schemas/CreateOnchainDataValidatorRequest"
            }
          }
        }
      },
      "CreateExtractorRequest": {
        "type": "object",
        "required": ["name", "supported_function_signatures", "outputs"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the extractor"
          },
          "supported_function_signatures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Function signatures that the extractor supports"
          },
          "outputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExtractorOutputInput"
            }
          },
          "onchain_extractors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainExtractorInput"
            }
          }
        }
      },
      "CreateIdentitiesBatchRequest": {
        "type": "object",
        "required": ["identities"],
        "properties": {
          "identities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateIdentityRequest"
            },
            "description": "List of identities to create"
          }
        }
      },
      "CreateIdentitiesBatchResponse": {
        "type": "object",
        "required": ["results"],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateIdentityResult"
            },
            "description": "List of identity creation results"
          }
        }
      },
      "CreateIdentityRegistryInput": {
        "type": "object",
        "required": ["name", "chain_selector", "description"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the identity registry"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress",
            "description": "Optional address. If not provided, the registry will be deployed and status will be creation_pending"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "description": {
            "type": "string",
            "description": "Description of the identity registry"
          }
        }
      },
      "CreateIdentityRequest": {
        "type": "object",
        "required": ["title", "entity_id", "registry_id", "onchain_identities"],
        "properties": {
          "title": {
            "type": "string",
            "description": "Human-readable title of the identity"
          },
          "description": {
            "type": "string",
            "description": "Description of the identity"
          },
          "entity_id": {
            "type": "string",
            "description": "Entity ID of the identity"
          },
          "registry_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_identities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainIdentityInput"
            },
            "description": "Onchain identities to register with the identity"
          },
          "credentials": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateCredentialInput"
            },
            "description": "Optional list of credentials to create for the new identity"
          }
        }
      },
      "CreateIdentityResult": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "identity": {
            "$ref": "#/components/schemas/Identity"
          },
          "status": {
            "$ref": "#/components/schemas/CreateIdentityResultStatus"
          },
          "error": {
            "type": "string",
            "description": "Error message if creation failed"
          }
        }
      },
      "CreateIdentityResultStatus": {
        "type": "string",
        "description": "Status of the identity creation",
        "enum": ["created", "failed"]
      },
      "CreateOffchainPolicyRequest": {
        "type": "object",
        "required": ["type", "name", "policy_engine_id", "onchain_policies", "config"],
        "properties": {
          "policy_kind": {
            "type": "string",
            "enum": ["offchain"],
            "description": "Optional. Set to \"offchain\" to create an offchain policy. Defaults to \"onchain\" if omitted."
          },
          "type": {
            "type": "string",
            "enum": ["wallet_risk_scoring"],
            "description": "Managed offchain policy MVP type. ACE Beta supports wallet_risk_scoring. Contact your Chainlink representative for setup assistance."
          },
          "name": {
            "type": "string",
            "description": "Human-readable policy name"
          },
          "policy_engine_id": {
            "$ref": "#/components/schemas/Id",
            "description": "ID of the onchain PolicyEngine this policy is associated with"
          },
          "onchain_policies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateOnchainTargetProtectionRequest"
            },
            "minItems": 1,
            "description": "Chain selectors to deploy the CertifiedActionDONValidator on (one deployment per chain)"
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Wallet screening configuration. Use secret_name, addresses_to_check, risk_threshold, block_unknown, optional category_filters, and optional fail_mode."
          }
        }
      },
      "CreateOnchainDataValidatorRequest": {
        "type": "object",
        "required": ["chain_selector"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "initial_config": {
            "type": "object",
            "description": "Initial configuration for schema-derived keys",
            "additionalProperties": true
          }
        }
      },
      "CreateOnchainPolicyRequest": {
        "type": "object",
        "required": ["chain_selector"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "initial_config": {
            "type": "object",
            "description": "Initial configuration values for properties listed in initial_configs",
            "additionalProperties": true
          }
        }
      },
      "CreateOnchainTargetProtectionRequest": {
        "type": "object",
        "required": ["chain_selector"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          }
        }
      },
      "CreatePolicyEngineRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy engine"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the policy engine"
          },
          "extractor_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Id"
            }
          },
          "onchain_policy_engines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyEngineInput"
            }
          }
        },
        "required": ["name", "onchain_policy_engines"]
      },
      "CreatePolicyRequest": {
        "type": "object",
        "required": ["name", "policy_implementation_id", "policy_engine_id"],
        "properties": {
          "policy_kind": {
            "type": "string",
            "enum": ["onchain"],
            "description": "Optional. Identifies this as an onchain policy creation request. Defaults to \"onchain\" if omitted."
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy instance"
          },
          "description": {
            "type": "string",
            "description": "Description of the policy instance"
          },
          "policy_implementation_id": {
            "$ref": "#/components/schemas/Id"
          },
          "policy_engine_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_policies": {
            "type": "array",
            "description": "On-chain deployments; each chain_selector may appear at most once",
            "items": {
              "$ref": "#/components/schemas/CreateOnchainPolicyRequest"
            }
          }
        }
      },
      "CreateRegistryAccessGrantRequest": {
        "type": "object",
        "required": ["grantee_org_id"],
        "properties": {
          "grantee_org_id": {
            "$ref": "#/components/schemas/OrgId",
            "description": "Organization ID to grant registry access to"
          }
        }
      },
      "CreateRegistryRequest": {
        "type": "object",
        "required": ["name", "description"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the registry"
          },
          "description": {
            "type": "string",
            "description": "Description of the registry"
          },
          "identity_registries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateIdentityRegistryInput"
            },
            "description": "List of identity registries to create and associate with this registry"
          },
          "credential_registries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateCredentialRegistryInput"
            },
            "description": "List of credential registries to create and associate with this registry"
          }
        }
      },
      "CreateTargetProtectionRequest": {
        "type": "object",
        "required": ["function_signature", "policy_instance_id"],
        "description": "For onchain policies, `policy_instance_id` is the onchain policy instance ID and `policy_kind` may be omitted (defaults to \"onchain\"). For offchain (CADV) policies, `policy_instance_id` is the offchain policy ID and `policy_kind` must be \"offchain\".\n",
        "properties": {
          "function_signature": {
            "type": "string",
            "description": "Function signature of the target protection"
          },
          "policy_instance_id": {
            "$ref": "#/components/schemas/Id",
            "description": "ID of the policy to protect. For onchain policies this is the policy instance ID; for offchain policies this is the offchain policy ID."
          },
          "policy_kind": {
            "type": "string",
            "enum": ["onchain", "offchain"],
            "description": "Kind of policy being protected. Defaults to \"onchain\" if omitted."
          },
          "desired_position": {
            "type": "integer",
            "description": "Desired position of the target protection"
          },
          "onchain_target_protections": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/CreateOnchainTargetProtectionRequest"
            }
          },
          "extractor_output_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Id"
            }
          }
        }
      },
      "CreateWalletRequest": {
        "type": "object",
        "required": ["owner_address", "chain_selector"],
        "properties": {
          "owner_address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "type": "array",
            "description": "ECDSA signer addresses allowed to sign transactions for this wallet. Only required for self-sign organizations.",
            "items": {
              "$ref": "#/components/schemas/EthAddress"
            }
          }
        }
      },
      "CreateWalletsRequest": {
        "type": "object",
        "required": ["wallets"],
        "properties": {
          "wallets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateWalletRequest"
            }
          }
        }
      },
      "CreatedAt": {
        "type": "integer",
        "format": "int64",
        "description": "Timestamp of the creation"
      },
      "Credential": {
        "type": "object",
        "required": [
          "id",
          "credential_type_id",
          "external_unique_id",
          "identity_id",
          "chain_selectors",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "credential_type_id": {
            "$ref": "#/components/schemas/Id"
          },
          "credential_type": {
            "$ref": "#/components/schemas/CredentialType"
          },
          "credential_data": {
            "nullable": true,
            "description": "Validated credential payload JSON when the credential type is linked to a data schema; null otherwise"
          },
          "external_unique_id": {
            "type": "string",
            "description": "External unique identifier for the credential"
          },
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration timestamp of the credential"
          },
          "identity_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_credentials": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainCredential"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when the credential was archived (null if not archived)"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "CredentialRegistry": {
        "type": "object",
        "required": [
          "id",
          "address",
          "name",
          "description",
          "created_at",
          "updated_at",
          "org_id",
          "chain_selector",
          "registry_id",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the credential registry"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the credential registry"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "registry_id": {
            "$ref": "#/components/schemas/Id"
          },
          "status": {
            "$ref": "#/components/schemas/RegistryStatus"
          }
        }
      },
      "CredentialStatus": {
        "type": "string",
        "description": "Status of the credential (active or archived)",
        "enum": ["active", "archived"]
      },
      "CredentialType": {
        "type": "object",
        "required": [
          "id",
          "registry_id",
          "title",
          "credential_type_hash",
          "chain_selectors",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "registry_id": {
            "$ref": "#/components/schemas/Id"
          },
          "title": {
            "type": "string",
            "description": "Title of the credential type"
          },
          "description": {
            "type": "string",
            "description": "Description of the credential type"
          },
          "credential_type": {
            "type": "string",
            "description": "Type of the credential (e.g., \"common.KYC\")"
          },
          "credential_type_hash": {
            "type": "string",
            "description": "Hash of the credential type"
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if not archived)",
            "nullable": true
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "data_schema": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/CredentialTypeEmbeddedDataSchema"
              }
            ]
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "CredentialTypeEmbeddedDataSchema": {
        "type": "object",
        "description": "Data schema linked to a credential type for credential payload validation",
        "required": ["id", "name", "description", "schema"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "schema": {
            "$ref": "#/components/schemas/PolicyConfigSchema"
          }
        }
      },
      "CredentialTypePatchStatus": {
        "type": "string",
        "description": "Status for credential type PATCH (archive only)",
        "enum": ["archived"]
      },
      "DataValidator": {
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "data_validator_implementation_id",
          "onchain_configs",
          "chain_selectors"
        ],
        "description": "A data validator instance (deployment aggregate across chains).",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "data_validator_implementation_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_configs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DataValidatorOnchainConfig"
            }
          },
          "onchain_data_validators": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainDataValidatorInstance"
            },
            "description": "Deprecated — prefer onchain_configs for config grouping; retained for backward compatibility."
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "ongoing_config_changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OngoingConfigChange"
            }
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Unix timestamp when archived"
          }
        }
      },
      "DataValidatorOnchainConfig": {
        "type": "object",
        "required": ["id", "chain_selectors", "config_json"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id",
            "description": "Data validator config log ID"
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            },
            "description": "Chain selectors sharing this config log"
          },
          "config_json": {
            "type": "object",
            "additionalProperties": true,
            "description": "Configuration JSON for this log"
          }
        }
      },
      "DataValidatorPatchStatus": {
        "type": "string",
        "description": "PATCH body for archiving a data validator instance",
        "enum": ["archived"]
      },
      "EthAddress": {
        "type": "string",
        "pattern": "^0x[a-fA-F0-9]{40}$",
        "description": "Ethereum address"
      },
      "Extractor": {
        "type": "object",
        "required": [
          "id",
          "name",
          "supported_function_signatures",
          "chain_selectors",
          "outputs",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the extractor"
          },
          "org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "supported_function_signatures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Function signatures that the extractor supports"
          },
          "outputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExtractorOutput"
            }
          },
          "onchain_extractors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainExtractor"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if not archived)",
            "nullable": true
          }
        }
      },
      "ExtractorOutput": {
        "type": "object",
        "required": ["id", "extractor_id", "name", "type", "created_at", "updated_at"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "extractor_id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the extractor output"
          },
          "type": {
            "type": "string",
            "description": "Type of the extractor output, e.g. \"address\", \"uint256\", \"bytes32\""
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "ExtractorOutputInput": {
        "type": "object",
        "required": ["name", "type"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the extractor output"
          },
          "type": {
            "type": "string",
            "description": "Type of the extractor output, e.g. \"address\", \"uint256\", \"bytes32\""
          }
        }
      },
      "ExtractorPatchStatus": {
        "type": "string",
        "description": "Status for extractor PATCH (archive only)",
        "enum": ["archived"]
      },
      "ExtractorRegistration": {
        "type": "object",
        "required": [
          "id",
          "extractor_id",
          "policy_engine_id",
          "onchain_extractor_registrations",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "extractor_id": {
            "$ref": "#/components/schemas/Id"
          },
          "policy_engine_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_extractor_registrations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainExtractorRegistration"
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "HealthCheck": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          }
        },
        "required": ["status"]
      },
      "Id": {
        "type": "string",
        "format": "uuid",
        "description": "ID"
      },
      "Identity": {
        "type": "object",
        "required": ["id", "title", "ccid", "chain_selectors", "created_at", "updated_at"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "title": {
            "type": "string",
            "description": "Human-readable title of the identity"
          },
          "description": {
            "type": "string",
            "description": "Description of the identity"
          },
          "entity_id": {
            "type": "string",
            "description": "Entity ID of the identity"
          },
          "ccid": {
            "type": "string",
            "description": "CCID of the identity"
          },
          "registryId": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_identities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainIdentity"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when the identity was archived (null if not archived)"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "IdentityPatchStatus": {
        "type": "string",
        "description": "Status for identity PATCH (archive only)",
        "enum": ["archived"]
      },
      "IdentityRegistry": {
        "type": "object",
        "required": [
          "id",
          "address",
          "name",
          "description",
          "created_at",
          "updated_at",
          "org_id",
          "chain_selector",
          "registry_id",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the identity registry"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the identity registry"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "registry_id": {
            "$ref": "#/components/schemas/Id"
          },
          "status": {
            "$ref": "#/components/schemas/RegistryStatus"
          }
        }
      },
      "IdentityStatus": {
        "type": "string",
        "description": "Status of the identity",
        "enum": ["creation_pending", "creation_failed", "created", "removal_pending", "removal_failed", "removed"]
      },
      "JsonPatchOperation": {
        "type": "object",
        "required": ["op", "path"],
        "properties": {
          "op": {
            "type": "string",
            "description": "JSON Patch operation type",
            "enum": ["add", "remove", "replace", "move", "copy", "test"]
          },
          "path": {
            "type": "string",
            "description": "JSON pointer path to patch (RFC 6902)"
          },
          "value": {
            "description": "Value for the operation (can be any JSON type: string, number, boolean, object, array, or null)",
            "nullable": true
          },
          "from": {
            "type": "string",
            "description": "Source path for move/copy operations (RFC 6902)"
          }
        }
      },
      "ListCredentialTypesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["credential_types"],
            "properties": {
              "credential_types": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CredentialType"
                }
              }
            }
          }
        ]
      },
      "ListCredentialsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["credentials"],
            "properties": {
              "credentials": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Credential"
                }
              }
            }
          }
        ]
      },
      "ListDataValidatorsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "properties": {
              "data_validators": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DataValidator"
                }
              }
            }
          }
        ]
      },
      "ListExtractorsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["extractors"],
            "properties": {
              "extractors": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Extractor"
                }
              }
            }
          }
        ]
      },
      "ListIdentitiesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["identities"],
            "properties": {
              "identities": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Identity"
                }
              }
            }
          }
        ]
      },
      "ListNetworksResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["networks"],
            "properties": {
              "networks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Network"
                }
              }
            }
          }
        ]
      },
      "ListOffchainPolicyProtectionsResponse": {
        "type": "object",
        "required": ["protections", "total", "total_pages", "page"],
        "properties": {
          "protections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OffchainPolicyProtectionResponse"
            }
          },
          "total": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          }
        }
      },
      "ListPoliciesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "properties": {
              "policies": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AnyPolicyResponse"
                }
              }
            }
          }
        ]
      },
      "ListPolicyEnginesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["policy_engines"],
            "properties": {
              "policy_engines": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PolicyEngine"
                }
              }
            }
          }
        ]
      },
      "ListPolicyImplementationsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["implementations"],
            "properties": {
              "implementations": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AnyPolicyImplementationResponse"
                }
              }
            }
          }
        ]
      },
      "ListRegistriesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["registries"],
            "properties": {
              "registries": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Registry"
                }
              }
            }
          }
        ]
      },
      "ListRegistryAccessGrantsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["access_grants"],
            "properties": {
              "access_grants": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/RegistryAccessGrant"
                }
              }
            }
          }
        ]
      },
      "ListResponseData": {
        "type": "object",
        "required": ["total", "total_pages", "page"],
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total number of items"
          },
          "total_pages": {
            "type": "integer",
            "description": "Total number of pages"
          },
          "page": {
            "type": "integer",
            "description": "Current page"
          }
        }
      },
      "ListTargetProtectionsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["target_protections"],
            "properties": {
              "target_protections": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TargetProtection"
                }
              }
            }
          }
        ]
      },
      "ListTargetsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ListResponseData"
          },
          {
            "type": "object",
            "required": ["targets"],
            "properties": {
              "targets": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Target"
                }
              }
            }
          }
        ]
      },
      "ListWalletsResponse": {
        "type": "object",
        "required": ["wallets"],
        "properties": {
          "wallets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Wallet"
            }
          }
        }
      },
      "MergeTargetRequest": {
        "type": "object",
        "required": ["source_target_ids"],
        "properties": {
          "source_target_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Id"
            },
            "minItems": 1,
            "description": "The IDs of the source targets whose onchain targets will be transferred to the destination target."
          }
        }
      },
      "Network": {
        "type": "object",
        "required": [
          "id",
          "name",
          "chain_id",
          "chain_selector",
          "chain_family",
          "is_testnet",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the network"
          },
          "chain_id": {
            "type": "string",
            "description": "Chain ID of the network"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "chain_family": {
            "type": "string",
            "description": "Chain family of the network"
          },
          "is_testnet": {
            "type": "boolean",
            "description": "Whether this network is a testnet (not mainnet)"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "OffchainPolicyImplementation": {
        "type": "object",
        "required": ["id", "name", "type", "config", "created_at", "updated_at"],
        "properties": {
          "policy_kind": {
            "type": "string",
            "enum": ["offchain"],
            "description": "Discriminator identifying this as an offchain policy implementation"
          },
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "Unique managed policy type identifier, for example wallet_risk_scoring"
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Implementation config including provider, provider_url, and config_schema"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OffchainPolicyProtectionResponse": {
        "type": "object",
        "required": ["id", "offchain_policy_id", "function_signature", "function_selector", "status", "created_at"],
        "properties": {
          "id": {
            "type": "string"
          },
          "offchain_policy_id": {
            "type": "string"
          },
          "function_signature": {
            "type": "string"
          },
          "function_selector": {
            "type": "string",
            "description": "4-byte hex selector, e.g. \"0xa9059cbb\""
          },
          "status": {
            "type": "string",
            "enum": ["pending", "active", "failed", "removing", "removed"]
          },
          "onchain_target_protections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainTargetProtection"
            },
            "description": "Per-chain status of the addPolicyAt() registration on the PolicyEngine"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OffchainPolicyResponse": {
        "type": "object",
        "required": ["id", "type", "name", "config", "deployment_status", "created_at", "policy_kind"],
        "properties": {
          "policy_kind": {
            "type": "string",
            "enum": ["offchain"],
            "description": "Discriminator identifying this as an offchain policy"
          },
          "id": {
            "type": "string",
            "description": "Policy ID"
          },
          "type": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "config": {
            "type": "object",
            "additionalProperties": true
          },
          "policy_engine_id": {
            "type": "string",
            "description": "ID of the onchain PolicyEngine this policy is associated with"
          },
          "policy_implementation_id": {
            "type": "string",
            "description": "ID of the offchain policy implementation (template) used to create this policy"
          },
          "action_validators": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionValidatorResponse"
            },
            "description": "Per-chain CADV deployment info (chain selector + contract address). Populated once deployment_status is active."
          },
          "deployment_status": {
            "type": "string",
            "enum": ["pending", "deploying", "active", "failed", "removing", "removed", "config_updating"]
          },
          "workflow_id": {
            "type": "string"
          },
          "workflow_name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OnChainCredentialStatus": {
        "type": "string",
        "description": "Status of the onchain credential\n",
        "enum": [
          "creation_pending",
          "creation_failed",
          "created",
          "update_pending",
          "update_failed",
          "removal_pending",
          "removal_failed",
          "removed"
        ]
      },
      "OnchainConfig": {
        "type": "object",
        "required": ["id", "chain_selectors", "config_json"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id",
            "description": "Policy config log ID"
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            },
            "description": "Array of chain selectors that use this config"
          },
          "config_json": {
            "type": "object",
            "additionalProperties": true,
            "description": "The policy configuration as JSON"
          }
        }
      },
      "OnchainCredential": {
        "type": "object",
        "required": ["id", "chain_selector", "status"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "status": {
            "$ref": "#/components/schemas/OnChainCredentialStatus"
          },
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration timestamp of the credential"
          }
        }
      },
      "OnchainDataValidatorInstance": {
        "type": "object",
        "required": ["id", "chain_selector", "data_validator_config_version", "status"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "data_validator_config_version": {
            "type": "string",
            "format": "uint64",
            "description": "Version of the data validator configuration on-chain"
          },
          "status": {
            "$ref": "#/components/schemas/OnchainDataValidatorInstanceStatus"
          }
        }
      },
      "OnchainDataValidatorInstanceStatus": {
        "type": "string",
        "description": "Status of an on-chain data validator deployment",
        "enum": ["creation_pending", "creation_failed", "created", "update_pending", "update_failed"]
      },
      "OnchainExtractor": {
        "type": "object",
        "required": ["id", "extractor_id", "chain_selector", "address", "created_at", "updated_at"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "extractor_id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "type": "string",
            "description": "Chain selector"
          },
          "address": {
            "type": "string",
            "description": "Ethereum address"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "OnchainExtractorInput": {
        "type": "object",
        "required": ["chain_selector", "address"],
        "properties": {
          "chain_selector": {
            "type": "string",
            "description": "Chain selector"
          },
          "address": {
            "type": "string",
            "description": "Ethereum address"
          }
        }
      },
      "OnchainExtractorRegistration": {
        "type": "object",
        "required": ["id", "chain_selector", "status", "created_at", "updated_at"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "status": {
            "$ref": "#/components/schemas/OnchainStatus"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "OnchainIdentity": {
        "type": "object",
        "required": ["id", "chain_selector", "identity_id", "address", "status", "created_at", "updated_at"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "identity_id": {
            "$ref": "#/components/schemas/Id"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "status": {
            "$ref": "#/components/schemas/IdentityStatus"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "OnchainIdentityInput": {
        "type": "object",
        "required": ["chain_selector", "address"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          }
        }
      },
      "OnchainPolicyEngine": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "status": {
            "$ref": "#/components/schemas/OnchainPolicyEngineStatus"
          }
        },
        "required": ["id", "address", "chain_selector", "status"]
      },
      "OnchainPolicyEngineInput": {
        "type": "object",
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          }
        },
        "required": ["chain_selector"]
      },
      "OnchainPolicyEngineStatus": {
        "type": "string",
        "description": "Status of the onchain policy engine",
        "enum": ["creation_pending", "creation_failed", "created"]
      },
      "OnchainPolicyImplementation": {
        "type": "object",
        "required": ["chain_selector", "address"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          }
        }
      },
      "OnchainPolicyInstance": {
        "type": "object",
        "required": ["id", "chain_selector", "policy_config_version", "out_of_sync", "status"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "policy_config_version": {
            "type": "string",
            "format": "uint64",
            "description": "Version of the policy configuration"
          },
          "out_of_sync": {
            "type": "boolean",
            "description": "Whether the policy configuration is out of sync due to an external configuration change"
          },
          "status": {
            "$ref": "#/components/schemas/OnchainPolicyInstanceStatus"
          }
        }
      },
      "OnchainPolicyInstanceStatus": {
        "type": "string",
        "description": "Status of the onchain policy instance",
        "enum": ["creation_pending", "creation_failed", "created", "update_pending", "update_failed"]
      },
      "OnchainStatus": {
        "type": "string",
        "description": "Status of the onchain entity",
        "enum": ["active", "inactive"]
      },
      "OnchainTarget": {
        "type": "object",
        "required": ["id", "chain_selector", "address"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "default_allow": {
            "type": "boolean",
            "description": "Default policy allow state on chain",
            "default": true
          }
        }
      },
      "OnchainTargetProtection": {
        "type": "object",
        "required": ["id", "chain_selector"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "position": {
            "type": "integer",
            "description": "Position of the target protection in for this specific chain"
          },
          "status": {
            "$ref": "#/components/schemas/TargetProtectionStatus"
          }
        }
      },
      "OngoingConfigChange": {
        "type": "object",
        "required": ["chain_selectors", "patches"],
        "properties": {
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            },
            "description": "Array of chain selectors for this configuration change"
          },
          "patches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonPatchOperation"
            },
            "description": "Array of JSON patch operations to apply"
          }
        }
      },
      "OrgId": {
        "type": "string",
        "description": "Organization ID (e.g. from CRE). Alphanumeric and limited symbols, max 100 characters.",
        "pattern": "^[a-zA-Z0-9._-]{1,100}$"
      },
      "PatchCredentialRequest": {
        "type": "object",
        "description": "Either status (to archive) OR update fields (external_unique_id, expires_at). Mutually exclusive.\n- If status is passed, other fields must not be passed (400).\n- If status=archived and credential is already archived, returns 400.\n- Only status=archived triggers archive; status=active is invalid for PATCH.\n- If external_unique_id or expires_at are set, reuses update logic.\n",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/CredentialStatus",
            "description": "Set to \"archived\" to archive. Mutually exclusive with update fields."
          },
          "external_unique_id": {
            "type": "string",
            "description": "External unique identifier. Mutually exclusive with status."
          },
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration timestamp. Mutually exclusive with status."
          }
        }
      },
      "PatchCredentialTypeRequest": {
        "type": "object",
        "description": "Either status (to archive) OR update fields (title, description). Mutually exclusive.\n- If status is passed, other fields must not be passed (400).\n- If status=archived and credential type is already archived, returns 400.\n- Only status=archived triggers archive.\n- If title or description are set, internally calls UpdateCredentialType (PUT).\n",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/CredentialTypePatchStatus",
            "description": "Set to \"archived\" to archive. Mutually exclusive with update fields."
          },
          "title": {
            "type": "string",
            "description": "Human-readable title. Mutually exclusive with status."
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the credential type. Mutually exclusive with status."
          }
        }
      },
      "PatchDataValidatorConfigsRequest": {
        "type": "object",
        "properties": {
          "patches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonPatchOperation"
            },
            "description": "JSON Patch operations (RFC 6902)"
          },
          "on_chains": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConfigureDataValidatorChains"
            },
            "description": "Chains to apply patches on (must include at least one entry)"
          }
        }
      },
      "PatchDataValidatorRequest": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "status": {
            "$ref": "#/components/schemas/DataValidatorPatchStatus"
          }
        }
      },
      "PatchExtractorRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the extractor.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/ExtractorPatchStatus",
            "description": "Set to \"archived\" to archive."
          }
        }
      },
      "PatchIdentityRequest": {
        "type": "object",
        "description": "Either status (to archive) OR update fields (title, description, onchain_identities). Mutually exclusive.\n- If status is passed, other fields must not be passed (400).\n- If status=archived and identity is already archived, returns 400.\n- Only status=archived triggers archive.\n- If title, description, or onchain_identities are set, internally calls UpdateIdentity (PUT).\n",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/IdentityPatchStatus",
            "description": "Set to \"archived\" to archive. Mutually exclusive with update fields."
          },
          "title": {
            "type": "string",
            "description": "Human-readable title. Mutually exclusive with status."
          },
          "description": {
            "type": "string",
            "description": "Description of the identity. Mutually exclusive with status."
          },
          "onchain_identities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainIdentityInput"
            },
            "description": "Onchain identities to register. Mutually exclusive with status."
          }
        }
      },
      "PatchPolicyConfigsRequest": {
        "type": "object",
        "properties": {
          "patches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonPatchOperation"
            },
            "description": "Array of JSON Patch operations to apply"
          },
          "apply_onchain_policies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplyOnchainPolicy"
            },
            "description": "Array of onchain policies to apply the patches to"
          }
        }
      },
      "PatchPolicyEngineRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the policy engine.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/PolicyEnginePatchStatus",
            "description": "Set to \"archived\" to archive."
          }
        }
      },
      "PatchPolicyImplementationRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the policy implementation.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/PolicyImplementationPatchStatus",
            "description": "Set to \"archived\" to archive."
          }
        }
      },
      "PatchPolicyRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the policy. Use policy_kind to distinguish onchain (default) from offchain policies.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/PolicyPatchStatus",
            "description": "Set to \"archived\" to archive."
          },
          "policy_kind": {
            "type": "string",
            "enum": ["onchain", "offchain"],
            "description": "Kind of policy to archive. Defaults to \"onchain\" if omitted."
          }
        }
      },
      "PatchRegistryAccessGrantRequest": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "status": {
            "type": "string",
            "enum": ["revoked"],
            "description": "Target status. Currently only \"revoked\" is accepted."
          }
        }
      },
      "PatchRegistryRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the registry.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/RegistryPatchStatus",
            "description": "Set to \"archived\" to archive."
          }
        }
      },
      "PatchTargetProtectionRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the target protection.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/TargetProtectionPatchStatus",
            "description": "Set to \"archived\" to archive."
          }
        }
      },
      "PatchTargetRequest": {
        "type": "object",
        "required": ["status"],
        "description": "Set status to \"archived\" to archive the target.",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/TargetPatchStatus",
            "description": "Set to \"archived\" to archive."
          }
        }
      },
      "Policy": {
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "policy_engine_id",
          "onchain_configs",
          "chain_selectors",
          "policy_kind"
        ],
        "properties": {
          "policy_kind": {
            "type": "string",
            "enum": ["onchain"],
            "description": "Discriminator identifying this as an onchain policy"
          },
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy instance"
          },
          "description": {
            "type": "string",
            "description": "Description of the policy instance"
          },
          "policy_implementation_id": {
            "$ref": "#/components/schemas/Id"
          },
          "policy_implementation_name": {
            "type": "string",
            "description": "Human-readable name of the policy implementation"
          },
          "policy_engine_id": {
            "$ref": "#/components/schemas/Id"
          },
          "onchain_configs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainConfig"
            },
            "description": "Array of onchain configurations grouped by config log ID"
          },
          "onchain_policies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyInstance"
            },
            "description": "Deprecated - use onchain_configs instead"
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "ongoing_config_changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OngoingConfigChange"
            },
            "description": "Array of ongoing configuration changes"
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if not archived)",
            "nullable": true
          }
        }
      },
      "PolicyConfigSchema": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ContractConfigSchema"
          }
        ],
        "description": "JSON Schema draft-07 document defining the configurable parameters of this policy\nimplementation.\n"
      },
      "PolicyEngine": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy engine"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the policy engine"
          },
          "type": {
            "$ref": "#/components/schemas/PolicyEngineType"
          },
          "onchain_policy_engines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyEngine"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "extractor_registrations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExtractorRegistration"
            }
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if not archived)",
            "nullable": true
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": ["id", "name", "type", "chain_selectors", "created_at", "updated_at"]
      },
      "PolicyEnginePatchStatus": {
        "type": "string",
        "description": "Status for policy engine PATCH (archive only)",
        "enum": ["archived"]
      },
      "PolicyEngineType": {
        "type": "string",
        "description": "Type of the policy engine",
        "enum": ["standard", "system"]
      },
      "PolicyImplementation": {
        "type": "object",
        "properties": {
          "policy_kind": {
            "type": "string",
            "enum": ["onchain"],
            "description": "Discriminator identifying this as an onchain policy implementation"
          },
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy implementation"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the policy implementation"
          },
          "type": {
            "$ref": "#/components/schemas/PolicyImplementationType"
          },
          "policy_config_schema": {
            "$ref": "#/components/schemas/PolicyConfigSchema"
          },
          "onchain_policy_implementations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyImplementation"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "parameters": {
            "type": "array",
            "description": "Processed policy run parameters with server-generated fields",
            "items": {
              "$ref": "#/components/schemas/PolicyRunParametersResponse"
            }
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Unix timestamp when archived; null if not archived"
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Timestamp of the creation"
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Timestamp of the last update"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "type",
          "policy_config_schema",
          "chain_selectors",
          "parameters",
          "created_at",
          "updated_at"
        ]
      },
      "PolicyImplementationPatchStatus": {
        "type": "string",
        "description": "Status for policy implementation PATCH (archive only)",
        "enum": ["archived"]
      },
      "PolicyImplementationType": {
        "type": "string",
        "description": "Type of the policy implementation; system types are predefined, custom for user-defined.",
        "enum": [
          "allow",
          "bypass",
          "certified_action_don_validator",
          "grouped_identity_validator",
          "identity_validator",
          "interval",
          "max",
          "only_authorized_sender",
          "pause",
          "reject",
          "role_based_access_control",
          "secure_mint",
          "volume",
          "volume_rate",
          "custom"
        ]
      },
      "PolicyPatchStatus": {
        "type": "string",
        "description": "Status for policy PATCH (archive only)",
        "enum": ["archived"]
      },
      "PolicyRunParametersResponse": {
        "type": "object",
        "description": "Policy parameter with server-generated fields (used in responses)",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy parameter"
          },
          "type": {
            "type": "string",
            "description": "Type of the policy parameter"
          },
          "position": {
            "type": "integer",
            "description": "Position of the policy parameter"
          },
          "max": {
            "type": "integer",
            "description": "Maximum number of values"
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Timestamp of the creation"
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Timestamp of the last update"
          }
        },
        "required": ["id", "name", "type", "position", "max", "created_at", "updated_at"]
      },
      "RegisterCredentialRequest": {
        "type": "object",
        "required": ["credential_type_id", "identity_id"],
        "properties": {
          "credential_type_id": {
            "$ref": "#/components/schemas/Id"
          },
          "credential_data": {
            "description": "Required when the credential type is linked to a data schema (JSON object or array per data schema)"
          },
          "external_unique_id": {
            "type": "string",
            "description": "External unique identifier for the credential"
          },
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration timestamp of the credential"
          },
          "identity_id": {
            "$ref": "#/components/schemas/Id"
          }
        }
      },
      "RegisterCredentialTypeRequest": {
        "type": "object",
        "required": ["registry_id", "title", "credential_type"],
        "properties": {
          "registry_id": {
            "$ref": "#/components/schemas/Id"
          },
          "title": {
            "type": "string",
            "description": "Human-readable title of the credential type"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the credential type"
          },
          "credential_type": {
            "type": "string",
            "description": "Type of the credential (e.g., \"common.KYC\")"
          },
          "data_schema_id": {
            "$ref": "#/components/schemas/Id",
            "description": "Optional shared or org-scoped data schema used to validate credential payload data"
          }
        }
      },
      "RegisterOnchainTargetRequest": {
        "type": "object",
        "required": ["chain_selector", "address"],
        "properties": {
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "address": {
            "$ref": "#/components/schemas/EthAddress"
          }
        }
      },
      "RegisterPolicyImplementationRequest": {
        "type": "object",
        "required": ["name", "description", "policy_config_schema"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy implementation"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the policy implementation"
          },
          "policy_config_schema": {
            "$ref": "#/components/schemas/PolicyConfigSchema"
          },
          "onchain_policy_implementations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyImplementation"
            }
          }
        }
      },
      "RegisterTargetRequest": {
        "type": "object",
        "required": ["title", "policy_engine_id"],
        "properties": {
          "title": {
            "type": "string",
            "description": "Human-readable title of the target"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the target"
          },
          "policy_engine_id": {
            "$ref": "#/components/schemas/Id"
          },
          "protected_methods": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Protected methods of the target"
          },
          "onchain_targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegisterOnchainTargetRequest"
            }
          },
          "desired_default_allow": {
            "type": "boolean",
            "description": "Whether to allow transactions by default if no policy explicitly returns an Allow or Reject. Defaults to true.",
            "default": true
          },
          "metadata": {
            "type": "object",
            "description": "JSON metadata associated with the target",
            "additionalProperties": true
          }
        }
      },
      "Registry": {
        "type": "object",
        "required": ["id", "name", "description", "org_id", "created_at", "updated_at", "chain_selectors", "mode"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string",
            "description": "Name of the registry"
          },
          "description": {
            "type": "string",
            "description": "Description of the registry"
          },
          "org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "identity_registries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IdentityRegistry"
            },
            "description": "List of identity registries associated with this registry"
          },
          "credential_registries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CredentialRegistry"
            },
            "description": "List of credential registries associated with this registry"
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "mode": {
            "$ref": "#/components/schemas/RegistryMode"
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if not archived)",
            "nullable": true
          },
          "access_type": {
            "type": "string",
            "enum": ["owned", "granted"],
            "description": "Whether the caller owns this registry or has been granted access by another org. Only present when the caller is a grantee or when include_granted=true is used on the list endpoint.",
            "nullable": true
          }
        }
      },
      "RegistryAccessGrant": {
        "type": "object",
        "required": ["id", "grantee_org_id", "grantor_org_id", "status", "granted_at"],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "grantee_org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "grantor_org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "status": {
            "type": "string",
            "enum": ["active", "revoked"],
            "description": "Current status of the access grant"
          },
          "granted_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when the grant was created"
          },
          "revoked_at": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Unix timestamp when the grant was revoked, null if still active"
          }
        }
      },
      "RegistryMode": {
        "type": "string",
        "description": "Mode of the registry",
        "enum": ["managed", "read_only"]
      },
      "RegistryPatchStatus": {
        "type": "string",
        "description": "Status for registry PATCH (archive only)",
        "enum": ["archived"]
      },
      "RegistryStatus": {
        "type": "string",
        "description": "Status of the registry",
        "enum": ["creation_pending", "creation_failed", "created"]
      },
      "SigningMode": {
        "type": "string",
        "description": "Signing mode for onchain operations.\n- delegated: ACE signs operations using a delegated key (default; existing behavior).\n- self_sign: ACE creates unsigned operation drafts; the tenant signs and finalizes directly with CREC.\nImmutable after org creation.\n",
        "enum": ["delegated", "self_sign"]
      },
      "Target": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "title": {
            "type": "string",
            "description": "Human-readable title of the target"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the target"
          },
          "policy_engine_id": {
            "$ref": "#/components/schemas/Id"
          },
          "protected_methods": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Protected methods of the target"
          },
          "onchain_targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainTarget"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "desired_default_allow": {
            "type": "boolean",
            "description": "Whether to allow transactions by default if no policy explicitly returns an Allow or Reject. Defaults to true.",
            "default": true
          },
          "metadata": {
            "type": "object",
            "description": "JSON metadata associated with the target",
            "additionalProperties": true
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Unix timestamp when archived; null if not archived"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "owner_org_id": {
            "$ref": "#/components/schemas/OrgId",
            "description": "Owning organization. Present when include_granted=true; for granted targets this is the grantor org."
          },
          "access_type": {
            "type": "string",
            "enum": ["owned", "granted"],
            "description": "Whether the caller owns this target or has been granted evaluation access. Only present when include_granted=true."
          }
        },
        "required": [
          "id",
          "title",
          "description",
          "policy_engine_id",
          "protected_methods",
          "desired_default_allow",
          "chain_selectors",
          "created_at",
          "updated_at"
        ]
      },
      "TargetPatchStatus": {
        "type": "string",
        "description": "Status for target PATCH (archive only)",
        "enum": ["archived"]
      },
      "TargetProtection": {
        "type": "object",
        "required": [
          "id",
          "function_selector",
          "target_id",
          "policy_instance_id",
          "chain_selectors",
          "extractor_output_ids",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "function_signature": {
            "type": "string",
            "description": "Function signature of the target protection"
          },
          "function_selector": {
            "type": "string",
            "description": "Function selector of the target protection"
          },
          "target_id": {
            "$ref": "#/components/schemas/Id"
          },
          "policy_instance_id": {
            "$ref": "#/components/schemas/Id"
          },
          "desired_position": {
            "type": "integer",
            "description": "Desired position of the target protection"
          },
          "onchain_target_protections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainTargetProtection"
            }
          },
          "chain_selectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          },
          "extractor_output_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Id"
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if not archived)",
            "nullable": true
          }
        }
      },
      "TargetProtectionPatchStatus": {
        "type": "string",
        "description": "Status for target protection PATCH (archive only)",
        "enum": ["archived"]
      },
      "TargetProtectionStatus": {
        "type": "string",
        "description": "Status of the target protection",
        "enum": ["creation_pending", "creation_failed", "created", "removal_pending", "removal_failed", "removed"]
      },
      "UpdateCredentialRequest": {
        "type": "object",
        "required": ["external_unique_id"],
        "properties": {
          "external_unique_id": {
            "type": "string",
            "description": "External unique identifier for the credential"
          },
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration timestamp of the credential"
          }
        }
      },
      "UpdateCredentialTypeRequest": {
        "type": "object",
        "required": ["title"],
        "properties": {
          "title": {
            "type": "string",
            "description": "Human-readable title of the credential type"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the credential type"
          }
        }
      },
      "UpdateDataValidatorRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "onchain_data_validators": {
            "type": "array",
            "description": "On-chain deployments; each chain_selector may appear at most once",
            "items": {
              "$ref": "#/components/schemas/CreateOnchainDataValidatorRequest"
            }
          }
        }
      },
      "UpdateExtractorRequest": {
        "type": "object",
        "required": ["name", "supported_function_signatures", "outputs"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the extractor"
          },
          "supported_function_signatures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Function signatures that the extractor supports"
          },
          "outputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExtractorOutputInput"
            }
          },
          "onchain_extractors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainExtractorInput"
            }
          }
        }
      },
      "UpdateIdentityRequest": {
        "type": "object",
        "required": ["title", "onchain_identities"],
        "properties": {
          "title": {
            "type": "string",
            "description": "Human-readable title of the identity"
          },
          "description": {
            "type": "string",
            "description": "Description of the identity"
          },
          "onchain_identities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainIdentityInput"
            },
            "description": "Onchain identities to register with the identity"
          }
        }
      },
      "UpdateOffchainPolicyConfigRequest": {
        "type": "object",
        "required": ["config"],
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Updated policy configuration. Triggers redeployment of the workflow with the new config (CRE upserts by owner + name). The policy's deployment_status will transition to config_updating while the operation is in progress.\n"
          }
        }
      },
      "UpdateOnchainPolicyRequest": {
        "type": "object",
        "properties": {}
      },
      "UpdatePolicyEngineRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy engine"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the policy engine"
          },
          "extractor_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Id"
            }
          },
          "onchain_policy_engines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyEngineInput"
            }
          }
        },
        "required": ["name", "onchain_policy_engines"]
      },
      "UpdatePolicyImplementationRequest": {
        "type": "object",
        "required": ["name", "description", "onchain_policy_implementations"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy implementation"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the policy implementation"
          },
          "onchain_policy_implementations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnchainPolicyImplementation"
            }
          }
        }
      },
      "UpdatePolicyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable name of the policy instance"
          },
          "description": {
            "type": "string",
            "description": "Description of the policy instance"
          },
          "onchain_policies": {
            "type": "array",
            "description": "On-chain deployments; each chain_selector may appear at most once",
            "items": {
              "$ref": "#/components/schemas/CreateOnchainPolicyRequest"
            }
          }
        }
      },
      "UpdateRegistryRequest": {
        "type": "object",
        "required": ["name", "description"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the registry"
          },
          "description": {
            "type": "string",
            "description": "Description of the registry"
          },
          "identity_registries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateIdentityRegistryInput"
            },
            "description": "List of identity registries"
          },
          "credential_registries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateCredentialRegistryInput"
            },
            "description": "List of credential registries"
          }
        }
      },
      "UpdateTargetProtectionRequest": {
        "type": "object",
        "required": ["onchain_target_protections"],
        "properties": {
          "onchain_target_protections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateOnchainTargetProtectionRequest"
            }
          }
        }
      },
      "UpdateTargetRequest": {
        "type": "object",
        "required": ["title"],
        "properties": {
          "owner": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "title": {
            "type": "string",
            "description": "Human-readable title of the target"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the target"
          },
          "protected_methods": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Protected methods of the target"
          },
          "onchain_targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegisterOnchainTargetRequest"
            }
          },
          "desired_default_allow": {
            "type": "boolean",
            "description": "Whether to allow transactions by default if no policy explicitly returns an Allow or Reject. When omitted, the existing value is preserved."
          },
          "metadata": {
            "type": "object",
            "description": "JSON metadata associated with the target",
            "additionalProperties": true
          }
        }
      },
      "UpdatedAt": {
        "type": "integer",
        "format": "int64",
        "description": "Timestamp of the last update"
      },
      "UserOrganization": {
        "type": "object",
        "required": [
          "id",
          "crec_channel_id",
          "crec_channel_offset",
          "signing_mode",
          "mainnet_allowed",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "crec_channel_id": {
            "$ref": "#/components/schemas/Id"
          },
          "crec_channel_offset": {
            "type": "integer",
            "description": "Offset of the CREC channel"
          },
          "signing_mode": {
            "$ref": "#/components/schemas/SigningMode"
          },
          "mainnet_allowed": {
            "type": "boolean",
            "description": "When true, the organization may use mainnet networks for on-chain resources."
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when archived (null if active)",
            "nullable": true
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "Wallet": {
        "type": "object",
        "required": [
          "id",
          "org_id",
          "chain_selector",
          "owner_address",
          "wallet_address",
          "status",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "org_id": {
            "$ref": "#/components/schemas/OrgId"
          },
          "chain_selector": {
            "$ref": "#/components/schemas/ChainSelector"
          },
          "owner_address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "wallet_address": {
            "$ref": "#/components/schemas/EthAddress"
          },
          "status": {
            "$ref": "#/components/schemas/WalletStatus"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        }
      },
      "WalletStatus": {
        "type": "string",
        "description": "Status of the wallet",
        "enum": ["creation_pending", "creation_failed", "created"]
      }
    },
    "parameters": {
      "include_onchains": {
        "name": "include_onchains",
        "in": "query",
        "description": "Whether to include onchain entities in the response. Defaults to true.",
        "required": false,
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "page": {
        "name": "page",
        "in": "query",
        "description": "Page number",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "page_size": {
        "name": "page_size",
        "in": "query",
        "description": "Number of items to return per page",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 10
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "API key authentication. Format: `Apikey <api-key>`"
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Health Check"
    },
    {
      "name": "Organizations"
    },
    {
      "name": "Networks"
    },
    {
      "name": "Wallets"
    },
    {
      "name": "Registries"
    },
    {
      "name": "Identities"
    },
    {
      "name": "Credential Types"
    },
    {
      "name": "Credentials"
    },
    {
      "name": "Policy Engines"
    },
    {
      "name": "Extractors"
    },
    {
      "name": "Policy Implementations"
    },
    {
      "name": "Policies"
    },
    {
      "name": "Data Validators"
    },
    {
      "name": "Targets"
    },
    {
      "name": "Target Protections"
    }
  ],
  "x-constants": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "org_id": "org-123",
    "address": "0x1234567890123456789012345678901234567890",
    "chain_id": "42161",
    "timestamp": 1700000000,
    "chain_family_evm": "evm",
    "eth_sepolia_name": "Ethereum Sepolia",
    "eth_sepolia_chain_id": "11155111",
    "eth_sepolia_chain_selector": "16015286601757825753",
    "arbitrum_chain_selector": "4949039107694359620",
    "error_bad_request": {
      "error": "Bad request",
      "message": "Invalid request parameters"
    },
    "error_not_found": {
      "error": "Not found",
      "message": "Resource not found"
    },
    "error_conflict": {
      "error": "Already exists",
      "message": "Resource already exists"
    },
    "error_forbidden": {
      "error": "Forbidden",
      "message": "You do not have permission to access this resource"
    },
    "policy_config_schema_example": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "allowlist": {
          "type": "array",
          "description": "Ethereum addresses permitted to send transactions protected by this policy.",
          "items": {
            "type": "object",
            "properties": {
              "address": {
                "type": "string",
                "pattern": "^0x[a-fA-F0-9]{40}$",
                "description": "Ethereum address to allow."
              }
            },
            "required": ["address"]
          },
          "metadata": {
            "primary_key_fields": ["address"],
            "on_chain_operations": [
              {
                "type": "add",
                "function_abi": {
                  "name": "allowAddress",
                  "type": "function",
                  "stateMutability": "nonpayable",
                  "inputs": [
                    {
                      "name": "address",
                      "type": "address"
                    }
                  ],
                  "outputs": []
                }
              },
              {
                "type": "remove",
                "function_abi": {
                  "name": "disallowAddress",
                  "type": "function",
                  "stateMutability": "nonpayable",
                  "inputs": [
                    {
                      "name": "address",
                      "type": "address"
                    }
                  ],
                  "outputs": []
                }
              }
            ]
          }
        }
      },
      "policy_run_parameters": [
        {
          "name": "Account",
          "type": "address",
          "max": -1
        }
      ],
      "initial_configs": []
    }
  },
  "paths": {
    "/health-check": {
      "get": {
        "tags": ["Health Check"],
        "summary": "Health check endpoint",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthCheck"
                },
                "example": {
                  "status": "ok"
                }
              }
            }
          }
        }
      }
    },
    "/organizations/me": {
      "get": {
        "tags": ["Organizations"],
        "summary": "Returns the organization the caller belongs to.",
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserOrganization"
                },
                "example": {
                  "id": "org-123",
                  "crec_channel_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "crec_channel_offset": 0,
                  "signing_mode": "delegated",
                  "mainnet_allowed": false,
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          }
        }
      }
    },
    "/policy-engines": {
      "get": {
        "tags": ["Policy Engines"],
        "summary": "Lists all policy engines.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListPolicyEnginesResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "policy_engines": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Policy Engine A",
                      "description": "Description for Policy Engine A",
                      "type": "standard",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_policy_engines": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "address": "0x1234567890123456789012345678901234567890",
                          "chain_selector": "16015286601757825753",
                          "status": "created"
                        }
                      ],
                      "extractor_registrations": [],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Policy Engines"],
        "summary": "Creates a new policy engine.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePolicyEngineRequest"
              },
              "example": {
                "name": "Policy Engine A",
                "description": "Description for Policy Engine A",
                "extractor_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                "onchain_policy_engines": [
                  {
                    "chain_selector": "16015286601757825753"
                  },
                  {
                    "chain_selector": "4949039107694359620"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyEngine"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Engine A",
                  "description": "Description for Policy Engine A",
                  "type": "standard",
                  "chain_selectors": ["16015286601757825753", "4949039107694359620"],
                  "onchain_policy_engines": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "status": "created"
                    }
                  ],
                  "extractor_registrations": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "onchain_extractor_registrations": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "status": "active",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "409": {
            "description": "Policy engine already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/policy-engines/{policy_engine_id}": {
      "get": {
        "tags": ["Policy Engines"],
        "summary": "Gets a policy engine by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_engine_id",
            "description": "Policy engine ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyEngine"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Engine A",
                  "description": "Description for Policy Engine A",
                  "type": "standard",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_engines": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "status": "created"
                    }
                  ],
                  "extractor_registrations": [],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "404": {
            "description": "Policy engine not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Policy Engines"],
        "summary": "Updates a policy engine. The system policy engine (type \"system\") cannot be updated; it is reserved for registry protection.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_engine_id",
            "description": "Policy engine ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePolicyEngineRequest"
              },
              "example": {
                "name": "Policy Engine A Updated",
                "description": "Updated description for Policy Engine A",
                "extractor_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                "onchain_policy_engines": [
                  {
                    "chain_selector": "16015286601757825753"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyEngine"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Engine A Updated",
                  "description": "Updated description for Policy Engine A",
                  "type": "standard",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_engines": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "status": "created"
                    }
                  ],
                  "extractor_registrations": [],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy engine not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Policy Engines"],
        "summary": "Archives a policy engine. Rejected if already archived, if policy instances exist that are not archived, or if this is the system policy engine reserved for registry protection.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_engine_id",
            "description": "Policy engine ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchPolicyEngineRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns policy engine when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyEngine"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Engine A",
                  "description": "Description for Policy Engine A",
                  "type": "standard",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_engines": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "status": "created"
                    }
                  ],
                  "extractor_registrations": [],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived, or policy instances exist that are not archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy engine not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/extractors": {
      "get": {
        "tags": ["Extractors"],
        "summary": "Lists extractors.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "policy_engine_id",
            "description": "Policy engine ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "function_signature",
            "description": "Function signature",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExtractorsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "extractors": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Extractor A",
                      "org_id": "org-123",
                      "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                      "chain_selectors": ["16015286601757825753"],
                      "outputs": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "name": "account",
                          "type": "address",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        },
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "name": "amount",
                          "type": "uint256",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "onchain_extractors": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Extractors"],
        "summary": "Creates a new extractor.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExtractorRequest"
              },
              "example": {
                "name": "Extractor A",
                "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                "outputs": [
                  {
                    "name": "account",
                    "type": "address"
                  },
                  {
                    "name": "amount",
                    "type": "uint256"
                  }
                ],
                "onchain_extractors": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extractor"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Extractor A",
                  "org_id": "org-123",
                  "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                  "chain_selectors": ["16015286601757825753"],
                  "outputs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "account",
                      "type": "address",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    },
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "amount",
                      "type": "uint256",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "onchain_extractors": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          }
        }
      }
    },
    "/extractors/{extractor_id}": {
      "get": {
        "tags": ["Extractors"],
        "summary": "Gets an extractor by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "extractor_id",
            "description": "Extractor ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extractor"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Extractor A",
                  "org_id": "org-123",
                  "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                  "chain_selectors": ["16015286601757825753"],
                  "outputs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "account",
                      "type": "address",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "onchain_extractors": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "404": {
            "description": "Extractor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Extractors"],
        "summary": "Updates an extractor.",
        "parameters": [
          {
            "in": "path",
            "name": "extractor_id",
            "description": "Extractor ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateExtractorRequest"
              },
              "example": {
                "name": "Extractor A",
                "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                "outputs": [
                  {
                    "name": "account",
                    "type": "address"
                  },
                  {
                    "name": "amount",
                    "type": "uint256"
                  }
                ],
                "onchain_extractors": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extractor"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Extractor A",
                  "org_id": "org-123",
                  "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                  "chain_selectors": ["16015286601757825753"],
                  "outputs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "account",
                      "type": "address",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "onchain_extractors": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Extractor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Extractors"],
        "summary": "Archives an extractor. Rejected if already archived.",
        "parameters": [
          {
            "in": "path",
            "name": "extractor_id",
            "description": "Extractor ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchExtractorRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns extractor when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extractor"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Extractor A",
                  "org_id": "org-123",
                  "supported_function_signatures": ["mint(address,uint256)", "burn(address,uint256)"],
                  "chain_selectors": ["16015286601757825753"],
                  "outputs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "account",
                      "type": "address",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "onchain_extractors": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "extractor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Extractor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/policy-implementations": {
      "get": {
        "tags": ["Policy Implementations"],
        "summary": "Lists all policy implementations (onchain and offchain).",
        "description": "When `policy_kind` is omitted, returns onchain implementations only (backward compatible with existing clients). Use `policy_kind=all` to return both onchain and offchain implementations merged in a single list.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "policy_kind",
            "description": "Filter by policy kind. Omit or set to `onchain` for onchain-only (default). Set to `offchain` for offchain-only. Set to `all` for both kinds merged.\n",
            "schema": {
              "type": "string",
              "enum": ["onchain", "offchain", "all"]
            },
            "required": false
          },
          {
            "in": "query",
            "name": "name",
            "description": "Name",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListPolicyImplementationsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "implementations": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Policy Implementation A",
                      "description": "Description for Policy Implementation A",
                      "policy_config_schema": {
                        "$schema": "http://json-schema.org/draft-07/schema#",
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "allowlist": {
                            "type": "array",
                            "description": "Ethereum addresses permitted to send transactions protected by this policy.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "address": {
                                  "type": "string",
                                  "pattern": "^0x[a-fA-F0-9]{40}$",
                                  "description": "Ethereum address to allow."
                                }
                              },
                              "required": ["address"]
                            },
                            "metadata": {
                              "primary_key_fields": ["address"],
                              "on_chain_operations": [
                                {
                                  "type": "add",
                                  "function_abi": {
                                    "name": "allowAddress",
                                    "type": "function",
                                    "stateMutability": "nonpayable",
                                    "inputs": [
                                      {
                                        "name": "address",
                                        "type": "address"
                                      }
                                    ],
                                    "outputs": []
                                  }
                                },
                                {
                                  "type": "remove",
                                  "function_abi": {
                                    "name": "disallowAddress",
                                    "type": "function",
                                    "stateMutability": "nonpayable",
                                    "inputs": [
                                      {
                                        "name": "address",
                                        "type": "address"
                                      }
                                    ],
                                    "outputs": []
                                  }
                                }
                              ]
                            }
                          }
                        },
                        "policy_run_parameters": [
                          {
                            "name": "Account",
                            "type": "address",
                            "max": -1
                          }
                        ],
                        "initial_configs": []
                      },
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_policy_implementations": [
                        {
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890"
                        }
                      ],
                      "parameters": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "name": "Account",
                          "type": "address",
                          "position": 0,
                          "max": -1,
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Policy Implementations"],
        "summary": "Register a custom policy implementation.",
        "description": "Registers a new policy implementation by supplying its name, description, on-chain addresses, and a policy_config_schema that declares the policy's configurable parameters.\n\nThe policy_config_schema is a JSON Schema document (draft-07) extended with ACE-specific fields:\n- **properties** — one entry per configurable parameter (e.g. an allowlist or a threshold). Each entry requires type, description, and a metadata block.\n- **metadata.on_chain_operations** — maps each type of config change (add, remove, replace) to a Solidity setter function. Copy the function_abi from your contract's JSON ABI build artifact.\n- **policy_run_parameters** — transaction values extracted by the policy engine and passed to the contract's run() function at enforcement time. Use [] if none.\n- **initial_configs** — ordered list of parameter names that must be set at deploy time (matching the configure() argument order). Use [] if none.\n- **$schema**, **type**, **additionalProperties** — always the fixed values shown in the example below.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterPolicyImplementationRequest"
              },
              "example": {
                "name": "Allow Policy",
                "description": "Maintains an allowlist. Rejects the transaction if any checked address is not on the list.",
                "policy_config_schema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "allowlist": {
                      "type": "array",
                      "description": "Ethereum addresses permitted to send transactions protected by this policy.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "address": {
                            "type": "string",
                            "pattern": "^0x[a-fA-F0-9]{40}$",
                            "description": "Ethereum address to allow."
                          }
                        },
                        "required": ["address"]
                      },
                      "metadata": {
                        "display_hints": {
                          "network_behaviour": "apply_per_chain",
                          "title": "Allowed addresses"
                        },
                        "primary_key_fields": ["address"],
                        "on_chain_operations": [
                          {
                            "type": "add",
                            "function_abi": {
                              "name": "allowAddress",
                              "type": "function",
                              "stateMutability": "nonpayable",
                              "inputs": [
                                {
                                  "name": "address",
                                  "type": "address"
                                }
                              ],
                              "outputs": []
                            }
                          },
                          {
                            "type": "remove",
                            "function_abi": {
                              "name": "disallowAddress",
                              "type": "function",
                              "stateMutability": "nonpayable",
                              "inputs": [
                                {
                                  "name": "address",
                                  "type": "address"
                                }
                              ],
                              "outputs": []
                            }
                          }
                        ]
                      }
                    }
                  },
                  "policy_run_parameters": [
                    {
                      "name": "Account",
                      "type": "address",
                      "max": -1
                    }
                  ],
                  "initial_configs": []
                },
                "onchain_policy_implementations": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyImplementation"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Implementation A",
                  "description": "Description for Policy Implementation A",
                  "policy_config_schema": {
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "allowlist": {
                        "type": "array",
                        "description": "Ethereum addresses permitted to send transactions protected by this policy.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string",
                              "pattern": "^0x[a-fA-F0-9]{40}$",
                              "description": "Ethereum address to allow."
                            }
                          },
                          "required": ["address"]
                        },
                        "metadata": {
                          "primary_key_fields": ["address"],
                          "on_chain_operations": [
                            {
                              "type": "add",
                              "function_abi": {
                                "name": "allowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            },
                            {
                              "type": "remove",
                              "function_abi": {
                                "name": "disallowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            }
                          ]
                        }
                      }
                    },
                    "policy_run_parameters": [
                      {
                        "name": "Account",
                        "type": "address",
                        "max": -1
                      }
                    ],
                    "initial_configs": []
                  },
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_implementations": [
                    {
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890"
                    }
                  ],
                  "parameters": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Account",
                      "type": "address",
                      "position": 0,
                      "max": -1,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "409": {
            "description": "Policy implementation already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/policy-implementations/{policy_implementation_id}": {
      "get": {
        "tags": ["Policy Implementations"],
        "summary": "Gets a policy implementation by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_implementation_id",
            "description": "Policy implementation ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnyPolicyImplementationResponse"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Implementation A",
                  "description": "Description for Policy Implementation A",
                  "policy_config_schema": {
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "allowlist": {
                        "type": "array",
                        "description": "Ethereum addresses permitted to send transactions protected by this policy.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string",
                              "pattern": "^0x[a-fA-F0-9]{40}$",
                              "description": "Ethereum address to allow."
                            }
                          },
                          "required": ["address"]
                        },
                        "metadata": {
                          "primary_key_fields": ["address"],
                          "on_chain_operations": [
                            {
                              "type": "add",
                              "function_abi": {
                                "name": "allowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            },
                            {
                              "type": "remove",
                              "function_abi": {
                                "name": "disallowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            }
                          ]
                        }
                      }
                    },
                    "policy_run_parameters": [
                      {
                        "name": "Account",
                        "type": "address",
                        "max": -1
                      }
                    ],
                    "initial_configs": []
                  },
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_implementations": [
                    {
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890"
                    }
                  ],
                  "parameters": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Account",
                      "type": "address",
                      "position": 0,
                      "max": -1,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "404": {
            "description": "Policy implementation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Policy Implementations"],
        "summary": "Archives a policy implementation. Rejected if policy instances exist.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_implementation_id",
            "description": "Policy implementation ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchPolicyImplementationRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns policy implementation when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyImplementation"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Implementation A",
                  "description": "Description for Policy Implementation A",
                  "policy_config_schema": {
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "allowlist": {
                        "type": "array",
                        "description": "Ethereum addresses permitted to send transactions protected by this policy.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string",
                              "pattern": "^0x[a-fA-F0-9]{40}$",
                              "description": "Ethereum address to allow."
                            }
                          },
                          "required": ["address"]
                        },
                        "metadata": {
                          "primary_key_fields": ["address"],
                          "on_chain_operations": [
                            {
                              "type": "add",
                              "function_abi": {
                                "name": "allowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            },
                            {
                              "type": "remove",
                              "function_abi": {
                                "name": "disallowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            }
                          ]
                        }
                      }
                    },
                    "policy_run_parameters": [
                      {
                        "name": "Account",
                        "type": "address",
                        "max": -1
                      }
                    ],
                    "initial_configs": []
                  },
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_implementations": [
                    {
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890"
                    }
                  ],
                  "parameters": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Account",
                      "type": "address",
                      "position": 0,
                      "max": -1,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy implementation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Cannot archive - policy instances exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Policy Implementations"],
        "summary": "Update a policy implementation",
        "parameters": [
          {
            "in": "path",
            "name": "policy_implementation_id",
            "description": "Policy implementation ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePolicyImplementationRequest"
              },
              "example": {
                "name": "Policy Implementation A",
                "description": "Updated description for Policy Implementation A",
                "onchain_policy_implementations": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyImplementation"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy Implementation A",
                  "description": "Updated description for Policy Implementation A",
                  "policy_config_schema": {
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "allowlist": {
                        "type": "array",
                        "description": "Ethereum addresses permitted to send transactions protected by this policy.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string",
                              "pattern": "^0x[a-fA-F0-9]{40}$",
                              "description": "Ethereum address to allow."
                            }
                          },
                          "required": ["address"]
                        },
                        "metadata": {
                          "primary_key_fields": ["address"],
                          "on_chain_operations": [
                            {
                              "type": "add",
                              "function_abi": {
                                "name": "allowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            },
                            {
                              "type": "remove",
                              "function_abi": {
                                "name": "disallowAddress",
                                "type": "function",
                                "stateMutability": "nonpayable",
                                "inputs": [
                                  {
                                    "name": "address",
                                    "type": "address"
                                  }
                                ],
                                "outputs": []
                              }
                            }
                          ]
                        }
                      }
                    },
                    "policy_run_parameters": [
                      {
                        "name": "Account",
                        "type": "address",
                        "max": -1
                      }
                    ],
                    "initial_configs": []
                  },
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_policy_implementations": [
                    {
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890"
                    }
                  ],
                  "parameters": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Account",
                      "type": "address",
                      "position": 0,
                      "max": -1,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy implementation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/targets": {
      "get": {
        "tags": ["Targets"],
        "summary": "Lists all targets.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "policy_engine_id",
            "description": "Policy Engine ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search by target title or onchain address",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "chain_selector",
            "description": "Filter by chain selector",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "include_granted",
            "description": "When true, include targets owned by other orgs that granted evaluation access to the caller.",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListTargetsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "targets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "title": "Target A",
                      "description": "Description for Target A",
                      "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "protected_methods": ["transfer(address,uint256)", "transferFrom(address,address,uint256)"],
                      "desired_default_allow": true,
                      "metadata": {},
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_targets": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "default_allow": true
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Targets"],
        "summary": "Registers a new target. Cannot reference the system policy engine (type \"system\"); that engine is reserved for registry protection.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterTargetRequest"
              },
              "example": {
                "title": "Target A",
                "description": "Description for Target A",
                "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "protected_methods": ["transfer(address,uint256)", "transferFrom(address,address,uint256)"],
                "desired_default_allow": true,
                "metadata": {},
                "onchain_targets": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Target"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Target A",
                  "description": "Description for Target A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "protected_methods": ["transfer(address,uint256)", "transferFrom(address,address,uint256)"],
                  "desired_default_allow": true,
                  "metadata": {},
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_targets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "default_allow": true
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "409": {
            "description": "Target already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/targets/{target_id}": {
      "get": {
        "tags": ["Targets"],
        "summary": "Gets a target by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Target"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Target A",
                  "description": "Description for Target A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "protected_methods": ["transfer(address,uint256)", "transferFrom(address,address,uint256)"],
                  "desired_default_allow": true,
                  "metadata": {},
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_targets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "default_allow": true
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "404": {
            "description": "Target not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Targets"],
        "summary": "Updates a target. Rejected if the target uses the system policy engine (registry targets are managed internally).",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTargetRequest"
              },
              "example": {
                "title": "Target A Updated",
                "description": "Updated description for Target A",
                "protected_methods": [
                  "transfer(address,uint256)",
                  "transferFrom(address,address,uint256)",
                  "mint(address,uint256)"
                ],
                "desired_default_allow": true,
                "metadata": {},
                "onchain_targets": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Target"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Target A Updated",
                  "description": "Updated description for Target A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "protected_methods": [
                    "transfer(address,uint256)",
                    "transferFrom(address,address,uint256)",
                    "mint(address,uint256)"
                  ],
                  "desired_default_allow": true,
                  "metadata": {},
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_targets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "default_allow": true
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Target not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Targets"],
        "summary": "Archives a target. Rejected if policy target protections exist that are not archived, or if the target uses the system policy engine.",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchTargetRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns target when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Target"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Target A",
                  "description": "Description for Target A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "protected_methods": ["transfer(address,uint256)", "transferFrom(address,address,uint256)"],
                  "desired_default_allow": true,
                  "metadata": {},
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_targets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "default_allow": true
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Target not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Cannot archive - policy target protections exist that are not archived",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/targets/{target_id}/merge": {
      "post": {
        "tags": ["Targets"],
        "summary": "Merges source targets into this target by transferring their onchain targets and archiving the sources. The targets must belong to the same policy engine and must not have onchain targets on the same chain. The source targets will be archived after the merge.",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Destination Target ID (the target that will receive the onchain targets)",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergeTargetRequest"
              },
              "example": {
                "source_target_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Target"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Target A",
                  "description": "Description for Target A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "protected_methods": ["transfer(address,uint256)", "transferFrom(address,address,uint256)"],
                  "desired_default_allow": true,
                  "metadata": {},
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_targets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "default_allow": true
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. archived target, system engine, same target)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Source or destination target not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Cannot merge",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/targets/{target_id}/protections": {
      "get": {
        "tags": ["Target Protections"],
        "summary": "Lists all protections for a target.",
        "description": "Returns onchain target protections only. Offchain (CADV) protections created via POST /targets/{target_id}/protections with `policy_kind` `\"offchain\"` are managed under the offchain policy and are listed via GET /policies/{policy_id}/protections instead.\n",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          },
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "function_signature",
            "description": "Function signature",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "policy_instance_id",
            "description": "Policy instance ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "status",
            "description": "Onchain target protection status",
            "schema": {
              "$ref": "#/components/schemas/TargetProtectionStatus"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListTargetProtectionsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "target_protections": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "function_signature": "transfer(address,uint256)",
                      "function_selector": "0xa9059cbb",
                      "target_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "desired_position": 1,
                      "chain_selectors": ["16015286601757825753"],
                      "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                      "onchain_target_protections": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "position": 1,
                          "status": "created"
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Target Protections"],
        "summary": "Creates a new target protection (onchain or offchain). Rejected if the target uses the system policy engine (registry protections are managed internally).",
        "description": "Set `policy_instance_id` to the policy ID to protect. For onchain policies this is the onchain policy instance ID (`policy_kind` may be omitted). For offchain (CADV) policies this is the offchain policy ID and `policy_kind` must be `\"offchain\"`. Onchain protections return 200; offchain protection attachment is queued and returns 202.\n",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTargetProtectionRequest"
              },
              "examples": {
                "onchain": {
                  "summary": "Onchain policy protection",
                  "value": {
                    "function_signature": "transfer(address,uint256)",
                    "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "desired_position": 1,
                    "onchain_target_protections": [
                      {
                        "chain_selector": "16015286601757825753"
                      }
                    ],
                    "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"]
                  }
                },
                "offchain": {
                  "summary": "Offchain (CADV) policy protection",
                  "value": {
                    "function_signature": "transfer(address,uint256)",
                    "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "policy_kind": "offchain",
                    "desired_position": 0,
                    "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Onchain protection created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetProtection"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "function_signature": "transfer(address,uint256)",
                  "function_selector": "0xa9059cbb",
                  "target_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "desired_position": 1,
                  "chain_selectors": ["16015286601757825753"],
                  "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                  "onchain_target_protections": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "position": 1,
                      "status": "created"
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "202": {
            "description": "Offchain protection attachment accepted (async)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OffchainPolicyProtectionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Target or policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - target protection with same policy, target, and function selector already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/targets/{target_id}/protections/{protection_id}": {
      "get": {
        "tags": ["Target Protections"],
        "summary": "Gets a specific protection on a target.",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "protection_id",
            "description": "Protection ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetProtection"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "function_signature": "transfer(address,uint256)",
                  "function_selector": "0xa9059cbb",
                  "target_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "desired_position": 1,
                  "chain_selectors": ["16015286601757825753"],
                  "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                  "onchain_target_protections": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "position": 1,
                      "status": "created"
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "404": {
            "description": "Target or protection not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Target Protections"],
        "summary": "Updates a target protection. Rejected if the target uses the system policy engine.",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "protection_id",
            "description": "Protection ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTargetProtectionRequest"
              },
              "example": {
                "onchain_target_protections": [
                  {
                    "chain_selector": "16015286601757825753"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetProtection"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "function_signature": "transfer(address,uint256)",
                  "function_selector": "0xa9059cbb",
                  "target_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "desired_position": 1,
                  "chain_selectors": ["16015286601757825753"],
                  "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                  "onchain_target_protections": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "position": 1,
                      "status": "created"
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. target protection already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Target or protection not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Target Protections"],
        "summary": "Archives a target protection.",
        "description": "Pass status=archived to archive. Only archives when all onchain target protections\nhave been removed from chain. If onchain protections still exist, triggers removal\nand archives when all are removed (async).\nRejected if the target uses the system policy engine (registry protections are managed internally).\n",
        "parameters": [
          {
            "in": "path",
            "name": "target_id",
            "description": "Target ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "protection_id",
            "description": "Protection ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchTargetProtectionRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns archived target protection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetProtection"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "function_signature": "transfer(address,uint256)",
                  "function_selector": "0xa9059cbb",
                  "target_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "policy_instance_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "desired_position": 1,
                  "chain_selectors": ["16015286601757825753"],
                  "extractor_output_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
                  "onchain_target_protections": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "position": 1,
                      "status": "created"
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. status must be archived, already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Target or protection not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/policies": {
      "get": {
        "tags": ["Policies"],
        "summary": "Lists all policies (onchain and offchain).",
        "description": "When `policy_kind` is omitted, returns onchain policies only with standard DB pagination (backward compatible with existing clients). Use `policy_kind=all` to return both onchain and offchain policies merged in a single list. Onchain-only query filters (e.g. `target_id`, `policy_engine_id`) exclude offchain policies from merged results.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "policy_kind",
            "description": "Filter by policy kind. Omit or set to `onchain` for onchain-only (default). Set to `offchain` for offchain-only. Set to `all` for both kinds merged.\n",
            "schema": {
              "type": "string",
              "enum": ["onchain", "offchain", "all"]
            },
            "required": false
          },
          {
            "in": "query",
            "name": "target_id",
            "description": "Filter by target ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filter by policy status",
            "schema": {
              "$ref": "#/components/schemas/OnchainPolicyInstanceStatus"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "name",
            "description": "Name",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "only_with_active_protections",
            "description": "Only return policies with active protections",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "required": false
          },
          {
            "in": "query",
            "name": "target_address",
            "description": "Filter by target contract address",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "policy_engine_id",
            "description": "Policy engine ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "policy_implementation_id",
            "description": "Filter by policy implementation ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListPoliciesResponse"
                },
                "example": {
                  "total": 2,
                  "total_pages": 1,
                  "page": 1,
                  "policies": [
                    {
                      "policy_kind": "onchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Policy A",
                      "description": "Description for Policy A",
                      "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "policy_implementation_name": "Policy Implementation A",
                      "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_configs": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selectors": ["16015286601757825753"],
                          "config_json": {
                            "allowList": ["0x1234567890123456789012345678901234567890"]
                          }
                        }
                      ],
                      "onchain_policies": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "policy_config_version": "1",
                          "out_of_sync": false,
                          "status": "created"
                        }
                      ],
                      "ongoing_config_changes": [],
                      "archived_at": null
                    },
                    {
                      "policy_kind": "offchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "type": "wallet_risk_scoring",
                      "name": "Transaction wallet screening",
                      "config": {
                        "secret_name": "trmApiKey",
                        "addresses_to_check": "ALL",
                        "fail_mode": "CLOSED",
                        "risk_threshold": "HIGH",
                        "block_unknown": false,
                        "category_filters": [{ "category": "Sanctions", "threshold": "LOW" }]
                      },
                      "chain_selectors": ["16015286601757825753"],
                      "deployment_status": "active",
                      "created_at": "2024-01-01T00:00:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Policies"],
        "summary": "Creates a new policy (onchain or offchain). Use `policy_kind` to select the type. Policies cannot attach to the system policy engine (type \"system\"); that engine is reserved for registry protection.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAnyPolicyRequest"
              },
              "examples": {
                "onchain": {
                  "summary": "Create an onchain policy",
                  "value": {
                    "policy_kind": "onchain",
                    "name": "Policy A",
                    "description": "Description for Policy A",
                    "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "onchain_policies": [
                      {
                        "chain_selector": "16015286601757825753",
                        "initial_config": {
                          "allowList": ["0x1234567890123456789012345678901234567890"]
                        }
                      }
                    ]
                  }
                },
                "offchain": {
                  "summary": "Create an offchain policy",
                  "value": {
                    "policy_kind": "offchain",
                    "type": "wallet_risk_scoring",
                    "name": "Transaction wallet screening",
                    "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "onchain_policies": [
                      {
                        "chain_selector": "16015286601757825753"
                      }
                    ],
                    "config": {
                      "secret_name": "trmApiKey",
                      "addresses_to_check": "ALL",
                      "fail_mode": "CLOSED",
                      "risk_threshold": "HIGH",
                      "block_unknown": false,
                      "category_filters": [{ "category": "Sanctions", "threshold": "LOW" }]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnyPolicyResponse"
                },
                "examples": {
                  "onchain": {
                    "summary": "Onchain policy created",
                    "value": {
                      "policy_kind": "onchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Policy A",
                      "description": "Description for Policy A",
                      "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_configs": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selectors": ["16015286601757825753"],
                          "config_json": {
                            "allowList": ["0x1234567890123456789012345678901234567890"]
                          }
                        }
                      ],
                      "onchain_policies": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "policy_config_version": "1",
                          "out_of_sync": false,
                          "status": "created"
                        }
                      ],
                      "ongoing_config_changes": [],
                      "archived_at": null
                    }
                  },
                  "offchain": {
                    "summary": "Offchain policy created",
                    "value": {
                      "policy_kind": "offchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "type": "wallet_risk_scoring",
                      "name": "Transaction wallet screening",
                      "config": {
                        "secret_name": "trmApiKey",
                        "addresses_to_check": "ALL",
                        "fail_mode": "CLOSED",
                        "risk_threshold": "HIGH",
                        "block_unknown": false,
                        "category_filters": [{ "category": "Sanctions", "threshold": "LOW" }]
                      },
                      "action_validators": [
                        {
                          "chain_selector": "16015286601757825753",
                          "validator_address": ""
                        }
                      ],
                      "deployment_status": "pending",
                      "created_at": "2024-01-01T00:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy implementation or policy engine not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Conflict (e.g. active offchain policy already exists for this org)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}": {
      "get": {
        "tags": ["Policies"],
        "summary": "Gets a policy by ID (onchain or offchain).",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "description": "Policy ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnyPolicyResponse"
                },
                "examples": {
                  "onchain": {
                    "summary": "Onchain policy",
                    "value": {
                      "policy_kind": "onchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Policy A",
                      "description": "Description for Policy A",
                      "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_configs": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selectors": ["16015286601757825753"],
                          "config_json": {
                            "allowList": ["0x1234567890123456789012345678901234567890"]
                          }
                        }
                      ],
                      "onchain_policies": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "policy_config_version": "1",
                          "out_of_sync": false,
                          "status": "created"
                        }
                      ],
                      "ongoing_config_changes": [],
                      "archived_at": null
                    }
                  },
                  "offchain": {
                    "summary": "Offchain policy",
                    "value": {
                      "policy_kind": "offchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "type": "wallet_risk_scoring",
                      "name": "Transaction wallet screening",
                      "config": {
                        "secret_name": "trmApiKey",
                        "addresses_to_check": "ALL",
                        "fail_mode": "CLOSED",
                        "risk_threshold": "HIGH",
                        "block_unknown": false,
                        "category_filters": [{ "category": "Sanctions", "threshold": "LOW" }]
                      },
                      "chain_selectors": ["16015286601757825753"],
                      "deployment_status": "active",
                      "created_at": "2024-01-01T00:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Policies"],
        "summary": "Updates a policy. Rejected if the policy is on the system policy engine reserved for registry protection.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "description": "Policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePolicyRequest"
              },
              "example": {
                "name": "Policy A Updated",
                "description": "Updated description for Policy A",
                "onchain_policies": [
                  {
                    "chain_selector": "16015286601757825753"
                  },
                  {
                    "chain_selector": "4949039107694359620"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy A Updated",
                  "description": "Updated description for Policy A",
                  "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "policy_implementation_name": "Policy Implementation A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753", "4949039107694359620"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {
                        "allowList": ["0x1234567890123456789012345678901234567890"]
                      }
                    }
                  ],
                  "onchain_policies": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "policy_config_version": "1",
                      "out_of_sync": false,
                      "status": "created"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": null
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. policy already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Policies"],
        "summary": "Archives a policy (onchain or offchain). For onchain policies, rejected if target protections exist that are not archived or if the policy is on the system policy engine. For offchain policies, triggers workflow undeployment.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "description": "Policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchPolicyRequest"
              },
              "examples": {
                "onchain": {
                  "summary": "Archive an onchain policy",
                  "value": {
                    "status": "archived"
                  }
                },
                "offchain": {
                  "summary": "Archive an offchain policy (triggers workflow undeployment)",
                  "value": {
                    "status": "archived",
                    "policy_kind": "offchain"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns the archived policy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnyPolicyResponse"
                },
                "examples": {
                  "onchain": {
                    "value": {
                      "policy_kind": "onchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Policy A",
                      "description": "Description for Policy A",
                      "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_configs": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selectors": ["16015286601757825753"],
                          "config_json": {
                            "allowList": ["0x1234567890123456789012345678901234567890"]
                          }
                        }
                      ],
                      "onchain_policies": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "policy_config_version": "1",
                          "out_of_sync": false,
                          "status": "created"
                        }
                      ],
                      "ongoing_config_changes": [],
                      "archived_at": 1700000000
                    }
                  },
                  "offchain": {
                    "value": {
                      "policy_kind": "offchain",
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Transaction wallet screening",
                      "type": "wallet_risk_scoring",
                      "action_validators": [
                        {
                          "chain_selector": "16015286601757825753",
                          "validator_address": "0x1234567890123456789012345678901234567890"
                        }
                      ],
                      "deployment_status": "removing",
                      "created_at": 1700000000
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Cannot archive - target protections exist that are not archived",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/protections": {
      "get": {
        "tags": ["Policies"],
        "summary": "List target protections for an offchain policy.",
        "description": "Returns protections attached to the given offchain policy. Only applicable to offchain policies; onchain policy protections are listed via GET /targets/{target_id}/protections.\n",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "description": "Offchain policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListOffchainPolicyProtectionsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Offchain policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/protections/{protection_id}": {
      "get": {
        "tags": ["Policies"],
        "summary": "Get a specific offchain policy protection.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "in": "path",
            "name": "protection_id",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OffchainPolicyProtectionResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Policies"],
        "summary": "Remove an offchain policy protection (detaches validator from function on engine).",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "in": "path",
            "name": "protection_id",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Protection removal accepted"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/config": {
      "put": {
        "tags": ["Policies"],
        "summary": "Update the config of an offchain policy. Config is immutable once deployed; calling this endpoint triggers redeployment of the workflow with the new config (CRE upserts by owner + name). The policy's deployment_status transitions to config_updating while the operation is in progress, then back to active on success.\n",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "description": "Offchain policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOffchainPolicyConfigRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Config update accepted; redeployment queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnyPolicyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request (invalid config or policy not in updatable state)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/targets/{target_id}/access-grants": {
      "get": {
        "tags": ["Policies"],
        "summary": "List evaluation access grants for an offchain policy and target pair.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "description": "Offchain policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListRegistryAccessGrantsResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Policies"],
        "summary": "Grant another organization evaluation access for an offchain policy on a target.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "description": "Offchain policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRegistryAccessGrantRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Grant created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistryAccessGrant"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Active grant already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/targets/{target_id}/access-grants/{grantee_org_id}": {
      "patch": {
        "tags": ["Policies"],
        "summary": "Revoke evaluation access for a grantee organization.",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "required": true,
            "description": "Offchain policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "name": "grantee_org_id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/OrgId"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchRegistryAccessGrantRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Grant revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistryAccessGrant"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/onchain/{onchain_policy_id}": {
      "put": {
        "tags": ["Policies"],
        "summary": "Updates states of an onchain policy.",
        "description": "This endpoint triggers a re-sync of the onchain policy state. The request body is empty.\n",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "description": "Policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "onchain_policy_id",
            "description": "Onchain policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOnchainPolicyRequest"
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnchainPolicyInstance"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selector": "16015286601757825753",
                  "address": "0x1234567890123456789012345678901234567890",
                  "policy_config_version": "1",
                  "out_of_sync": false,
                  "status": "created"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy or onchain policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/policies/{policy_id}/configs": {
      "patch": {
        "tags": ["Policies"],
        "summary": "Updates policy configurations with JSON patches.",
        "description": "Applies [JSON Patch (RFC 6902)](https://jsonpatch.com/) operations\nto the policy's configuration.\n",
        "parameters": [
          {
            "in": "path",
            "name": "policy_id",
            "description": "Policy ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchPolicyConfigsRequest"
              },
              "example": {
                "patches": [
                  {
                    "op": "add",
                    "path": "/allowList/-",
                    "value": "0x1234567890123456789012345678901234567890"
                  },
                  {
                    "op": "remove",
                    "path": "/allowList/0"
                  }
                ],
                "apply_onchain_policies": [
                  {
                    "chain_selector": "16015286601757825753",
                    "current_policy_config_version": "1"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Policy A",
                  "description": "Description for Policy A",
                  "policy_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "policy_implementation_name": "Policy Implementation A",
                  "policy_engine_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {
                        "allowList": ["0x1234567890123456789012345678901234567890"]
                      }
                    }
                  ],
                  "onchain_policies": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "policy_config_version": "2",
                      "out_of_sync": false,
                      "status": "created"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": null
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Policy not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/data-validators": {
      "get": {
        "tags": ["Data Validators"],
        "summary": "Lists all data validator instances.",
        "description": "Optional filters combine with AND semantics. Use `chain_selector` and/or `address` to narrow\nlist to instances that have a matching on-chain deployment row.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filters instances that have an on-chain deployment in this status",
            "schema": {
              "$ref": "#/components/schemas/OnchainDataValidatorInstanceStatus"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "name",
            "description": "Name (case-insensitive substring)",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "data_validator_implementation_id",
            "description": "Data validator implementation ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "chain_selector",
            "description": "When set, only instances that have an on-chain deployment on this CCIP chain selector are returned",
            "schema": {
              "$ref": "#/components/schemas/ChainSelector"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "address",
            "description": "When set, only instances that have an on-chain deployment at this contract address are returned (case-insensitive match)",
            "schema": {
              "$ref": "#/components/schemas/EthAddress"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListDataValidatorsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "data_validators": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Data Validator A",
                      "description": "Description",
                      "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_configs": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selectors": ["16015286601757825753"],
                          "config_json": {}
                        }
                      ],
                      "onchain_data_validators": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "data_validator_config_version": "0",
                          "status": "created"
                        }
                      ],
                      "ongoing_config_changes": [],
                      "archived_at": null
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Data Validators"],
        "summary": "Creates a new data validator instance.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDataValidatorRequest"
              },
              "example": {
                "name": "Data Validator A",
                "description": "Description",
                "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "onchain_data_validators": [
                  {
                    "chain_selector": "16015286601757825753",
                    "initial_config": {}
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataValidator"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Data Validator A",
                  "description": "Description",
                  "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {}
                    }
                  ],
                  "onchain_data_validators": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "data_validator_config_version": "0",
                      "status": "creation_pending"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": null
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Data validator implementation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/data-validators/{data_validator_id}": {
      "get": {
        "tags": ["Data Validators"],
        "summary": "Gets a data validator instance by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "data_validator_id",
            "required": true,
            "description": "Data validator instance ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataValidator"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Data Validator A",
                  "description": "Description",
                  "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {}
                    }
                  ],
                  "onchain_data_validators": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "data_validator_config_version": "0",
                      "status": "created"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": null
                }
              }
            }
          },
          "404": {
            "description": "Data validator instance not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Data Validators"],
        "summary": "Updates a data validator instance.",
        "parameters": [
          {
            "in": "path",
            "name": "data_validator_id",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDataValidatorRequest"
              },
              "example": {
                "name": "Data Validator A Updated",
                "description": "Updated description",
                "onchain_data_validators": [
                  {
                    "chain_selector": "16015286601757825753",
                    "initial_config": {}
                  },
                  {
                    "chain_selector": "4949039107694359620",
                    "initial_config": {}
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataValidator"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Data Validator A Updated",
                  "description": "Updated description",
                  "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753", "4949039107694359620"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {}
                    }
                  ],
                  "onchain_data_validators": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "data_validator_config_version": "0",
                      "status": "created"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": null
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Data validator instance not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Data Validators"],
        "summary": "Archives a data validator instance.",
        "parameters": [
          {
            "in": "path",
            "name": "data_validator_id",
            "required": true,
            "description": "Data validator instance ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchDataValidatorRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns the instance when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataValidator"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Data Validator A",
                  "description": "Description",
                  "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {}
                    }
                  ],
                  "onchain_data_validators": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "data_validator_config_version": "0",
                      "status": "created"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Data validator instance not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Cannot archive while on-chain deployment is being created or configuration change is in flight",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/data-validators/{data_validator_id}/configs": {
      "patch": {
        "tags": ["Data Validators"],
        "summary": "Updates data validator configuration using JSON Patch.",
        "description": "Applies [JSON Patch (RFC 6902)](https://jsonpatch.com/) operations to the instance configuration.\nUse `on_chains` to select deployments and supply `current_config_version` per chain (optimistic concurrency).\n",
        "parameters": [
          {
            "in": "path",
            "name": "data_validator_id",
            "description": "Data validator instance ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchDataValidatorConfigsRequest"
              },
              "example": {
                "patches": [
                  {
                    "op": "add",
                    "path": "/someKey/-",
                    "value": "example"
                  }
                ],
                "on_chains": [
                  {
                    "chain_selector": "16015286601757825753",
                    "current_config_version": "0"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataValidator"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Data Validator A",
                  "description": "Description",
                  "data_validator_implementation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_configs": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "config_json": {}
                    }
                  ],
                  "onchain_data_validators": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "data_validator_config_version": "1",
                      "status": "created"
                    }
                  ],
                  "ongoing_config_changes": [],
                  "archived_at": null
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Data validator instance not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Configuration change rejected (version mismatch, instance not created, or ongoing change in flight)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/registries": {
      "get": {
        "tags": ["Registries"],
        "summary": "Lists all registries.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Type of registry. Can be \"pair\", \"identity\", or \"credential\". Defaults to \"pair\".",
            "schema": {
              "type": "string",
              "enum": ["pair", "identity", "credential"],
              "default": "pair"
            }
          },
          {
            "in": "query",
            "name": "include_granted",
            "required": false,
            "description": "When true, includes registries that other orgs have granted access to the caller, in addition to owned registries. Each registry in the response will have an access_type field (\"owned\" or \"granted\").",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListRegistriesResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Registry A",
                      "description": "Description for Registry A",
                      "org_id": "org-123",
                      "mode": "managed",
                      "chain_selectors": ["16015286601757825753"],
                      "identity_registries": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "name": "Identity Registry on Chain A",
                          "description": "Description for identity registry on Chain A",
                          "address": "0x1234567890123456789012345678901234567890",
                          "chain_selector": "16015286601757825753",
                          "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "org_id": "org-123",
                          "status": "created",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "credential_registries": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "name": "Credential Registry on Chain A",
                          "description": "Description for credential registry on Chain A",
                          "address": "0x1234567890123456789012345678901234567890",
                          "chain_selector": "16015286601757825753",
                          "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "org_id": "org-123",
                          "status": "created",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Registries"],
        "summary": "Creates a new registry with identity and credential registries.",
        "description": "The address field is optional. If omitted, the registry will be deployed on-chain,\nits status will be \"creation_pending\" until created, and the mode will be `managed`. The possible modes are `managed` - when no address is provided - and `read_only` - when an address is passed - this mode does not allow any write changes to the registry like adding identities or credentials.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRegistryRequest"
              },
              "example": {
                "name": "Registry A",
                "description": "Description for Registry A",
                "identity_registries": [
                  {
                    "name": "Identity Registry on Chain A",
                    "description": "Description for identity registry on Chain A",
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ],
                "credential_registries": [
                  {
                    "name": "Credential Registry on Chain A",
                    "description": "Description for credential registry on Chain A",
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Registry"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Registry A",
                  "description": "Description for Registry A",
                  "org_id": "org-123",
                  "mode": "managed",
                  "chain_selectors": ["16015286601757825753"],
                  "identity_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Identity Registry on Chain A",
                      "description": "Description for identity registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "credential_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Credential Registry on Chain A",
                      "description": "Description for credential registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "409": {
            "description": "Registry already exists or conflict with existing registries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/registries/{registry_id}": {
      "get": {
        "tags": ["Registries"],
        "summary": "Gets a registry by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "registry_id",
            "required": true,
            "description": "Registry ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Type of registry. Can be \"pair\", \"identity\", or \"credential\". Defaults to \"pair\".",
            "schema": {
              "type": "string",
              "enum": ["pair", "identity", "credential"],
              "default": "pair"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Registry"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Registry A",
                  "description": "Description for Registry A",
                  "org_id": "org-123",
                  "mode": "managed",
                  "chain_selectors": ["16015286601757825753"],
                  "identity_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Identity Registry on Chain A",
                      "description": "Description for identity registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "credential_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Credential Registry on Chain A",
                      "description": "Description for credential registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller does not own this registry and has no active access grant (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Registries"],
        "summary": "Updates a registry with identity and credential registries.",
        "parameters": [
          {
            "in": "path",
            "name": "registry_id",
            "required": true,
            "description": "Registry ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRegistryRequest"
              },
              "example": {
                "name": "Registry A",
                "description": "Description for Registry A",
                "identity_registries": [
                  {
                    "name": "Identity Registry on Chain A",
                    "description": "Description for identity registry on Chain A",
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  },
                  {
                    "name": "Identity Registry on Chain B",
                    "description": "Description for identity registry on Chain B",
                    "chain_selector": "4949039107694359620",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ],
                "credential_registries": [
                  {
                    "name": "Credential Registry on Chain A",
                    "description": "Description for credential registry on Chain A",
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  },
                  {
                    "name": "Credential Registry on Chain B",
                    "description": "Description for credential registry on Chain B",
                    "chain_selector": "4949039107694359620",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Registry"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Registry A",
                  "description": "Description for Registry A",
                  "org_id": "org-123",
                  "mode": "managed",
                  "chain_selectors": ["16015286601757825753", "4949039107694359620"],
                  "identity_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Identity Registry on Chain A",
                      "description": "Description for identity registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    },
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Identity Registry on Chain B",
                      "description": "Description for identity registry on Chain B",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "4949039107694359620",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "credential_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Credential Registry on Chain A",
                      "description": "Description for credential registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    },
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Credential Registry on Chain B",
                      "description": "Description for credential registry on Chain B",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "4949039107694359620",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. registry already archived, cannot remove registry pairs - only adding new pairs is allowed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Registry not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Conflict with existing registries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Registries"],
        "summary": "Archives a registry. Rejected if identities exist.",
        "parameters": [
          {
            "in": "path",
            "name": "registry_id",
            "required": true,
            "description": "Registry ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchRegistryRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns registry when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Registry"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Registry A",
                  "description": "Description for Registry A",
                  "org_id": "org-123",
                  "mode": "managed",
                  "chain_selectors": ["16015286601757825753"],
                  "identity_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Identity Registry on Chain A",
                      "description": "Description for identity registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "credential_registries": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Credential Registry on Chain A",
                      "description": "Description for credential registry on Chain A",
                      "address": "0x1234567890123456789012345678901234567890",
                      "chain_selector": "16015286601757825753",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. already archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Registry not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Cannot archive - identities exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/registries/{registry_id}/access-grants": {
      "get": {
        "tags": ["Registries"],
        "summary": "Lists all access grants for a registry. Requires registry ownership.",
        "parameters": [
          {
            "in": "path",
            "name": "registry_id",
            "required": true,
            "description": "Registry ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListRegistryAccessGrantsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "access_grants": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "grantee_org_id": "org-456",
                      "grantor_org_id": "org-123",
                      "status": "active",
                      "granted_at": 1700000000,
                      "revoked_at": null
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Caller does not own the registry (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Registries"],
        "summary": "Grants registry access to another organization. Requires registry ownership.",
        "parameters": [
          {
            "in": "path",
            "name": "registry_id",
            "required": true,
            "description": "Registry ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRegistryAccessGrantRequest"
              },
              "example": {
                "grantee_org_id": "org-456"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Access grant created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistryAccessGrant"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "grantee_org_id": "org-456",
                  "grantor_org_id": "org-123",
                  "status": "active",
                  "granted_at": 1700000000,
                  "revoked_at": null
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. grantee_org_id missing or invalid)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not own the registry (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          },
          "409": {
            "description": "An active grant for this grantee already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/registries/{registry_id}/access-grants/{grantee_org_id}": {
      "patch": {
        "tags": ["Registries"],
        "summary": "Revokes registry access for a grantee organization. Requires registry ownership.",
        "parameters": [
          {
            "in": "path",
            "name": "registry_id",
            "required": true,
            "description": "Registry ID",
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "in": "path",
            "name": "grantee_org_id",
            "required": true,
            "description": "Grantee organization ID",
            "schema": {
              "$ref": "#/components/schemas/OrgId"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchRegistryAccessGrantRequest"
              },
              "example": {
                "status": "revoked"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Access grant updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistryAccessGrant"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "grantee_org_id": "org-456",
                  "grantor_org_id": "org-123",
                  "status": "revoked",
                  "granted_at": 1700000000,
                  "revoked_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. status value not accepted)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not own the registry (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          },
          "404": {
            "description": "No active access grant exists for the grantee (caller owns the registry)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/identities": {
      "get": {
        "tags": ["Identities"],
        "summary": "Lists all identities.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "query",
            "description": "Title of the identity, can be a substring",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "registry_id",
            "description": "Filter by registry ID",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListIdentitiesResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "identities": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "title": "Identity A",
                      "description": "Description for Identity A",
                      "entity_id": "1234567890",
                      "ccid": "0x1234567890123456789012345678901234567890",
                      "registryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_identities": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "address": "0x1234567890123456789012345678901234567890",
                          "status": "created",
                          "created_at": 1700000000,
                          "updated_at": 1700000000
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller has no read access to registry_id (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Identities"],
        "summary": "Creates a new identity.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateIdentityRequest"
              },
              "example": {
                "title": "Identity A",
                "description": "Description for Identity A",
                "entity_id": "1234567890",
                "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "onchain_identities": [
                  {
                    "address": "0x1234567890123456789012345678901234567890",
                    "chain_selector": "16015286601757825753"
                  }
                ],
                "credentials": [
                  {
                    "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "external_unique_id": "ext-123",
                    "expires_at": 1800000000
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Identity"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Identity A",
                  "description": "Description for Identity A",
                  "entity_id": "1234567890",
                  "ccid": "0x1234567890123456789012345678901234567890",
                  "registryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_identities": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          }
        }
      }
    },
    "/identities/batch": {
      "post": {
        "tags": ["Identities"],
        "summary": "Creates multiple identities in a batch operation.",
        "description": "Creates multiple identities at once. If any identity fails validation or creation, the entire batch fails.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateIdentitiesBatchRequest"
              },
              "example": {
                "identities": [
                  {
                    "title": "Identity A",
                    "description": "Description for Identity A",
                    "entity_id": "1234567890",
                    "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "onchain_identities": [
                      {
                        "address": "0x1234567890123456789012345678901234567890",
                        "chain_selector": "16015286601757825753"
                      }
                    ]
                  },
                  {
                    "title": "Identity B",
                    "description": "Description for Identity B",
                    "entity_id": "0987654321",
                    "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "onchain_identities": [
                      {
                        "address": "0x1234567890123456789012345678901234567890",
                        "chain_selector": "16015286601757825753"
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateIdentitiesBatchResponse"
                },
                "example": {
                  "results": [
                    {
                      "status": "created",
                      "identity": {
                        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                        "title": "Identity A",
                        "description": "Description for Identity A",
                        "entity_id": "1234567890",
                        "ccid": "0x1234567890123456789012345678901234567890",
                        "registryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                        "chain_selectors": ["16015286601757825753"],
                        "onchain_identities": [
                          {
                            "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                            "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                            "chain_selector": "16015286601757825753",
                            "address": "0x1234567890123456789012345678901234567890",
                            "status": "created",
                            "created_at": 1700000000,
                            "updated_at": 1700000000
                          }
                        ],
                        "archived_at": null,
                        "created_at": 1700000000,
                        "updated_at": 1700000000
                      }
                    },
                    {
                      "status": "failed",
                      "error": "Identity already exists"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request - validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - one or more identities already exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/identities/{identity_id}": {
      "get": {
        "tags": ["Identities"],
        "summary": "Gets an identity by identity ID.",
        "parameters": [
          {
            "in": "path",
            "name": "identity_id",
            "description": "Identity ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Identity"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Identity A",
                  "description": "Description for Identity A",
                  "entity_id": "1234567890",
                  "ccid": "0x1234567890123456789012345678901234567890",
                  "registryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_identities": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller has no read access to the identity's registry (including when the identity id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Identities"],
        "summary": "Update or archive an identity.",
        "description": "Pass status=archived to archive, OR title/description/onchain_identities to update.\nMutually exclusive - if status is passed, update fields must not be passed (400).\nIf identity is already archived and status is passed, returns 400.\nIf identity is archived and update fields are passed, returns 400.\n",
        "parameters": [
          {
            "in": "path",
            "name": "identity_id",
            "description": "Identity ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchIdentityRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns identity when update fields are used; identity when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Identity"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Identity A",
                  "description": "Description for Identity A",
                  "entity_id": "1234567890",
                  "ccid": "0x1234567890123456789012345678901234567890",
                  "registryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_identities": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Identity not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Identities"],
        "summary": "Updates an identity.",
        "description": "Returns 400 if identity is archived.",
        "parameters": [
          {
            "in": "path",
            "name": "identity_id",
            "description": "Identity ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateIdentityRequest"
              },
              "example": {
                "title": "Identity A Updated",
                "description": "Updated description for Identity A",
                "onchain_identities": [
                  {
                    "chain_selector": "16015286601757825753",
                    "address": "0x1234567890123456789012345678901234567890"
                  },
                  {
                    "chain_selector": "4949039107694359620",
                    "address": "0x1234567890123456789012345678901234567890"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Identity"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Identity A Updated",
                  "description": "Updated description for Identity A",
                  "entity_id": "1234567890",
                  "ccid": "0x1234567890123456789012345678901234567890",
                  "registryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753", "4949039107694359620"],
                  "onchain_identities": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "address": "0x1234567890123456789012345678901234567890",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. identity is archived)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Identity not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/credential-types": {
      "get": {
        "tags": ["Credential Types"],
        "summary": "Lists all credential types.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "in": "query",
            "name": "registry_id",
            "description": "Registry ID",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCredentialTypesResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "credential_types": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "title": "Credential Type A",
                      "description": "Description for Credential Type A",
                      "credential_type": "common.KYC",
                      "credential_type_hash": "0x1234567890123456789012345678901234567890",
                      "chain_selectors": ["16015286601757825753"],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller has no read access to registry_id (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Credential Types"],
        "summary": "Register a credential type.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterCredentialTypeRequest"
              },
              "example": {
                "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "title": "Credential Type A",
                "description": "Description for Credential Type A",
                "credential_type": "common.KYC"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialType"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Credential Type A",
                  "description": "Description for Credential Type A",
                  "credential_type": "common.KYC",
                  "credential_type_hash": "0x1234567890123456789012345678901234567890",
                  "chain_selectors": ["16015286601757825753"],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "409": {
            "description": "Credential type already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/credential-types/{credential_type_id}": {
      "get": {
        "tags": ["Credential Types"],
        "summary": "Gets a credential type by its ID.",
        "parameters": [
          {
            "in": "path",
            "name": "credential_type_id",
            "description": "Credential Type ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialType"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Credential Type A",
                  "description": "Description for Credential Type A",
                  "credential_type": "common.KYC",
                  "credential_type_hash": "0x1234567890123456789012345678901234567890",
                  "chain_selectors": ["16015286601757825753"],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller has no read access to the credential type's registry (including when the credential type id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Credential Types"],
        "summary": "Update credential type details.",
        "parameters": [
          {
            "in": "path",
            "name": "credential_type_id",
            "description": "Credential Type ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCredentialTypeRequest"
              },
              "example": {
                "title": "Credential Type A Updated",
                "description": "Updated description for Credential Type A"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialType"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Credential Type A Updated",
                  "description": "Updated description for Credential Type A",
                  "credential_type": "common.KYC",
                  "credential_type_hash": "0x1234567890123456789012345678901234567890",
                  "chain_selectors": ["16015286601757825753"],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Credential type not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Credential Types"],
        "summary": "Archive or update a credential type.",
        "description": "Either status=archived to archive, OR title/description to update. Mutually exclusive.\nIf credentials exist with this credential type, archive returns 409. No onchain operations.\n",
        "parameters": [
          {
            "in": "path",
            "name": "credential_type_id",
            "description": "Credential Type ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchCredentialTypeRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns credential type when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialType"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "registry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "title": "Credential Type A",
                  "description": "Description for Credential Type A",
                  "credential_type": "common.KYC",
                  "credential_type_hash": "0x1234567890123456789012345678901234567890",
                  "chain_selectors": ["16015286601757825753"],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Credential type not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - credentials exist with this credential type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/credentials": {
      "get": {
        "tags": ["Credentials"],
        "summary": "Lists all credentials.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "$ref": "#/components/parameters/include_onchains"
          },
          {
            "in": "query",
            "name": "credential_type_id",
            "description": "Credential Type ID",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "in": "query",
            "name": "identity_id",
            "description": "Identity ID",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          },
          {
            "in": "query",
            "name": "entity_id",
            "description": "Entity ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "registry_id",
            "description": "Registry ID",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCredentialsResponse"
                },
                "example": {
                  "total": 1,
                  "total_pages": 1,
                  "page": 1,
                  "credentials": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "external_unique_id": "ext-credential-123",
                      "expires_at": 1800000000,
                      "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selectors": ["16015286601757825753"],
                      "onchain_credentials": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "chain_selector": "16015286601757825753",
                          "status": "created",
                          "expires_at": 1800000000
                        }
                      ],
                      "archived_at": null,
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller has no read access to registry_id (including when the registry id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Credentials"],
        "summary": "Register a credential.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterCredentialRequest"
              },
              "example": {
                "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "external_unique_id": "ext-credential-123",
                "expires_at": 1800000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credential"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "external_unique_id": "ext-credential-123",
                  "expires_at": 1800000000,
                  "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_credentials": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "status": "created",
                      "expires_at": 1800000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "409": {
            "description": "Credential already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/credentials/{credential_id}": {
      "get": {
        "tags": ["Credentials"],
        "summary": "Gets a credential by its ID.",
        "parameters": [
          {
            "in": "path",
            "name": "credential_id",
            "description": "Credential ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credential"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "external_unique_id": "ext-credential-123",
                  "expires_at": 1800000000,
                  "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_credentials": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "status": "created",
                      "expires_at": 1800000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "403": {
            "description": "Access denied — caller has no read access to the credential's registry (including when the credential id is unknown)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "You do not have permission to access this resource"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Credentials"],
        "summary": "Update credential details.",
        "parameters": [
          {
            "in": "path",
            "name": "credential_id",
            "description": "Credential ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCredentialRequest"
              },
              "example": {
                "external_unique_id": "ext-credential-456",
                "expires_at": 1900000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credential"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "external_unique_id": "ext-credential-456",
                  "expires_at": 1900000000,
                  "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_credentials": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "status": "created",
                      "expires_at": 1900000000
                    }
                  ],
                  "archived_at": null,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Credential not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Credentials"],
        "summary": "Update or archive a credential.",
        "description": "Pass status=archived to archive, OR external_unique_id/expires_at to update.\nMutually exclusive - if status is passed, update fields must not be passed (400).\nIf credential is already archived and status is passed, returns 400.\n",
        "parameters": [
          {
            "in": "path",
            "name": "credential_id",
            "description": "Credential ID",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchCredentialRequest"
              },
              "example": {
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request accepted. Returns credential when update fields are used; empty body when archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credential"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "credential_type_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "external_unique_id": "ext-credential-123",
                  "expires_at": 1800000000,
                  "identity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "chain_selectors": ["16015286601757825753"],
                  "onchain_credentials": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "chain_selector": "16015286601757825753",
                      "status": "created",
                      "expires_at": 1800000000
                    }
                  ],
                  "archived_at": 1700000000,
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "404": {
            "description": "Credential not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    },
    "/wallets": {
      "get": {
        "tags": ["Wallets"],
        "summary": "Lists all wallets.",
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListWalletsResponse"
                },
                "example": {
                  "wallets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "chain_selector": "16015286601757825753",
                      "owner_address": "0x1234567890123456789012345678901234567890",
                      "wallet_address": "0x1234567890123456789012345678901234567890",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Wallets"],
        "summary": "Creates wallets on networks.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWalletsRequest"
              },
              "example": {
                "wallets": [
                  {
                    "owner_address": "0x1234567890123456789012345678901234567890",
                    "chain_selector": "16015286601757825753",
                    "address": ["0x1234567890123456789012345678901234567890"]
                  },
                  {
                    "owner_address": "0x1234567890123456789012345678901234567890",
                    "chain_selector": "4949039107694359620",
                    "address": ["0x1234567890123456789012345678901234567890"]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListWalletsResponse"
                },
                "example": {
                  "wallets": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "org_id": "org-123",
                      "chain_selector": "16015286601757825753",
                      "owner_address": "0x1234567890123456789012345678901234567890",
                      "wallet_address": "0x1234567890123456789012345678901234567890",
                      "status": "created",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Bad request",
                  "message": "Invalid request parameters"
                }
              }
            }
          },
          "409": {
            "description": "Wallet already exists for this chain selector",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Already exists",
                  "message": "Resource already exists"
                }
              }
            }
          }
        }
      }
    },
    "/networks": {
      "get": {
        "tags": ["Networks"],
        "summary": "Lists all networks.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/page_size"
          },
          {
            "in": "query",
            "name": "chain_id",
            "description": "Chain ID",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "chain_family",
            "description": "Chain family",
            "schema": {
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "show_unavailable",
            "description": "When true, lists mainnet networks too (even if the org lacks mainnet_allowed and cannot use them for on-chain operations).",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListNetworksResponse"
                },
                "example": {
                  "total": 3,
                  "total_pages": 1,
                  "page": 1,
                  "networks": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "name": "Ethereum Sepolia",
                      "chain_id": "11155111",
                      "chain_selector": "16015286601757825753",
                      "chain_family": "evm",
                      "created_at": 1700000000,
                      "updated_at": 1700000000
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/networks/{chain_selector}": {
      "get": {
        "tags": ["Networks"],
        "summary": "Gets a network by chain selector.",
        "parameters": [
          {
            "in": "path",
            "name": "chain_selector",
            "description": "Chain selector",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ChainSelector"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Network"
                },
                "example": {
                  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "name": "Ethereum Sepolia",
                  "chain_id": "11155111",
                  "chain_selector": "16015286601757825753",
                  "chain_family": "evm",
                  "created_at": 1700000000,
                  "updated_at": 1700000000
                }
              }
            }
          },
          "404": {
            "description": "Network not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "error": "Not found",
                  "message": "Resource not found"
                }
              }
            }
          }
        }
      }
    }
  }
}
