{
  "openapi": "3.1.0",
  "info": {
    "title": "AgentFide API",
    "version": "1.0.0",
    "description": "The trust handshake for the agent economy. Verify any agent, score its reputation, and back the deal with recourse, in a single call before money moves.",
    "contact": {
      "name": "AgentFide",
      "url": "https://agentfide.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://agentfide.com/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/assess": {
      "post": {
        "operationId": "assess",
        "summary": "Run the four check trust stack and get a decision",
        "description": "Verifies the agent (signed A2A card), checks authority against a mandate, scores reputation, and reports recourse availability. Idempotent on context.idempotency_key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssessRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assessment result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body was not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription for this API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Per key rate limit exceeded. Includes a Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/outcome": {
      "post": {
        "operationId": "outcome",
        "summary": "Report a transaction outcome",
        "description": "Reports what happened against a prior assessment (paid, delivered, disputed…). Feeds reputation and returns a signed, private by default receipt.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutcomeRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Outcome accepted; receipt issued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutcomeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body was not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription for this API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No assessment found for assessment_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Per key rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/recourse/open": {
      "post": {
        "operationId": "recourseOpen",
        "summary": "Open escrow on a guaranteed transaction",
        "description": "Holds the buyer's funds in Stripe Connect escrow for a guaranteed transaction tied to a prior assessment, and returns a reputation-priced coverage quote. The seller is the assessed agent's operator. Test mode.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecourseOpenRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Escrow held.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecourseOpenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body was not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription for this API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Not eligible for coverage, or the seller is not onboarded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Per key rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage or payments temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/recourse/release": {
      "post": {
        "operationId": "recourseRelease",
        "summary": "Release a held escrow to the seller",
        "description": "Releases the held transaction value to the seller's connected account on completion. Blocked until the seller's payouts are enabled.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecourseClaimRef"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrow released.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecourseResolveResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription for this API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No claim found for claim_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Claim is not held, or the seller's payouts are not enabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/recourse/refund": {
      "post": {
        "operationId": "recourseRefund",
        "summary": "Refund a held escrow to the buyer (Agent Rewind)",
        "description": "Refunds the held transaction value to the buyer. This is the Agent Rewind primitive for undoing a bad transaction.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecourseClaimRef"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrow refunded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecourseResolveResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription for this API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No claim found for claim_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Claim is not held.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Liveness + schema check",
        "description": "Public endpoint (no API key). Reports DB connectivity and schema presence.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "db": {
                      "type": "string"
                    },
                    "schema": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Service or database unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "AgentFide API key as a bearer token, e.g. `Authorization: Bearer af_live_…`."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Machine readable error code."
          },
          "detail": {
            "type": "string",
            "description": "Optional human readable detail."
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Field level validation errors (422)."
          }
        },
        "required": [
          "error"
        ]
      },
      "AssessRequest": {
        "type": "object",
        "required": [
          "agent",
          "action"
        ],
        "properties": {
          "agent": {
            "type": "string",
            "description": "An A2A agent card URL or a known AgentFide agent id."
          },
          "acting_for": {
            "type": "object",
            "required": [
              "principal"
            ],
            "properties": {
              "principal": {
                "type": "string"
              },
              "mandate": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  },
                  "limit": {
                    "type": "number",
                    "minimum": 0
                  },
                  "currency": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          },
          "action": {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "pay",
                  "purchase",
                  "hire",
                  "transfer",
                  "other"
                ]
              },
              "amount": {
                "type": "number",
                "minimum": 0
              },
              "currency": {
                "type": "string",
                "minLength": 3,
                "maxLength": 3
              },
              "counterparty": {
                "type": "string"
              },
              "description": {
                "type": "string"
              }
            }
          },
          "context": {
            "type": "object",
            "properties": {
              "marketplace": {
                "type": "string"
              },
              "idempotency_key": {
                "type": "string"
              }
            }
          }
        }
      },
      "AssessResponse": {
        "type": "object",
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "allow",
              "review",
              "deny"
            ]
          },
          "identity": {
            "type": "object",
            "properties": {
              "card_verified": {
                "type": "boolean"
              },
              "operator": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "signature_method": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "authority": {
            "type": "object",
            "properties": {
              "mandate_valid": {
                "type": "boolean"
              },
              "in_scope": {
                "type": "boolean"
              },
              "limit_remaining": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "reputation": {
            "type": "object",
            "properties": {
              "score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1000
              },
              "tier": {
                "type": "string",
                "enum": [
                  "unrated",
                  "bronze",
                  "silver",
                  "gold",
                  "platinum"
                ]
              },
              "factors": {
                "type": "object",
                "additionalProperties": {
                  "type": "number"
                }
              },
              "explanation": {
                "type": "string"
              }
            }
          },
          "recourse": {
            "type": "object",
            "properties": {
              "available": {
                "type": "boolean"
              },
              "escrow_offered": {
                "type": "boolean"
              },
              "rewind_supported": {
                "type": "boolean"
              },
              "coverage": {
                "type": "object",
                "description": "Reputation-priced coverage quote, present when recourse is available.",
                "properties": {
                  "rate_bps": {
                    "type": "integer"
                  },
                  "fee": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "coverage_amount": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "max_coverage": {
                    "type": "number"
                  },
                  "currency": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          },
          "assessment_id": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OutcomeRequest": {
        "type": "object",
        "required": [
          "assessment_id",
          "result"
        ],
        "properties": {
          "assessment_id": {
            "type": "string"
          },
          "result": {
            "type": "string",
            "enum": [
              "paid",
              "delivered",
              "disputed",
              "reversed",
              "failed"
            ]
          },
          "amount": {
            "type": "number",
            "minimum": 0
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "OutcomeResponse": {
        "type": "object",
        "properties": {
          "received": {
            "type": "boolean"
          },
          "assessment_id": {
            "type": "string"
          },
          "result": {
            "type": "string",
            "enum": [
              "paid",
              "delivered",
              "disputed",
              "reversed",
              "failed"
            ]
          },
          "outcome_id": {
            "type": "string"
          },
          "receipt_id": {
            "type": "string"
          },
          "signing_kid": {
            "type": "string"
          }
        }
      },
      "RecourseOpenRequest": {
        "type": "object",
        "required": [
          "assessment_id",
          "amount",
          "currency"
        ],
        "properties": {
          "assessment_id": {
            "type": "string",
            "description": "A prior assessment of the seller agent."
          },
          "amount": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Transaction value to guarantee."
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "payment_method": {
            "type": "string",
            "description": "Buyer's Stripe payment method. Optional in test mode."
          }
        }
      },
      "RecourseClaimRef": {
        "type": "object",
        "required": [
          "claim_id"
        ],
        "properties": {
          "claim_id": {
            "type": "string"
          }
        }
      },
      "RecourseOpenResponse": {
        "type": "object",
        "properties": {
          "claim_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "held"
            ]
          },
          "payment_status": {
            "type": "string"
          },
          "payment_intent": {
            "type": "string"
          },
          "coverage": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "RecourseResolveResponse": {
        "type": "object",
        "properties": {
          "claim_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "released",
              "refunded"
            ]
          },
          "transfer": {
            "type": "string"
          },
          "refund": {
            "type": "string"
          }
        }
      }
    }
  }
}