{
  "openapi": "3.1.0",
  "info": {
    "title": "FLINT Agent Transaction Control API",
    "version": "1.0.0",
    "description": "FLINT verifies agent authority before autonomous economic activity, issues signed verification records, accepts outcome feedback, and returns partner-safe Trust Graph reputation."
  },
  "servers": [
    {
      "url": "https://flint.network",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Verification Records",
      "description": "Issue and verify signed verification records."
    },
    {
      "name": "Outcome Feedback",
      "description": "Submit transaction outcomes that seed Trust Graph reputation."
    },
    {
      "name": "Trust Graph",
      "description": "Read partner-safe aggregate agent reputation and graph health."
    },
    {
      "name": "Agent Passport",
      "description": "Issue, resolve, and update Agent Passports: hybrid-signed agent identity credentials with a separate mutable mandate."
    }
  ],
  "paths": {
    "/api/passport": {
      "post": {
        "tags": ["Agent Passport"],
        "operationId": "issueAgentPassport",
        "summary": "Issue an Agent Passport",
        "description": "Issues a hybrid-signed (ES256 + ML-DSA-65) Agent Passport that binds an agent to its controller and wallet. The passport signs identity only; the mandate is a separate, unsigned, mutable config. Persists the passport, seeds the Trust Graph, and returns a public resolvable id. Free and per-IP rate limited.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PassportIssueRequest" }
            }
          }
        },
        "responses": {
          "200": { "description": "Passport issued.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PassportResponse" } } } },
          "400": { "description": "Invalid request.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "429": { "description": "Rate limited.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/api/passport/{passport_id}": {
      "get": {
        "tags": ["Agent Passport"],
        "operationId": "resolveAgentPassport",
        "summary": "Resolve a public Agent Passport",
        "description": "Returns the signed passport envelope, decoded identity, current mandate, and a verification summary (signature valid, status, not expired).",
        "parameters": [
          { "name": "passport_id", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^kya_" }, "description": "Passport id (kya_ prefix + ULID)." }
        ],
        "responses": {
          "200": { "description": "Passport resolved.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PassportResponse" } } } },
          "404": { "description": "Passport not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      },
      "post": {
        "tags": ["Agent Passport"],
        "operationId": "updateAgentMandate",
        "summary": "Update a passport mandate",
        "description": "Updates the mutable mandate (allowed_actions, max_transaction_amount, notes). This is a pure data update: it bumps the mandate version, signs nothing, and leaves the passport signature byte-for-byte unchanged.",
        "parameters": [
          { "name": "passport_id", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^kya_" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MandateUpdateRequest" }
            }
          }
        },
        "responses": {
          "200": { "description": "Mandate updated; passport signature unchanged.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MandateUpdateResponse" } } } },
          "404": { "description": "Passport not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/api/verify": {
      "post": {
        "tags": ["Verification Records"],
        "operationId": "issueAuthorizationRecord",
        "summary": "Issue a signed verification record",
        "description": "Use before an AI agent initiates a payment, paid API call, checkout action, stablecoin transfer, x402 request, or delegated commercial transaction. Returns a compact JWS signed verification record.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyRequest"
              },
              "examples": {
                "agentPayment": {
                  "summary": "Agent payment authorization",
                  "value": {
                    "nonce": "8b2ef62d-6ec0-4ac8-a5e4-e6d4ec447bcf",
                    "timestamp": "2026-05-20T16:00:00.000Z",
                    "partner_id": "sandbox_public",
                    "merchant_reference": "invoice_123",
                    "transaction": {
                      "amount_display": "42.00",
                      "asset": "USDC",
                      "chain": "eip155:8453",
                      "counterparty_address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
                    },
                    "declared_scope": {
                      "max_amount_per_tx_display": "250.00",
                      "allowed_counterparties": ["invoice_123"],
                      "time_window_end": "2026-05-20T17:00:00.000Z"
                    },
                    "agent_claim": {
                      "agent_id": "agent_checkout_worker",
                      "principal_hint": "skyfire",
                      "agent_runtime_hint": "browser"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Compact JWS signed verification record",
            "headers": {
              "X-FLINT-Verdict": {
                "schema": {
                  "$ref": "#/components/schemas/VerdictDecision"
                }
              },
              "X-FLINT-Score": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/jwt": {
                "schema": {
                  "type": "string",
                  "description": "Compact JWS containing the signed verification record."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/outcomes": {
      "post": {
        "tags": ["Outcome Feedback"],
        "operationId": "submitTransactionOutcome",
        "summary": "Submit transaction outcome feedback",
        "description": "Use after a transaction completes, is disputed, or is flagged. Outcome feedback updates durable storage and Trust Graph reputation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutcomeRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Outcome accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutcomeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/graph/agent/{flint_agent_id}": {
      "get": {
        "tags": ["Trust Graph"],
        "operationId": "lookupAgentReputation",
        "summary": "Lookup partner-safe aggregate agent reputation",
        "description": "Returns partner-facing aggregate reputation for a partner-scoped FLINT agent ID. Raw runtime provider identifiers and internal signal fields are not returned.",
        "parameters": [
          {
            "name": "flint_agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^faid_[a-f0-9]{24}$"
            },
            "description": "Partner-scoped FLINT agent identifier."
          }
        ],
        "responses": {
          "200": {
            "description": "Agent reputation summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentReputationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/api/graph/health": {
      "get": {
        "tags": ["Trust Graph"],
        "operationId": "getTrustGraphHealth",
        "summary": "Check Trust Graph health",
        "description": "Operational endpoint that checks Trust Graph configuration and connectivity.",
        "responses": {
          "200": {
            "description": "Trust Graph is reachable or intentionally unconfigured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphHealthResponse"
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          }
        }
      }
    },
    "/.well-known/jwks.json": {
      "get": {
        "tags": ["Verification Records"],
        "operationId": "getJwks",
        "summary": "Get FLINT public signing keys",
        "description": "Returns the public JWKS used to verify compact JWS signed verification records.",
        "responses": {
          "200": {
            "description": "JSON Web Key Set",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["keys"],
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/flint.json": {
      "get": {
        "tags": ["Trust Graph"],
        "operationId": "getFlintTrustManifest",
        "summary": "Get FLINT Trust Manifest",
        "description": "Returns this domain's Trust Manifest for agent commerce authorization semantics.",
        "responses": {
          "200": {
            "description": "FLINT Trust Manifest",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustManifest"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "VerifyRequest": {
        "type": "object",
        "required": ["nonce", "timestamp", "transaction"],
        "properties": {
          "nonce": {
            "type": "string",
            "minLength": 8,
            "description": "Unique replay-protection nonce. UUID v4 is recommended."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Request timestamp. Must be within the server replay-protection window."
          },
          "partner_id": {
            "type": "string",
            "default": "sandbox_public",
            "description": "Merchant or platform identifier used for partner-scoped public IDs."
          },
          "merchant_reference": {
            "type": "string",
            "description": "Merchant transaction, invoice, or API access reference."
          },
          "transaction": {
            "$ref": "#/components/schemas/TransactionIntent"
          },
          "declared_scope": {
            "$ref": "#/components/schemas/AuthorizationScope"
          },
          "agent_claim": {
            "$ref": "#/components/schemas/AgentClaim"
          }
        }
      },
      "TransactionIntent": {
        "type": "object",
        "required": ["amount_display"],
        "properties": {
          "amount_display": {
            "type": "string",
            "description": "Human-readable transaction amount."
          },
          "amount_atomic": {
            "type": ["string", "null"],
            "description": "Atomic token amount when available."
          },
          "asset": {
            "type": "string",
            "description": "Asset symbol, such as USDC."
          },
          "chain": {
            "type": "string",
            "description": "CAIP-2 chain identifier."
          },
          "counterparty_address": {
            "type": ["string", "null"],
            "description": "Wallet or counterparty address."
          },
          "merchant_reference": {
            "type": ["string", "null"],
            "description": "Merchant reference for the intended action."
          },
          "tx_intent_hash": {
            "type": ["string", "null"],
            "description": "Optional hash of the transaction intent."
          }
        }
      },
      "AuthorizationScope": {
        "type": "object",
        "properties": {
          "max_amount_per_tx_display": {
            "type": "string",
            "description": "Maximum amount authorized per transaction."
          },
          "allowed_counterparties": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed merchant references or counterparties."
          },
          "time_window_end": {
            "type": "string",
            "format": "date-time",
            "description": "Expiration time for the declared scope."
          }
        }
      },
      "AgentClaim": {
        "type": "object",
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "Agent-provided stable identifier or handle."
          },
          "principal_hint": {
            "type": "string",
            "description": "Principal or authority hint supplied by the agent."
          },
          "agent_runtime_hint": {
            "type": "string",
            "description": "Agent runtime category, such as browser, api_client, or api_meter."
          },
          "wallet_type": {
            "type": "string",
            "description": "Wallet or account type claimed by the agent."
          }
        }
      },
      "VerdictDecision": {
        "type": "string",
        "enum": ["allow", "step_up", "review", "block"]
      },
      "OutcomeRequest": {
        "type": "object",
        "required": ["record_id", "outcome"],
        "properties": {
          "record_id": {
            "type": "string",
            "pattern": "^frv_",
            "description": "Signed verification record ID."
          },
          "outcome": {
            "type": "string",
            "enum": ["completed", "disputed", "flagged"]
          },
          "merchant_note": {
            "type": ["string", "null"]
          },
          "partner_id": {
            "type": "string",
            "default": "sandbox_public"
          }
        }
      },
      "OutcomeResponse": {
        "type": "object",
        "required": ["ok", "outcome_id", "record_id", "outcome", "stored_at"],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "outcome_id": {
            "type": "string"
          },
          "record_id": {
            "type": "string"
          },
          "outcome": {
            "type": "string",
            "enum": ["completed", "disputed", "flagged"]
          },
          "stored_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AgentReputationResponse": {
        "type": "object",
        "required": ["ok", "agent_reputation"],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "agent_reputation": {
            "$ref": "#/components/schemas/AgentReputation"
          }
        }
      },
      "AgentReputation": {
        "type": "object",
        "required": ["flint_agent_id", "global_stats", "runtime_diversity", "principal_consistency", "recent_outcomes"],
        "properties": {
          "flint_agent_id": {
            "type": "string"
          },
          "global_stats": {
            "type": "object",
            "required": ["first_seen", "total_transactions", "dispute_rate"],
            "properties": {
              "first_seen": {
                "type": ["string", "null"],
                "format": "date-time"
              },
              "total_transactions": {
                "type": "integer",
                "minimum": 0
              },
              "dispute_rate": {
                "type": "number",
                "minimum": 0
              }
            }
          },
          "runtime_diversity": {
            "type": "integer",
            "minimum": 0
          },
          "principal_consistency": {
            "type": "integer",
            "minimum": 0
          },
          "recent_outcomes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["completed", "disputed", "flagged"]
            }
          }
        }
      },
      "GraphHealthResponse": {
        "type": "object",
        "required": ["ok", "status"],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": ["ok", "configured", "unconfigured"]
          },
          "latency_ms": {
            "type": "integer",
            "minimum": 0
          },
          "message": {
            "type": "string"
          }
        }
      },
      "TrustManifest": {
        "type": "object",
        "required": ["version", "requires_flint_authorization", "partner_id"],
        "properties": {
          "version": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "requires_flint_authorization": {
            "type": "boolean"
          },
          "partner_id": {
            "type": "string"
          },
          "authorization_record": {
            "type": "object"
          },
          "agent_commerce": {
            "type": "object"
          },
          "trust_graph": {
            "type": "object"
          },
          "outcome_feedback": {
            "type": "object"
          },
          "docs": {
            "type": "object"
          },
          "privacy": {
            "type": "object"
          },
          "contact": {
            "type": "object"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "error": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "PassportIssueRequest": {
        "type": "object",
        "required": ["agent"],
        "properties": {
          "agent": {
            "type": "object",
            "description": "Agent identity. Signed into the passport.",
            "properties": {
              "agent_id": { "type": "string" },
              "agent_name": { "type": "string" },
              "controller_id": { "type": "string" },
              "controller_type": { "type": "string", "enum": ["user", "organization"] },
              "wallet_address": { "type": "string" },
              "attestations": { "type": "array", "items": { "type": "object" } }
            }
          },
          "mandate": {
            "type": "object",
            "description": "Mutable spend authority captured at issue. NOT part of the passport signature.",
            "properties": {
              "allowed_actions": { "type": "array", "items": { "type": "string" } },
              "max_transaction_amount": { "type": "number" },
              "notes": { "type": "string" }
            }
          }
        }
      },
      "Mandate": {
        "type": "object",
        "description": "Unsigned, mutable mandate config read at decision time.",
        "properties": {
          "passport_id": { "type": "string" },
          "allowed_actions": { "type": "array", "items": { "type": "string" } },
          "max_transaction_amount": { "type": "number" },
          "notes": { "type": "string", "nullable": true },
          "version": { "type": "integer" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "PassportResponse": {
        "type": "object",
        "properties": {
          "passport_id": { "type": "string", "description": "kya_ prefix + ULID." },
          "flint_agent_id": { "type": "string", "description": "Trust Graph node key (faid_ prefix)." },
          "passport": {
            "type": "object",
            "description": "Hybrid-v0 signature envelope.",
            "properties": {
              "envelope_version": { "type": "string", "example": "hybrid-v0" },
              "jws": { "type": "string", "description": "ES256 compact JWS over the identity-only payload." },
              "pq_signature": { "type": "string", "nullable": true, "description": "ML-DSA-65 signature (base64url)." },
              "pq_kid": { "type": "string", "nullable": true },
              "pq_alg": { "type": "string", "nullable": true }
            }
          },
          "mandate": { "$ref": "#/components/schemas/Mandate" },
          "verification": {
            "type": "object",
            "properties": {
              "signature_valid": { "type": "boolean" },
              "status": { "type": "string" },
              "not_expired": { "type": "boolean" },
              "valid": { "type": "boolean" }
            }
          }
        }
      },
      "MandateUpdateRequest": {
        "type": "object",
        "properties": {
          "action": { "type": "string", "enum": ["update_mandate"] },
          "allowed_actions": { "type": "array", "items": { "type": "string" } },
          "max_transaction_amount": { "type": "number" },
          "notes": { "type": "string" }
        }
      },
      "MandateUpdateResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "passport_id": { "type": "string" },
          "mandate": { "$ref": "#/components/schemas/Mandate" },
          "passport_signature_unchanged": { "type": "boolean", "description": "Always true: a mandate update never re-signs the passport." }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflict or idempotency collision",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "BadGateway": {
        "description": "Upstream graph or service failure",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unavailable": {
        "description": "Service unavailable or not configured",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServerError": {
        "description": "Server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
