{
  "openapi": "3.1.0",
  "info": {
    "title": "Mementom Partner API",
    "version": "1.0.0",
    "description": "Server-to-server API for anonymous partner relationships and protected-action decisions.\nBackend-language-neutral HTTPS/JSON contract. Native SDK coverage and decision verification requirements: /developers/guides/backend-contract.md. Browser lifecycle is shared across backend languages."
  },
  "servers": [
    { "url": "https://auth.mementom.app/api/v1", "description": "Production server API" }
  ],
  "security": [
    { "vendorBearer": [] }
  ],
  "tags": [
    { "name": "Authorizations" },
    { "name": "Configuration" },
    { "name": "Connections" },
    { "name": "Protected actions" },
    { "name": "Entitlements" },
    { "name": "Events" }
  ],
  "paths": {
    "/integration-setup": {
      "post": {
        "operationId": "setupIntegration",
        "summary": "Configure standard web sign-in from your server",
        "description": "Explicit, repeatable setup. Registers only the public RSA key, preserves existing custom settings, and never grants account access. Runtime configuration reads do not call this operation.",
        "security": [
          {
            "vendorBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "applicationId",
                  "expectedVersion",
                  "website",
                  "returnUri",
                  "accountAccess",
                  "publicJwk"
                ],
                "properties": {
                  "applicationId": {
                    "type": "string"
                  },
                  "expectedVersion": {
                    "type": "integer"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri"
                  },
                  "returnUri": {
                    "type": "string",
                    "format": "uri"
                  },
                  "accountAccess": {
                    "type": "boolean"
                  },
                  "publicJwk": {
                    "type": "object",
                    "description": "Public RSA JWK only. Private members are rejected."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuration ready; changed=false on an unchanged replay."
          },
          "400": {
            "description": "Invalid public key or input."
          },
          "401": {
            "description": "Company authentication required."
          },
          "404": {
            "description": "App not owned by this company."
          },
          "409": {
            "description": "Existing configuration conflicts; no silent policy or key replacement."
          }
        },
        "tags": [
          "Configuration"
        ]
      }
    },
"/applications/{applicationId}/integration-config": {
  "get": {
    "tags": [
      "Configuration"
    ],
    "operationId": "getIntegrationConfiguration",
    "summary": "Discover the server SDK configuration",
    "description": "Read-only, vendor-scoped. Requires explicit SDK setup and active challenges/response keys. Returns no secrets; creates no tags or policies. Cache in SDK memory at most 60 seconds; retain per-attempt bindings.",
    "parameters": [
      {
        "name": "applicationId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    ],
    "responses": {
      "200": {
        "description": "Authoritative integration configuration",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/IntegrationConfiguration"
            }
          }
        }
      },
      "400": {
        "$ref": "#/components/responses/BadRequest"
      },
      "401": {
        "$ref": "#/components/responses/Unauthorized"
      },
      "404": {
        "$ref": "#/components/responses/NotFound"
      },
      "409": {
        "$ref": "#/components/responses/Conflict"
      }
    }
  }
},
"/challenge-definitions/save": {
  "post": {
    "tags": [
      "Configuration"
    ],
    "operationId": "saveChallengeDefinition",
    "summary": "Save or publish an application challenge through the vendor API",
    "description": "Uses the same definition validation, dependency checks and optimistic app version as Developer Console. Does not issue rights or authenticate a user.",
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": [
              "applicationId",
              "expectedVersion",
              "operation",
              "definition"
            ],
            "properties": {
              "applicationId": {
                "type": "string"
              },
              "expectedVersion": {
                "type": "integer"
              },
              "operation": {
                "enum": [
                  "save-draft",
                  "activate",
                  "set-status",
                  "retire"
                ]
              },
              "definition": {
                "$ref": "#/components/schemas/ManagedDefinition"
              }
            }
          }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Updated application",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Application"
            }
          }
        }
      },
      "400": {
        "$ref": "#/components/responses/BadRequest"
      },
      "401": {
        "$ref": "#/components/responses/Unauthorized"
      },
      "404": {
        "$ref": "#/components/responses/NotFound"
      },
      "409": {
        "$ref": "#/components/responses/Conflict"
      }
    }
  }
},
  "/insight-integration/catalog": {
    "servers": [
      {
        "url": "https://mementom.app/api/v1",
        "description": "Public insight API; not the authorization origin"
      }
    ],
    "post": {
      "tags": [
        "Company insights"
      ],
      "operationId": "getInsightCatalog",
      "summary": "Read the app's registered insight catalog",
      "description": "Company backend only; send bearer credential and no browser Origin/Sec-Fetch-Site headers. Never supply a ring/subject identifier. Validation is not a live write.",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InsightApplicationRequest"
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Success",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightCatalogResponse"
              }
            }
          }
        },
        "400": {
          "description": "Invalid fields, schema, timestamp, dataset or event ID",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "401": {
          "description": "Invalid company credential or current application session required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "403": {
          "description": "Browser call rejected or owner permission required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "404": {
          "description": "Application unavailable to this credential",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "409": {
          "description": "Catalog revision, event replay or observation conflict",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        }
      }
    }
  },
  "/insight-integration/validate": {
    "servers": [
      {
        "url": "https://mementom.app/api/v1",
        "description": "Public insight API; not the authorization origin"
      }
    ],
    "post": {
      "tags": [
        "Company insights"
      ],
      "operationId": "validateInsightSamples",
      "summary": "Validate synthetic observations without writing to a ring",
      "description": "Company backend only; send bearer credential and no browser Origin/Sec-Fetch-Site headers. Never supply a ring/subject identifier. Validation is not a live write.",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InsightValidationRequest"
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Receipt may contain invalid rows. Refresh catalog after validation because its revision advances.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightValidationResponse"
              }
            }
          }
        },
        "400": {
          "description": "Invalid fields, schema, timestamp, dataset or event ID",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "401": {
          "description": "Invalid company credential or current application session required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "403": {
          "description": "Browser call rejected or owner permission required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "404": {
          "description": "Application unavailable to this credential",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "409": {
          "description": "Catalog revision, event replay or observation conflict",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        }
      }
    }
  },
  "/insight-integration/ingest": {
    "servers": [
      {
        "url": "https://mementom.app/api/v1",
        "description": "Public insight API; not the authorization origin"
      }
    ],
    "post": {
      "tags": [
        "Company insights"
      ],
      "operationId": "ingestCompanyInsight",
      "summary": "Apply a company observation to the active session's ring",
      "description": "Company backend only; send bearer credential and no browser Origin/Sec-Fetch-Site headers. Never supply a ring/subject identifier. Validation is not a live write.",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InsightIngestRequest"
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Success",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightIngestResponse"
              }
            }
          }
        },
        "400": {
          "description": "Invalid fields, schema, timestamp, dataset or event ID",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "401": {
          "description": "Invalid company credential or current application session required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "403": {
          "description": "Browser call rejected or owner permission required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "404": {
          "description": "Application unavailable to this credential",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "409": {
          "description": "Catalog revision, event replay or observation conflict",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        }
      }
    }
  },
  "/insight-integration/read": {
    "servers": [
      {
        "url": "https://mementom.app/api/v1",
        "description": "Public insight API; not the authorization origin"
      }
    ],
    "post": {
      "tags": [
        "Company insights"
      ],
      "operationId": "readCompanyInsights",
      "summary": "Retrieve this app's permitted current insights",
      "description": "Returns only this application's unexpired permitted values. Empty values is a valid result, including absent permission. Does not return another company's values, external captures, persistent identities or session identifiers.",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InsightReadRequest"
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Success",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightReadResponse"
              }
            }
          }
        },
        "400": {
          "description": "Invalid fields, schema, timestamp, dataset or event ID",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "401": {
          "description": "Invalid company credential or current application session required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "403": {
          "description": "Browser call rejected or owner permission required",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "404": {
          "description": "Application unavailable to this credential",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        },
        "409": {
          "description": "Catalog revision, event replay or observation conflict",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightError"
              }
            }
          }
        }
      }
    }
  },
  "/authorization-invitations": {
    "post": {
      "tags": [
        "Authorizations"
      ],
      "operationId": "createAuthorizationInvitation",
      "summary": "Issue a one-claim or reusable authorization",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "applicationId",
                "challengeActionId"
              ],
              "properties": {
                "capabilityPolicy": {
                  "$ref": "#/components/schemas/KeyCapabilityPolicy"
                },
                "applicationId": {
                  "type": "string"
                },
                "challengeActionId": {
                  "type": "string"
                },
                "claimLimit": {
                  "enum": [
                    1,
                    null
                  ],
                  "default": 1,
                  "description": "1 for a single holder; null for unlimited distinct keyring holders."
                },
                "claimMinutes": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 1,
                  "maximum": 10080,
                  "description": "Optional claim deadline, measured from issue. Omit or use null for no deadline, for either single or unlimited claims."
                },
                "maximumUses": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 1,
                  "maximum": 1000000,
                  "description": "Successful uses per granted right, independent of claimLimit."
                },
                "startsAt": {
                  "type": [
                    "string",
                    "number",
                    "null"
                  ]
                },
                "expiresAt": {
                  "type": [
                    "string",
                    "number",
                    "null"
                  ]
                },
                "resourceDigest": {
                  "type": "string",
                  "pattern": "^sha256:[a-f0-9]{64}$"
                },
                "resourceLabel": {
                  "type": "string",
                  "maxLength": 120
                },
                "accountRef": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{32,128}$",
                  "description": "Vendor-generated random opaque account reference. Never an internal account ID, identity, credential or keyring identifier."
                }
              },
              "dependentRequired": {
                "accountRef": [
                  "resourceLabel"
                ]
              }
            }
          }
        }
      },
      "responses": {
        "201": {
          "description": "token, invitationUrl, qrSvg, claimLimit, claimCount, claimExpiresAt and permission limits. Keep the returned QR/link; tokens cannot be retrieved later."
        },
        "400": {
          "$ref": "#/components/responses/BadRequest"
        },
        "401": {
          "$ref": "#/components/responses/Unauthorized"
        },
        "409": {
          "$ref": "#/components/responses/Conflict"
        }
      },
      "description": "The company backend decides eligibility before issuing earned/private access. Unlimited-claim QR codes are public access: any proven keyring holder can accept. Repeat claims for the same app/challenge/resource/domain return the existing grant without resetting usage, expiry or revocation. No login session is issued by claiming; use the existing connection ceremony when the company needs a server-verifiable relationship. Never place company credentials or delivery identities in page code. For account-specific access, supply accountRef and a readable resourceLabel with a published action definition. The service derives an application-scoped resourceDigest; a supplied digest must match. Account invitations require claimLimit 1. Keep account invitations private in an authorized account-permission flow. For an already verified account and current personal app session, /access-rights/accounts/link provides direct association. Invitations remain a supported way for brands, vendors and partners to grant new rights to a keyring. General Login remains separate."
    }
  },
  "/access-rights/list": {
    "post": {
      "tags": [
        "Authorizations"
      ],
      "operationId": "listAccessRights",
      "summary": "Search invitations and granted rights",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "applicationId"
              ],
              "properties": {
                "applicationId": {
                  "type": "string"
                },
                "manage": {
                  "type": "boolean"
                },
                "q": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "kind": {
                  "enum": [
                    "invitation",
                    "right"
                  ]
                },
                "action": {
                  "type": "string"
                },
                "from": {
                  "type": "string",
                  "format": "date-time"
                },
                "to": {
                  "type": "string",
                  "format": "date-time"
                },
                "offset": {
                  "type": "integer"
                },
                "limit": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "With manage:true: entries, total, offset, limit, scopes; otherwise invitations, rights, scopes. No keyring subject IDs."
        },
        "400": {
          "$ref": "#/components/responses/BadRequest"
        },
        "401": {
          "$ref": "#/components/responses/Unauthorized"
        },
        "409": {
          "$ref": "#/components/responses/Conflict"
        }
      }
    }
  },
  "/access-rights/manage": {
    "post": {
      "tags": [
        "Authorizations"
      ],
      "operationId": "updateAccessRight",
      "summary": "Edit, cancel, revoke or set explicit challenge policy",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "applicationId"
              ],
              "properties": {
                "capabilityPolicy": { "$ref": "#/components/schemas/KeyCapabilityPolicy" },
                "applicationId": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "kind": {
                  "enum": [
                    "invitation",
                    "right",
                    "policy"
                  ]
                },
                "edit": {
                  "type": "boolean"
                },
                "cancel": {
                  "type": "boolean"
                },
                "revoke": {
                  "type": "boolean"
                },
                "version": {
                  "type": "integer"
                },
                "maximumUses": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 1,
                  "maximum": 1000000,
                  "description": "Successful uses per granted right, independent of claimLimit."
                },
                "startsAt": {
                  "type": [
                    "string",
                    "number",
                    "null"
                  ]
                },
                "expiresAt": {
                  "type": [
                    "string",
                    "number",
                    "null"
                  ]
                },
                "claimExpiresAt": {
                  "type": [
                    "string",
                    "number",
                    "null"
                  ]
                },
                "action": {
                  "type": "string"
                },
                "required": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Updated record. Invitation edits affect future claims only. Cancellation stops new claims; existing grants are managed separately. Scope and claim mode are immutable."
        },
        "400": {
          "$ref": "#/components/responses/BadRequest"
        },
        "401": {
          "$ref": "#/components/responses/Unauthorized"
        },
        "409": {
          "$ref": "#/components/responses/Conflict"
        }
      }
    }
  },
  "/access-rights/check": {
    "post": {
      "tags": [
        "Authorizations"
      ],
      "operationId": "checkAccessRight",
      "summary": "Check the current right without spending a use",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "sessionId",
                "action"
              ],
              "properties": {
                "sessionId": {
                  "type": "string"
                },
                "action": {
                  "type": "string"
                },
                "resourceDigest": {
                  "type": "string",
                  "pattern": "^sha256:[a-f0-9]{64}$"
                },
                "domain": {
                  "type": "string"
                },
                "applicationId": {
                  "type": "string"
                },
                "accountRef": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{32,128}$",
                  "description": "Vendor-generated random opaque account reference. Never an internal account ID, identity, credential or keyring identifier."
                }
              },
              "dependentRequired": {
                "accountRef": [
                  "applicationId",
                  "domain"
                ]
              }
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "allowed:boolean. Uses the existing company session; never accepts an arbitrary keyring identifier."
        },
        "400": {
          "$ref": "#/components/responses/BadRequest"
        },
        "401": {
          "$ref": "#/components/responses/Unauthorized"
        },
        "409": {
          "$ref": "#/components/responses/Conflict"
        }
      },
      "description": "Supply accountRef for strict account access under a current authenticated application session. Account checks require applicationId, registered domain and a published action. Generic Login/action rights and open policies cannot satisfy an account check. Neither checking nor discovery spends a use or extends authentication. This checks entitlement; it does not replace any required action ceremony and verified decision."
    }
  },
  "/access-rights/accounts/link": {
    "post": {
      "tags": [
        "Authorizations"
      ],
      "operationId": "linkAccountAccess",
      "summary": "Link a verified vendor account to the current personal keyring session",
      "description": "Authenticate the vendor account first and bind its proof to this same Mementom session. Derives the keyring from the current Login-approved session. Idempotent for the exact account; never regrants or resets a restricted right. Shared credentials are rejected. Use the account right after linking; account setup creates no separate challenge. The account right persists across fresh Login sessions; the current session authorizes its creation. Invitations remain available for brands, vendors and partners granting new rights. For ordinary account access, useAccountAccess admits the exact account without another ceremony.",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "applicationId",
                "sessionId",
                "domain",
                "action",
                "accountRef",
                "resourceLabel"
              ],
              "properties": {
                "applicationId": {
                  "type": "string"
                },
                "sessionId": {
                  "type": "string"
                },
                "domain": {
                  "type": "string"
                },
                "action": {
                  "type": "string"
                },
                "accountRef": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{32,128}$"
                },
                "resourceLabel": {
                  "type": "string",
                  "maxLength": 120
                }
              }
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Account linked or existing usable link retained; no identity is returned.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "linked",
                  "accountRef",
                  "resourceDigest"
                ],
                "properties": {
                  "linked": {
                    "const": true
                  },
                  "accountRef": {
                    "type": "string"
                  },
                  "resourceDigest": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "401": {
          "$ref": "#/components/responses/Unauthorized",
          "description": "vendor_authentication_required: fix the server credential. company_session_required: obtain a current personal Login session and rebind the verified app account."
        },
        "409": {
          "$ref": "#/components/responses/Conflict",
          "description": "access_right_unavailable: manage the existing restricted right; never replace the account reference to bypass it. invalid_account_access_scope: setup changed during linking; refresh configuration and start a new attempt."
        },
        "400": {
          "description": "Invalid request or invalid_account_access_scope. Use the configured account action and registered origin; refresh configuration before a new attempt."
        },
        "403": {
          "description": "An ineligible or restricted keyring cannot link this account."
        }
      }
    }
  },
  "/access-rights/accounts": {
    "post": {
      "tags": [
        "Authorizations"
      ],
      "operationId": "listAccountAccess",
      "summary": "Discover accounts authorized for the current application session",
      "description": "Returns only vendor-owned account references with currently usable rights for this session. No keyring, subject, connection or grant identifier is returned. Map the references to accounts on the vendor backend. Current Login revocation and stale or ended sessions block discovery. Each page rechecks live rights.",
      "requestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "applicationId",
                "sessionId",
                "domain",
                "action"
              ],
              "properties": {
                "applicationId": {
                  "type": "string"
                },
                "sessionId": {
                  "type": "string"
                },
                "domain": {
                  "type": "string",
                  "description": "Registered application origin."
                },
                "action": {
                  "type": "string",
                  "description": "Published account-access action."
                },
                "limit": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 100,
                  "default": 50
                },
                "after": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "pattern": "^[A-Za-z0-9_-]{32,128}$",
                  "description": "nextAfter from the previous page."
                }
              }
            }
          }
        }
      },
      "responses": {
        "200": {
          "description": "Accessible account references; empty accounts means no current matching rights.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "accounts",
                  "nextAfter"
                ],
                "properties": {
                  "accounts": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "required": [
                        "accountRef",
                        "resourceDigest",
                        "resourceLabel"
                      ],
                      "properties": {
                        "accountRef": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_-]{32,128}$",
                          "description": "Vendor-generated random opaque account reference. Never an internal account ID, identity, credential or keyring identifier."
                        },
                        "resourceDigest": {
                          "type": "string",
                          "pattern": "^sha256:[a-f0-9]{64}$"
                        },
                        "resourceLabel": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "nextAfter": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "400": {
          "$ref": "#/components/responses/BadRequest"
        },
        "401": {
          "$ref": "#/components/responses/Unauthorized"
        }
      }
    }
  },
    "/challenge-definitions/resolve": {
      "post": {
        "tags": ["Configuration"], "summary": "Resolve a saved app challenge and automatic policy/tag bindings", "operationId": "resolveManagedChallenge",
        "description": "OFF returns authorizationRequired false with no identity or key proof. Unknown actions are errors, never OFF. Resolve again on your server after an OFF browser continuation. Active action challenges require a public response key registered once for the app.",
        "requestBody": {"required":true,"content":{"application/json":{"schema":{"type":"object","required":["applicationId","challengeActionId"],"properties":{"applicationId":{"type":"string"},"challengeActionId":{"type":"string"},"state":{"type":"string"}}}}}},
        "responses":{"200":{"description":"Resolved rule: authorizationRequired, mode, applicationId, action, definitionVersion, optional policyId/challengeTagId; OFF has status authorization_not_required."},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Unknown app or action"},"409":{"$ref":"#/components/responses/Conflict"}}
      }
    },
    "/developer/applications/{applicationId}/challenges": {
      "parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"string"}}],
      "put": {
        "servers":[{"url":"https://developer.mementom.net/api/v1"}],"security":[{"developerCookie":[]}],"tags":["Configuration"],"operationId":"saveDeveloperChallengeDefinition","summary":"Save, activate, switch or retire a company-owned challenge",
        "description":"Same-origin staff console request, owner/admin/developer role, optimistic app-version concurrency. Definitions contain labels and field IDs only, never private values. save-draft does not change enforcement; set-status does not publish a draft.",
        "requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["expectedVersion","operation","definition"],"properties":{"expectedVersion":{"type":"integer"},"operation":{"enum":["save-draft","activate","set-status","retire"]},"definition":{"$ref":"#/components/schemas/ManagedDefinition"}}}}}},
        "responses":{"200":{"description":"Updated application with persisted challengeDefinitions and incremented version"},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"description":"Wrong origin or role"},"409":{"$ref":"#/components/responses/Conflict"}}
      }
    },
    "/applications": {
      "get": {
        "tags": ["Configuration"],
        "summary": "List applications owned by the authenticated company",
        "operationId": "listApplications",
        "responses": {
          "200": {
            "description": "Applications",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["applications"],
                  "properties": {
                    "applications": { "type": "array", "items": { "$ref": "#/components/schemas/Application" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "post": {
        "tags": ["Configuration"],
        "summary": "Create an application",
        "operationId": "createApplication",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique 16–200 character value. Retrying the same normalized registration with the same value returns the original application.",
            "schema": { "type": "string", "minLength": 16, "maxLength": 200 }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["displayName", "applicationType", "redirectUris", "allowedOrigins"],
                "properties": {
                  "displayName": { "type": "string", "minLength": 2, "maxLength": 120 },
                  "applicationType": { "type": "string", "enum": ["web", "native", "service", "device"] },
                  "redirectUris": { "type": "array", "items": { "type": "string", "format": "uri" } },
                  "allowedOrigins": { "type": "array", "items": { "type": "string", "format": "uri" } },
                  "branding": { "type": "object" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Application created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Application" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/applications/{applicationId}": {
      "get": {
        "tags": ["Configuration"],
        "summary": "Get one application owned by the authenticated company",
        "operationId": "getApplication",
        "parameters": [
          { "name": "applicationId", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^app_" } }
        ],
        "responses": {
          "200": { "description": "Application", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Application" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/applications/update": {
  "post": {
    "tags": [
      "Configuration"
    ],
    "summary": "Update an application",
    "operationId": "updateApplication",
    "description": "Application type and ownership are immutable. A successful update cancels in-flight state created under the previous configuration.",
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": [
              "applicationId",
              "expectedVersion"
            ],
            "properties": {
              "applicationId": {
                "type": "string",
                "pattern": "^app_"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              },
              "displayName": {
                "type": "string",
                "minLength": 2,
                "maxLength": 120
              },
              "redirectUris": {
                "type": "array",
                "minItems": 1,
                "maxItems": 20,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "allowedOrigins": {
                "type": "array",
                "minItems": 1,
                "maxItems": 20,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "branding": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "integrationSettings": {
                "$ref": "#/components/schemas/IntegrationSettings"
              }
            },
            "additionalProperties": false
          }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Application updated",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Application"
            }
          }
        }
      },
      "400": {
        "$ref": "#/components/responses/BadRequest"
      },
      "401": {
        "$ref": "#/components/responses/Unauthorized"
      },
      "404": {
        "$ref": "#/components/responses/NotFound"
      },
      "409": {
        "$ref": "#/components/responses/Conflict"
      }
    }
  }
},
    "/applications/lifecycle": {
      "post": {
        "tags": ["Configuration"],
        "summary": "Suspend, reactivate, or retire an application",
        "operationId": "setApplicationLifecycle",
        "description": "Retirement is permanent. Every successful transition cancels in-flight state for the application.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["applicationId", "expectedVersion", "status"],
                "properties": {
                  "applicationId": { "type": "string", "pattern": "^app_" },
                  "expectedVersion": { "type": "integer", "minimum": 1 },
                  "status": { "type": "string", "enum": ["active", "suspended", "retired"] }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Application lifecycle changed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Application" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/assurance-policies": {
      "post": {
        "tags": ["Configuration"],
        "summary": "Create an assurance policy",
        "operationId": "createAssurancePolicy",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "minimumMemkeys"],
                "properties": {
                  "name": { "type": "string" },
                  "minimumMemkeys": { "type": "integer", "minimum": 2 },
                  "recoveryProofs": { "type": "integer", "minimum": 2 }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Policy created" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/response-keys": {
      "post": {
        "tags": ["Configuration"],
        "summary": "Create a response key",
        "operationId": "createResponseKey",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["publicJwk"],
                "properties": {
                  "applicationId": { "type": "string", "pattern": "^app_" },
                  "publicJwk": { "type": "object", "description": "RSA public JWK" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Response key created" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/challenge-tags": {
      "get": {
        "tags": ["Configuration"],
        "summary": "List challenge tags",
        "operationId": "listChallengeTags",
        "responses": {
          "200": {
            "description": "Challenge tags",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "challengeTags": { "type": "array", "items": { "$ref": "#/components/schemas/ChallengeTag" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "post": {
        "tags": ["Configuration"],
        "summary": "Create a challenge tag",
        "operationId": "createChallengeTag",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["key", "displayName", "description", "responseKeyId"],
                "properties": {
                  "key": { "type": "string" },
                  "displayName": { "type": "string" },
                  "description": { "type": "string" },
                  "coverageCount": { "type": "integer", "minimum": 1 },
                  "minimumMemkeys": { "type": "integer", "minimum": 2 },
                  "retryLimit": { "type": "integer", "minimum": 0 },
                  "distinctFromAccess": { "type": "boolean" },
                  "responseKeyId": { "type": "string", "pattern": "^rkey_" },
                  "networkPolicyId": { "type": "string", "pattern": "^npol_" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Challenge tag created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChallengeTag" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/connection-requests": {
      "post": {
        "tags": ["Connections"],
        "summary": "Create a connection request",
        "operationId": "createConnectionRequest",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "anyOf": [{"required":["applicationId","challengeActionId","state"]},{"required":["applicationId", "policyId", "returnUri", "visiblePurpose", "requestedRights", "visibleConsequence", "state"]}],
                "properties": {
                  "challengeActionId":{"type":"string","description":"Saved managed login action. Policy, return address and visible context are inherited."},
                  "responseDestinationId": {"type": "string", "description": "Use the saved response destination for the original attempt when configured."},
                  "applicationId": { "type": "string", "pattern": "^app_" },
                  "policyId": { "type": "string", "pattern": "^pol_" },
                  "returnUri": { "type": "string", "format": "uri" },
                  "visiblePurpose": { "type": "string" },
                  "requestedRights": { "type": "array", "items": { "type": "string" } },
                  "visibleConsequence": { "type": "string" },
                  "state": { "type": "string" },
                  "opaqueCustomerReference": { "type": ["string", "null"] },
                  "authorization": { "$ref": "#/components/schemas/ConnectionAuthorization" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Connection request created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectionRequest" } } } },
          "200": {"description":"Managed challenge is OFF: authorization_not_required, no identity or ceremony."},
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/connections/session": {
      "post": {
        "tags": ["Connections"],
        "summary": "Exchange a connection code",
        "operationId": "exchangeConnectionCode",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["applicationId", "code"],
                "properties": {
                  "applicationId": { "type": "string", "pattern": "^app_" },
                  "code": { "type": "string" },
                  "responseDestinationId": {"type": "string", "description": "Use the saved response destination for the original attempt when configured."}
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Mementom session created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Session" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/connections/logout": {
      "post": {
        "tags": ["Connections"],
        "summary": "End the current application session",
        "operationId": "logoutConnection",
        "description": "Backend only. Ends this session without deleting its company connection or insights. Redirect the browser to logoutUrl to complete application file-access cleanup on the Mementom authorization surface; Mementom then returns to returnUri.",
        "requestBody": {
          "required": true,
          "content": {"application/json": {"schema": {
            "type": "object",
            "required": ["applicationId", "sessionId", "returnUri"],
            "properties": {
              "applicationId": {"type": "string", "pattern": "^app_"},
              "sessionId": {"type": "string", "description": "The current opaque application session, never a keyring ID."},
              "returnUri": {"type": "string", "format": "uri", "description": "A fixed HTTPS URL whose origin is in this application's allowedOrigins. Do not accept an arbitrary browser return URL."}
            }
          }}}
        },
        "responses": {
          "200": {"description": "Session ended; complete browser cleanup at the returned URL.", "content": {"application/json": {"schema": {
            "type": "object", "required": ["logoutUrl"], "properties": {"logoutUrl": {"type": "string", "format": "uri"}}
          }}}},
          "400": {"$ref": "#/components/responses/BadRequest"},
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "403": {"description": "The session belongs to another application or vendor; invalid_logout."}
        }
      }
    },
    "/connections/remove": {
      "post": {
        "tags": ["Connections"],
        "summary": "Remove a connection",
        "operationId": "removeConnection",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["applicationId", "sessionId"],
                "properties": { "applicationId": { "type": "string" }, "sessionId": { "type": "string" } }, "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Connection removed" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/challenges": {
      "post": {
        "tags": ["Protected actions"],
        "summary": "Create a challenge",
        "operationId": "createChallenge",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ChallengeRequest" }
            }
          }
        },
        "responses": {
          "201": { "description": "Challenge created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Challenge" } } } },
          "200": {"description":"Managed challenge OFF: authorization_not_required; no key required."},
          "202": { "description": "Additional Mementom setup required" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/decisions/retrieve": {
      "post": {
        "tags": ["Protected actions"],
        "summary": "Retrieve a decision",
        "operationId": "retrieveDecision",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["resultId"],
                "properties": { "resultId": { "type": "string" } }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Encrypted decision envelope" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/challenge-approvals/reset": {
      "post": {
        "tags": [
          "Protected actions"
        ],
        "summary": "Clear one current-session challenge approval",
        "operationId": "resetChallengeApproval",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "applicationId",
                  "sessionId",
                  "action"
                ],
                "additionalProperties": false,
                "properties": {
                  "applicationId": {
                    "type": "string"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "action": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Whether the current-session approval was reset"
          },
          "401": {
            "description": "No valid current company session"
          }
        }
      }
    },
    "/decisions/consume": {
      "post": {
        "tags": ["Protected actions"],
        "summary": "Consume a decision",
        "operationId": "consumeDecision",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["resultId", "nonce", "applicationId", "sessionId"],
                "properties": {
                  "resultId": { "type": "string" },
                  "nonce": { "type": "string" },
                  "applicationId": { "type": "string" },
                  "sessionId": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Decision consumed" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/entitlements/grant": {
      "post": {
        "tags": ["Entitlements"],
        "summary": "Grant an entitlement",
        "operationId": "grantEntitlement",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/EntitlementRequest" }
            }
          }
        },
        "responses": {
          "200": { "description": "Existing entitlement updated" },
          "201": { "description": "Entitlement created" },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/entitlements/remove": {
      "post": {
        "tags": ["Entitlements"],
        "summary": "Remove an entitlement",
        "operationId": "removeEntitlement",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/EntitlementRequest" }
            }
          }
        },
        "responses": {
          "200": { "description": "Entitlement removed" },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/webhooks": {
      "post": {
        "tags": ["Events"],
        "summary": "Create a webhook endpoint",
        "operationId": "createWebhook",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["endpointUrl"],
                "properties": { "endpointUrl": { "type": "string", "format": "uri" } }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Webhook endpoint created; signing secret returned once" },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/events": {
      "get": {
        "tags": ["Events"],
        "summary": "List vendor events",
        "operationId": "listEvents",
        "responses": {
          "200": { "description": "Recent vendor events" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/audit": {
      "get": {
        "tags": ["Events"],
        "summary": "List audit events",
        "operationId": "listAuditEvents",
        "parameters": [
          { "name": "connectionId", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Sanitized audit events" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/access-rights/accounts/use": {
      "post": {
        "tags": [
          "Authorizations"
        ],
        "operationId": "useAccountAccess",
        "summary": "Use an account right under the current authenticated session without another ceremony",
        "description": "Requires account rights On. New setup creates no account challenge. Existing explicitly published protected-action policies must use their configured ceremony. Checks the exact account right and current Login session, atomically spends at most one use per session/account, and returns allowed. Concurrent and response-loss retries do not spend again; revocation, expiry and capability restrictions still apply. Admitted sessions retain read-only check/list eligibility after the last allowed use. Another session needs another use. No QR, browser challenge or keyring identity is involved.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "applicationId",
                  "sessionId",
                  "domain",
                  "action",
                  "accountRef"
                ],
                "properties": {
                  "applicationId": {
                    "type": "string"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "domain": {
                    "type": "string"
                  },
                  "action": {
                    "type": "string"
                  },
                  "accountRef": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{32,128}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Exact account admission result. False never permits opening or automatically replacing an account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "allowed"
                  ],
                  "properties": {
                    "allowed": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "description": "vendor_authentication_required: fix the server credential. company_session_required: obtain a current personal Login session and rebind the verified app account."
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "description": "account_challenge_required: refresh configuration and use the explicitly configured additional challenge. invalid_account_access_scope: account access is off or changed."
          },
          "400": {
            "description": "Invalid request or invalid_account_access_scope. Use the configured account action and registered origin; refresh configuration before a new attempt."
          },
          "403": {
            "description": "An ineligible or restricted keyring cannot link this account."
          }
        }
      }
    },
    "/connection-requests/status": {
      "post": {
        "tags": [
          "Connections"
        ],
        "summary": "Check whether an issued connection request can be reused",
        "operationId": "connectionRequestStatus",
        "description": "Requires the issuing company credential. Returns only reusable, false for ended, expired, completed, missing, or foreign requests. No keyring identity or verification details are returned.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "applicationId",
                  "connectionRequestToken"
                ],
                "properties": {
                  "applicationId": {
                    "type": "string"
                  },
                  "connectionRequestToken": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request reuse status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "reusable"
                  ],
                  "properties": {
                    "reusable": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "developerCookie":{"type":"apiKey","in":"cookie","name":"mementom_developer_session"},
      "vendorBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "vnd_{id}.{clientSecret}"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Unauthorized": {
        "description": "Vendor authentication required",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Resource unavailable",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Conflict": {
        "description": "Request conflict",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "schemas": {
"IntegrationSettings": {
  "type": [
    "object",
    "null"
  ],
  "additionalProperties": false,
  "required": [
    "origin",
    "loginActionId"
  ],
  "properties": {
    "origin": {
      "type": "string",
      "format": "uri"
    },
    "loginActionId": {
      "type": "string"
    },
    "accountActionId": {
      "type": [
        "string",
        "null"
      ],
      "default": null
    },
    "responseDestinationId": {
      "type": [
        "string",
        "null"
      ],
      "default": null
    },
    "accountAccessEnabled": {
      "type": "boolean",
      "description": "Account rights switch, independent of the selected action live/draft additional-challenge status. New setup creates an account-right scope without a challenge definition. Legacy apps preserve saved behavior until edited."
    }
  }
},
"IntegrationChallenge": {
  "type": "object",
  "required": ["actionId", "mode", "definitionVersion", "returnUri", "responseKeyId", "challengeRequired"],
  "properties": {
    "actionId": {
      "type": "string"
    },
    "mode": {
      "enum": [
        "connection",
        "action"
      ]
    },
    "definitionVersion": {
      "type": "integer"
    },
    "returnUri": {
      "type": "string",
      "format": "uri"
    },
    "responseKeyId": {
      "type": [
        "string",
        "null"
      ]
    },
    "challengeRequired": {
      "type": "boolean",
      "description": "For accountAccess, only explicit false permits useAccountAccess without another ceremony. True or missing on older versions requires the existing challenge/decision flow."
    }
  }
},
"IntegrationConfiguration": {
  "type": "object",
  "required": [
    "schemaVersion",
    "applicationId",
    "vendorId",
    "applicationVersion",
    "origin",
    "responseDestinationId",
    "challenges",
    "responseKeys",
    "decisionSigningKeys",
    "cacheMaxAgeSeconds"
  ],
  "properties": {
    "schemaVersion": {
      "const": 1
    },
    "applicationId": {
      "type": "string"
    },
    "vendorId": {
      "type": "string"
    },
    "applicationVersion": {
      "type": "integer"
    },
    "origin": {
      "type": "string",
      "format": "uri"
    },
    "responseDestinationId": {
      "type": [
        "string",
        "null"
      ]
    },
    "challenges": {
      "type": "object",
      "required": [
        "login",
        "accountAccess"
      ],
      "properties": {
        "login": {
          "$ref": "#/components/schemas/IntegrationChallenge"
        },
        "accountAccess": {
          "anyOf": [
            {
              "$ref": "#/components/schemas/IntegrationChallenge"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    },
    "responseKeys": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "responseKeyId",
          "version",
          "algorithm",
          "publicJwk"
        ],
        "properties": {
          "responseKeyId": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "algorithm": {
            "const": "RSA-OAEP-256+A256GCM"
          },
          "publicJwk": {
            "type": "object",
            "required": [
              "kty",
              "n",
              "e"
            ],
            "properties": {
              "kty": {
                "const": "RSA"
              },
              "n": {
                "type": "string"
              },
              "e": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        }
      }
    },
    "decisionSigningKeys": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "keyId": {
            "type": "string"
          },
          "algorithm": {
            "const": "EdDSA"
          },
          "publicJwk": {
            "type": "object"
          }
        }
      }
    },
    "cacheMaxAgeSeconds": {
      "type": "integer",
      "maximum": 60
    }
  }
},
    "KeyCapabilityPolicy": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "label",
        "statements"
      ],
      "properties": {
        "label": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "reauthenticationHours": {
          "type": "number",
          "minimum": 0.25,
          "maximum": 168,
          "multipleOf": 0.25,
          "default": 24
        },
        "statements": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "capability",
              "access",
              "resources"
            ],
            "properties": {
              "capability": {
                "type": "string",
                "description": "Exact capability from the service catalogue. offers.items reads or responds; offers.definitions authors. Unknown capabilities are rejected."
              },
              "access": {
                "type": "array",
                "minItems": 1,
                "maxItems": 2,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "read",
                    "write"
                  ]
                }
              },
              "resources": {
                "type": "array",
                "minItems": 1,
                "maxItems": 100,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "maxLength": 160
                },
                "description": "Explicit resource IDs, or [\"*\"] for all eligible resources. Never grants upstream authority."
              },
              "filters": {
                "type": "object",
                "additionalProperties": false,
                "description": "Offers only. Empty/omitted filters add no restriction. Different filter types combine with AND. Missing metadata does not match a selected filter.",
                "properties": {
                  "vendorIds": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 120
                    }
                  },
                  "tagsAny": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 120
                    }
                  },
                  "priceBelow": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "currency",
                      "amountMinor"
                    ],
                    "properties": {
                      "currency": {
                        "type": "string",
                        "pattern": "^[A-Z]{3}$"
                      },
                      "amountMinor": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100000000000
                      }
                    },
                    "description": "Strictly below this purchase price in the specified currency. USD 200 is amountMinor 20000. No currency conversion or reward-based inference."
                  }
                }
              }
            }
          }
        }
      }
    },
  "InsightApplicationRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "applicationId"
    ],
    "properties": {
      "applicationId": {
        "type": "string",
        "minLength": 1
      }
    }
  },
  "InsightReadRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "applicationId",
      "sessionId"
    ],
    "properties": {
      "applicationId": {
        "type": "string",
        "minLength": 1
      },
      "sessionId": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256
      }
    }
  },
  "InsightObservation": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "schemaVersion",
      "observedAt",
      "values"
    ],
    "properties": {
      "schemaVersion": {
        "const": 1
      },
      "observedAt": {
        "type": "string",
        "format": "date-time",
        "description": "Original event time, not in the future. Preserve it on retries."
      },
      "values": {
        "type": "object",
        "minProperties": 1,
        "additionalProperties": {
          "oneOf": [
            {
              "type": "string"
            },
            {
              "type": "boolean"
            },
            {
              "type": "integer"
            }
          ]
        },
        "description": "Only keys registered in this dataset; types, enum values, bounds and TTL come from catalog."
      }
    }
  },
  "InsightIngestRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "applicationId",
      "sessionId",
      "expectedRevision",
      "datasetId",
      "eventId",
      "sample"
    ],
    "properties": {
      "applicationId": {
        "type": "string",
        "minLength": 1
      },
      "sessionId": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256
      },
      "expectedRevision": {
        "type": "integer",
        "minimum": 0
      },
      "datasetId": {
        "type": "string"
      },
      "eventId": {
        "type": "string",
        "pattern": "^[A-Za-z0-9_-]{8,80}$"
      },
      "sample": {
        "$ref": "#/components/schemas/InsightObservation"
      }
    }
  },
  "InsightValidationRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "applicationId",
      "expectedRevision",
      "datasetId",
      "samples"
    ],
    "properties": {
      "applicationId": {
        "type": "string",
        "minLength": 1
      },
      "expectedRevision": {
        "type": "integer",
        "minimum": 0
      },
      "datasetId": {
        "type": "string"
      },
      "samples": {
        "type": "array",
        "minItems": 1,
        "maxItems": 50,
        "items": {
          "$ref": "#/components/schemas/InsightObservation"
        }
      }
    }
  },
  "InsightError": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "error",
      "activityId"
    ],
    "properties": {
      "error": {
        "type": "string"
      },
      "message": {
        "type": "string"
      },
      "activityId": {
        "type": "string",
        "format": "uuid"
      }
    }
  },
  "InsightValue": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "key",
      "version",
      "value",
      "observedAt",
      "expiresAt",
      "provenance"
    ],
    "properties": {
      "key": {
        "type": "string"
      },
      "version": {
        "type": "integer"
      },
      "value": {
        "oneOf": [
          {
            "type": "string"
          },
          {
            "type": "boolean"
          },
          {
            "type": "integer"
          }
        ]
      },
      "observedAt": {
        "type": "string",
        "format": "date-time"
      },
      "expiresAt": {
        "type": "string",
        "format": "date-time"
      },
      "provenance": {
        "const": "company_asserted"
      }
    }
  },
  "InsightReadResponse": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "schemaVersion",
      "values",
      "activityId"
    ],
    "properties": {
      "schemaVersion": {
        "const": 1
      },
      "values": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/InsightValue"
        }
      },
      "activityId": {
        "type": "string"
      }
    }
  },
  "InsightIngestResponse": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "receiptId",
      "accepted",
      "duplicate",
      "observedAt",
      "activityId"
    ],
    "properties": {
      "receiptId": {
        "type": "string"
      },
      "accepted": {
        "type": "integer",
        "minimum": 1
      },
      "duplicate": {
        "type": "boolean"
      },
      "observedAt": {
        "type": "string",
        "format": "date-time"
      },
      "activityId": {
        "type": "string"
      }
    }
  },
  "InsightDefinition": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string"
      },
      "key": {
        "type": "string"
      },
      "version": {
        "type": "integer"
      },
      "label": {
        "type": "string"
      },
      "description": {
        "type": "string"
      },
      "type": {
        "enum": [
          "enum",
          "boolean",
          "integer"
        ]
      },
      "values": {
        "type": "array",
        "items": {
          "type": "string"
        }
      },
      "minimum": {
        "type": "integer"
      },
      "maximum": {
        "type": "integer"
      },
      "ttlDays": {
        "type": "integer"
      },
      "windowDays": {
        "type": "integer"
      },
      "updateMode": {
        "type": "string"
      },
      "uses": {
        "type": "array",
        "items": {
          "type": "string"
        }
      },
      "status": {
        "enum": [
          "standard",
          "approved"
        ]
      },
      "isSample": {
        "type": "boolean"
      },
      "sample": {
        "type": "object"
      }
    },
    "required": [
      "id",
      "key",
      "version",
      "label",
      "type",
      "ttlDays",
      "status"
    ]
  },
  "InsightDataset": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string"
      },
      "name": {
        "type": "string"
      },
      "definitionIds": {
        "type": "array",
        "items": {
          "type": "string"
        }
      },
      "sourceMethod": {
        "enum": [
          "company_asserted",
          "consumer_ai_extraction",
          "mementom_extraction"
        ]
      },
      "status": {
        "type": "string",
        "description": "Legacy workspace lifecycle label, not holder consent. Only non-sample company_asserted datasets with approved definitions can ingest."
      },
      "isSample": {
        "type": "boolean"
      },
      "sample": {
        "type": "object"
      }
    },
    "required": [
      "id",
      "name",
      "definitionIds",
      "sourceMethod",
      "status"
    ]
  },
  "InsightCatalogResponse": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "schemaVersion",
      "applicationId",
      "revision",
      "definitions",
      "datasets",
      "capabilities",
      "maxBatchSize",
      "activityId"
    ],
    "properties": {
      "schemaVersion": {
        "const": 1
      },
      "applicationId": {
        "type": "string"
      },
      "revision": {
        "type": "integer",
        "minimum": 0
      },
      "definitions": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/InsightDefinition"
        }
      },
      "datasets": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/InsightDataset"
        }
      },
      "capabilities": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "validation",
          "consumerIngestion",
          "holderPermissionRequired"
        ],
        "properties": {
          "validation": {
            "const": true
          },
          "consumerIngestion": {
            "const": true
          },
          "holderPermissionRequired": {
            "const": true
          }
        }
      },
      "maxBatchSize": {
        "const": 50
      },
      "activityId": {
        "type": "string"
      }
    }
  },
  "InsightValidationResponse": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "applicationId",
      "revision",
      "receipt",
      "consumerRecordsWritten",
      "activityId"
    ],
    "properties": {
      "applicationId": {
        "type": "string"
      },
      "revision": {
        "type": "integer",
        "minimum": 0
      },
      "receipt": {
        "type": "object",
        "required": [
          "id",
          "datasetId",
          "status",
          "sampleCount",
          "validCount",
          "invalidCount",
          "results",
          "consumerRecordsWritten"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "datasetId": {
            "type": "string"
          },
          "status": {
            "enum": [
              "valid",
              "invalid"
            ]
          },
          "sampleCount": {
            "type": "integer"
          },
          "validCount": {
            "type": "integer"
          },
          "invalidCount": {
            "type": "integer"
          },
          "fields": {
            "type": "integer"
          },
          "createdAt": {
            "type": "integer"
          },
          "consumerRecordsWritten": {
            "const": 0
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "status": {
                  "enum": [
                    "valid",
                    "invalid"
                  ]
                },
                "fields": {
                  "type": "integer"
                },
                "consumerRecordsWritten": {
                  "const": 0
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "index",
                "status"
              ]
            }
          }
        }
      },
      "consumerRecordsWritten": {
        "const": 0
      },
      "activityId": {
        "type": "string"
      }
    }
  },
      "ManagedDefinition": {
        "type":"object","additionalProperties":false,
        "required":["name","actionId","mode","status","purpose","requestedRight","resourceSummary","consequence","requestTtl","resultTtl","assurance","allowRecent","webhook","inheritReturn","privateFields"],
        "properties":{
          "id":{"type":"string"},"name":{"type":"string","minLength":3,"maxLength":60},"actionId":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Immutable after creation"},
          "mode":{"enum":["connection","action"],"description":"Immutable after creation"},"status":{"enum":["draft","live","retired"],"description":"live requires a key; draft bypasses this gate; retired challenges reject requests."},
          "purpose":{"type":"string","minLength":8,"maxLength":180},"requestedRight":{"type":"string","minLength":3,"maxLength":120},"resourceSummary":{"type":"string","minLength":3,"maxLength":120},"consequence":{"type":"string","minLength":8,"maxLength":240},
          "requestTtl":{"enum":["5","10","15","30"],"description":"Minutes"},"resultTtl":{"enum":["5","15","30"],"description":"Minutes"},"assurance":{"enum":["one-key","two-key"]},"cinematicVerification":{"type":"boolean","default":true,"description":"Show the cinematic lock presentation. False uses a standard verification dialog; authorization policy is unchanged."},"maximumAttempts":{"type":"integer","enum":[1,2,3],"default":2,"description":"Key verification attempt limit. Password and authenticator verification remain single-attempt."},"allowRecent":{"type":"boolean","description":"Allow a verified proof from the last 15 minutes for this app/action and unchanged rule."},"webhook":{"type":"boolean"},
          "inheritReturn":{"type":"boolean"},"returnUrl":{"type":"string","description":"Must be a registered application return URI when not inherited."},"policyId":{"type":"string"},"challengeTagId":{"type":"string"},
          "privateFields":{"type":"array","maxItems":30,"items":{"type":"object","additionalProperties":false,"required":["label","fieldId"],"properties":{"label":{"type":"string","maxLength":40},"fieldId":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9_.-]{1,63}$"}}}}
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" }
        }
      },
      "Application": {
  "type": "object",
  "required": [
    "applicationId",
    "vendorId",
    "displayName",
    "applicationType",
    "redirectUris",
    "allowedOrigins",
    "branding",
    "status",
    "version",
    "createdAt",
    "updatedAt"
  ],
  "properties": {
    "applicationId": {
      "type": "string",
      "pattern": "^app_"
    },
    "vendorId": {
      "type": "string",
      "pattern": "^vnd_"
    },
    "displayName": {
      "type": "string"
    },
    "applicationType": {
      "type": "string"
    },
    "redirectUris": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uri"
      }
    },
    "allowedOrigins": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uri"
      }
    },
    "branding": {
      "type": "object"
    },
    "status": {
      "type": "string",
      "enum": [
        "active",
        "suspended",
        "retired"
      ]
    },
    "version": {
      "type": "integer",
      "minimum": 1
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time"
    },
    "integrationSettings": {
      "$ref": "#/components/schemas/IntegrationSettings"
    }
  }
},
      "ChallengeTag": {
        "type": "object",
        "properties": {
          "challengeTagId": { "type": "string", "pattern": "^ctag_" },
          "vendorId": { "type": "string", "pattern": "^vnd_" },
          "key": { "type": "string" },
          "displayName": { "type": "string" },
          "description": { "type": "string" },
          "responseKeyId": { "type": "string", "pattern": "^rkey_" },
          "status": { "type": "string" },
          "version": { "type": "integer" }
        }
      },
      "ConnectionRequest": {
        "type": "object",
        "properties": {
          "requestId": { "type": "string", "pattern": "^creq_" },
          "connectionRequestToken": { "type": "string" },
          "consumerUrl": { "type": "string", "format": "uri" },
          "expiresAt": { "type": "string", "format": "date-time" }
        }
      },
      "Session": {
        "type": "object",
        "description": "Fresh random app session for each new authentication. Only Mementom maps it to the keyring. No company user database is required.",
        "properties": {
          "tokenType": { "const": "MementomSession" },
          "sessionContract": { "const": "mementom-session-only-v1" },
          "requestId": { "type": "string", "pattern": "^creq_", "description": "Must match the connection request saved when this browser began sign-in." },
          "sessionId": { "type": "string" },
          "identityAttributes": { "type": "object", "maxProperties": 0 },
          "resultId": { "type": "string", "pattern": "^result_", "description": "Present only when the connection request carried a bound authorization." },
          "expiresAt": { "type": "string", "format": "date-time" }
        }
      },
      "ConnectionAuthorization": {
        "type": "object",
        "required": ["challengeTagId", "gateRequestId", "action", "resourceDigest", "visibleDetails"],
        "properties": {
          "challengeTagId": { "type": "string", "pattern": "^ctag_" },
          "gateRequestId": { "type": "string" },
          "action": { "type": "string" },
          "resourceDigest": { "type": "string", "description": "SHA-256 digest" },
          "visibleDetails": {
            "type": "object",
            "required": ["resourceSummary", "consequence", "expiresAt"],
            "properties": {
              "actionLabel": { "type": "string" },
              "resourceSummary": { "type": "string" },
              "consequence": { "type": "string" },
              "expiresAt": { "type": "string", "format": "date-time" }
            }
          }
        },
        "description": "Optional protected action completed by the same proof that establishes the connection."
      },
      "ChallengeRequest": {
        "type": "object",
        "anyOf":[{"required":["applicationId","challengeActionId","state"]},{"required":["applicationId", "sessionId", "challengeTagId", "gateRequestId", "state", "action", "resourceDigest", "visibleDetails", "returnUri"]}],
        "properties": {
          "challengeActionId":{"type":"string","description":"Managed action ID. Active rules also require sessionId, gateRequestId and resourceDigest. Other settings are inherited. OFF needs no session or proof."},
          "applicationId": { "type": "string", "pattern": "^app_" },
          "sessionId": { "type": "string" },
          "challengeTagId": { "type": "string", "pattern": "^ctag_" },
          "gateRequestId": { "type": "string" },
          "state": { "type": "string" },
          "action": { "type": "string" },
          "resourceDigest": { "type": "string", "description": "SHA-256 digest" },
          "visibleDetails": {
            "type": "object",
            "required": ["resourceSummary", "consequence"],
            "properties": {
              "actionLabel": { "type": "string" },
              "resourceSummary": { "type": "string" },
              "consequence": { "type": "string" },
              "expiresAt": { "type": "string", "format": "date-time" }
            }
          },
          "returnUri": { "type": "string", "format": "uri" }
        }
      },
      "Challenge": {
        "type": "object",
        "properties": {
          "status":{"enum":["completed"],"description":"Optional: opted-in recent proof satisfied this action. Verify and consume resultId using the normal signed-result contract."},
          "resultId":{"type":"string"},
          "challengeId": { "type": "string", "pattern": "^chal_" },
          "gateRequestId": { "type": "string" },
          "challengeUrl": { "type": "string", "format": "uri" },
          "expiresAt": { "type": "string", "format": "date-time" },
          "idempotentReplay": { "type": "boolean" }
        }
      },
      "EntitlementRequest": {
        "type": "object",
        "required": ["applicationId", "sessionId", "challengeTagId"],
        "additionalProperties": false,
        "properties": {
          "applicationId": { "type": "string" },
          "sessionId": { "type": "string" },
          "challengeTagId": { "type": "string", "pattern": "^ctag_" },
          "expiresAt": { "type": ["string", "null"], "format": "date-time" }
        }
      }
    }
  }
}
